From: Greg Kroah-Hartman Date: Wed, 8 Mar 2017 07:00:00 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.53~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c5aa4dcf2d9d2d33b857a1487e5560f85ee3c115;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: am437x-vpfe-always-assign-bpp-variable.patch cxd2820r-fix-gpio-null-pointer-dereference.patch ext4-fix-deadlock-between-inline_data-and-ext4_expand_extra_isize_ea.patch lirc_dev-lirc_-g-s-et_rec_mode-do-not-work.patch media-fix-dm1105.c-build-error.patch media-properly-pass-through-media-entity-types-in-entity-enumeration.patch mips-bcm47xx-fix-button-inversion-for-asus-wl-500w.patch mips-calculate-micromips-ra-properly-when-unwinding-the-stack.patch mips-clear-isa-bit-correctly-in-get_frame_info.patch mips-fix-get_frame_info-handling-of-micromips-function-size.patch mips-fix-is_jump_ins-handling-of-16b-micromips-instructions.patch mips-fix-special-case-in-64-bit-ip-checksumming.patch mips-handle-micromips-jumps-in-the-same-way-as-mips32-mips64-jumps.patch mips-lantiq-keep-ethernet-enabled-during-boot.patch mips-octeon-fix-copy_from_user-fault-handling-for-large-buffers.patch mips-pic32mzda-fix-linker-error-for-pic32_get_pbclk.patch mips-prevent-unaligned-accesses-during-stack-unwinding.patch mmc-sdhci-acpi-support-deferred-probe.patch uvcvideo-fix-a-wrong-macro.patch --- diff --git a/queue-4.9/am437x-vpfe-always-assign-bpp-variable.patch b/queue-4.9/am437x-vpfe-always-assign-bpp-variable.patch new file mode 100644 index 00000000000..4a73e08483b --- /dev/null +++ b/queue-4.9/am437x-vpfe-always-assign-bpp-variable.patch @@ -0,0 +1,41 @@ +From 6ebf75774f823ddbdbd10921006989d4df222f4a Mon Sep 17 00:00:00 2001 +From: Nicolas Iooss +Date: Tue, 27 Dec 2016 16:02:36 -0200 +Subject: [media] am437x-vpfe: always assign bpp variable + +From: Nicolas Iooss + +commit 6ebf75774f823ddbdbd10921006989d4df222f4a upstream. + +In vpfe_s_fmt(), when the sensor format and the requested format were +the same, bpp was assigned to vpfe->bpp without being initialized first. + +Grab the bpp value that is currently used by using __vpfe_get_format() +instead of its wrapper, vpfe_try_fmt(). + +This use of uninitialized variable has been found by compiling the +kernel with clang. + +Fixes: 417d2e507edc ("[media] media: platform: add VPFE capture driver +support for AM437X") + +Signed-off-by: Nicolas Iooss +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/platform/am437x/am437x-vpfe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/platform/am437x/am437x-vpfe.c ++++ b/drivers/media/platform/am437x/am437x-vpfe.c +@@ -1576,7 +1576,7 @@ static int vpfe_s_fmt(struct file *file, + return -EBUSY; + } + +- ret = vpfe_try_fmt(file, priv, &format); ++ ret = __vpfe_get_format(vpfe, &format, &bpp); + if (ret) + return ret; + diff --git a/queue-4.9/cxd2820r-fix-gpio-null-pointer-dereference.patch b/queue-4.9/cxd2820r-fix-gpio-null-pointer-dereference.patch new file mode 100644 index 00000000000..9dda08230c9 --- /dev/null +++ b/queue-4.9/cxd2820r-fix-gpio-null-pointer-dereference.patch @@ -0,0 +1,49 @@ +From 0ffb94b6cc5df6376ab6bff5b80075641f6716f8 Mon Sep 17 00:00:00 2001 +From: Antti Palosaari +Date: Mon, 16 Jan 2017 19:27:41 -0200 +Subject: [media] cxd2820r: fix gpio null pointer dereference +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Antti Palosaari + +commit 0ffb94b6cc5df6376ab6bff5b80075641f6716f8 upstream. + +Setting GPIOs during probe causes null pointer deference when +GPIOLIB was not selected by Kconfig. Initialize driver private +field before calling set gpios. + +It is regressing bug since 4.9. + +Fixes: 07fdf7d9f19f ("[media] cxd2820r: add I2C driver bindings") + +Reported-by: Chris Rankin +Tested-by: Chris Rankin +Tested-by: Håkan Lennestål +Signed-off-by: Antti Palosaari +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/dvb-frontends/cxd2820r_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/dvb-frontends/cxd2820r_core.c ++++ b/drivers/media/dvb-frontends/cxd2820r_core.c +@@ -615,6 +615,7 @@ static int cxd2820r_probe(struct i2c_cli + } + + priv->client[0] = client; ++ priv->fe.demodulator_priv = priv; + priv->i2c = client->adapter; + priv->ts_mode = pdata->ts_mode; + priv->ts_clk_inv = pdata->ts_clk_inv; +@@ -697,7 +698,6 @@ static int cxd2820r_probe(struct i2c_cli + memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof(priv->fe.ops)); + if (!pdata->attach_in_use) + priv->fe.ops.release = NULL; +- priv->fe.demodulator_priv = priv; + i2c_set_clientdata(client, priv); + + /* Setup callbacks */ diff --git a/queue-4.9/ext4-fix-deadlock-between-inline_data-and-ext4_expand_extra_isize_ea.patch b/queue-4.9/ext4-fix-deadlock-between-inline_data-and-ext4_expand_extra_isize_ea.patch new file mode 100644 index 00000000000..418a52e9d7a --- /dev/null +++ b/queue-4.9/ext4-fix-deadlock-between-inline_data-and-ext4_expand_extra_isize_ea.patch @@ -0,0 +1,472 @@ +From c755e251357a0cee0679081f08c3f4ba797a8009 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Wed, 11 Jan 2017 21:50:46 -0500 +Subject: ext4: fix deadlock between inline_data and ext4_expand_extra_isize_ea() + +From: Theodore Ts'o + +commit c755e251357a0cee0679081f08c3f4ba797a8009 upstream. + +The xattr_sem deadlock problems fixed in commit 2e81a4eeedca: "ext4: +avoid deadlock when expanding inode size" didn't include the use of +xattr_sem in fs/ext4/inline.c. With the addition of project quota +which added a new extra inode field, this exposed deadlocks in the +inline_data code similar to the ones fixed by 2e81a4eeedca. + +The deadlock can be reproduced via: + + dmesg -n 7 + mke2fs -t ext4 -O inline_data -Fq -I 256 /dev/vdc 32768 + mount -t ext4 -o debug_want_extra_isize=24 /dev/vdc /vdc + mkdir /vdc/a + umount /vdc + mount -t ext4 /dev/vdc /vdc + echo foo > /vdc/a/foo + +and looks like this: + +[ 11.158815] +[ 11.160276] ============================================= +[ 11.161960] [ INFO: possible recursive locking detected ] +[ 11.161960] 4.10.0-rc3-00015-g011b30a8a3cf #160 Tainted: G W +[ 11.161960] --------------------------------------------- +[ 11.161960] bash/2519 is trying to acquire lock: +[ 11.161960] (&ei->xattr_sem){++++..}, at: [] ext4_expand_extra_isize_ea+0x3d/0x4cd +[ 11.161960] +[ 11.161960] but task is already holding lock: +[ 11.161960] (&ei->xattr_sem){++++..}, at: [] ext4_try_add_inline_entry+0x3a/0x152 +[ 11.161960] +[ 11.161960] other info that might help us debug this: +[ 11.161960] Possible unsafe locking scenario: +[ 11.161960] +[ 11.161960] CPU0 +[ 11.161960] ---- +[ 11.161960] lock(&ei->xattr_sem); +[ 11.161960] lock(&ei->xattr_sem); +[ 11.161960] +[ 11.161960] *** DEADLOCK *** +[ 11.161960] +[ 11.161960] May be due to missing lock nesting notation +[ 11.161960] +[ 11.161960] 4 locks held by bash/2519: +[ 11.161960] #0: (sb_writers#3){.+.+.+}, at: [] mnt_want_write+0x1e/0x3e +[ 11.161960] #1: (&type->i_mutex_dir_key){++++++}, at: [] path_openat+0x338/0x67a +[ 11.161960] #2: (jbd2_handle){++++..}, at: [] start_this_handle+0x582/0x622 +[ 11.161960] #3: (&ei->xattr_sem){++++..}, at: [] ext4_try_add_inline_entry+0x3a/0x152 +[ 11.161960] +[ 11.161960] stack backtrace: +[ 11.161960] CPU: 0 PID: 2519 Comm: bash Tainted: G W 4.10.0-rc3-00015-g011b30a8a3cf #160 +[ 11.161960] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1 04/01/2014 +[ 11.161960] Call Trace: +[ 11.161960] dump_stack+0x72/0xa3 +[ 11.161960] __lock_acquire+0xb7c/0xcb9 +[ 11.161960] ? kvm_clock_read+0x1f/0x29 +[ 11.161960] ? __lock_is_held+0x36/0x66 +[ 11.161960] ? __lock_is_held+0x36/0x66 +[ 11.161960] lock_acquire+0x106/0x18a +[ 11.161960] ? ext4_expand_extra_isize_ea+0x3d/0x4cd +[ 11.161960] down_write+0x39/0x72 +[ 11.161960] ? ext4_expand_extra_isize_ea+0x3d/0x4cd +[ 11.161960] ext4_expand_extra_isize_ea+0x3d/0x4cd +[ 11.161960] ? _raw_read_unlock+0x22/0x2c +[ 11.161960] ? jbd2_journal_extend+0x1e2/0x262 +[ 11.161960] ? __ext4_journal_get_write_access+0x3d/0x60 +[ 11.161960] ext4_mark_inode_dirty+0x17d/0x26d +[ 11.161960] ? ext4_add_dirent_to_inline.isra.12+0xa5/0xb2 +[ 11.161960] ext4_add_dirent_to_inline.isra.12+0xa5/0xb2 +[ 11.161960] ext4_try_add_inline_entry+0x69/0x152 +[ 11.161960] ext4_add_entry+0xa3/0x848 +[ 11.161960] ? __brelse+0x14/0x2f +[ 11.161960] ? _raw_spin_unlock_irqrestore+0x44/0x4f +[ 11.161960] ext4_add_nondir+0x17/0x5b +[ 11.161960] ext4_create+0xcf/0x133 +[ 11.161960] ? ext4_mknod+0x12f/0x12f +[ 11.161960] lookup_open+0x39e/0x3fb +[ 11.161960] ? __wake_up+0x1a/0x40 +[ 11.161960] ? lock_acquire+0x11e/0x18a +[ 11.161960] path_openat+0x35c/0x67a +[ 11.161960] ? sched_clock_cpu+0xd7/0xf2 +[ 11.161960] do_filp_open+0x36/0x7c +[ 11.161960] ? _raw_spin_unlock+0x22/0x2c +[ 11.161960] ? __alloc_fd+0x169/0x173 +[ 11.161960] do_sys_open+0x59/0xcc +[ 11.161960] SyS_open+0x1d/0x1f +[ 11.161960] do_int80_syscall_32+0x4f/0x61 +[ 11.161960] entry_INT80_32+0x2f/0x2f +[ 11.161960] EIP: 0xb76ad469 +[ 11.161960] EFLAGS: 00000286 CPU: 0 +[ 11.161960] EAX: ffffffda EBX: 08168ac8 ECX: 00008241 EDX: 000001b6 +[ 11.161960] ESI: b75e46bc EDI: b7755000 EBP: bfbdb108 ESP: bfbdafc0 +[ 11.161960] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 007b + +Reported-by: George Spelvin +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inline.c | 66 +++++++++++++++++++++++++------------------------------ + fs/ext4/xattr.c | 30 ++++++++++--------------- + fs/ext4/xattr.h | 32 ++++++++++++++++++++++++++ + 3 files changed, 74 insertions(+), 54 deletions(-) + +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -376,7 +376,7 @@ out: + static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode, + unsigned int len) + { +- int ret, size; ++ int ret, size, no_expand; + struct ext4_inode_info *ei = EXT4_I(inode); + + if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) +@@ -386,15 +386,14 @@ static int ext4_prepare_inline_data(hand + if (size < len) + return -ENOSPC; + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + + if (ei->i_inline_off) + ret = ext4_update_inline_data(handle, inode, len); + else + ret = ext4_create_inline_data(handle, inode, len); + +- up_write(&EXT4_I(inode)->xattr_sem); +- ++ ext4_write_unlock_xattr(inode, &no_expand); + return ret; + } + +@@ -523,7 +522,7 @@ static int ext4_convert_inline_data_to_e + struct inode *inode, + unsigned flags) + { +- int ret, needed_blocks; ++ int ret, needed_blocks, no_expand; + handle_t *handle = NULL; + int retries = 0, sem_held = 0; + struct page *page = NULL; +@@ -563,7 +562,7 @@ retry: + goto out; + } + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + sem_held = 1; + /* If some one has already done this for us, just exit. */ + if (!ext4_has_inline_data(inode)) { +@@ -600,7 +599,7 @@ retry: + put_page(page); + page = NULL; + ext4_orphan_add(handle, inode); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + sem_held = 0; + ext4_journal_stop(handle); + handle = NULL; +@@ -626,7 +625,7 @@ out: + put_page(page); + } + if (sem_held) +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + if (handle) + ext4_journal_stop(handle); + brelse(iloc.bh); +@@ -719,7 +718,7 @@ convert: + int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, + unsigned copied, struct page *page) + { +- int ret; ++ int ret, no_expand; + void *kaddr; + struct ext4_iloc iloc; + +@@ -737,7 +736,7 @@ int ext4_write_inline_data_end(struct in + goto out; + } + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + BUG_ON(!ext4_has_inline_data(inode)); + + kaddr = kmap_atomic(page); +@@ -747,7 +746,7 @@ int ext4_write_inline_data_end(struct in + /* clear page dirty so that writepages wouldn't work for us. */ + ClearPageDirty(page); + +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + brelse(iloc.bh); + out: + return copied; +@@ -758,7 +757,7 @@ ext4_journalled_write_inline_data(struct + unsigned len, + struct page *page) + { +- int ret; ++ int ret, no_expand; + void *kaddr; + struct ext4_iloc iloc; + +@@ -768,11 +767,11 @@ ext4_journalled_write_inline_data(struct + return NULL; + } + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + kaddr = kmap_atomic(page); + ext4_write_inline_data(inode, &iloc, kaddr, 0, len); + kunmap_atomic(kaddr); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + + return iloc.bh; + } +@@ -1249,7 +1248,7 @@ out: + int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname, + struct inode *dir, struct inode *inode) + { +- int ret, inline_size; ++ int ret, inline_size, no_expand; + void *inline_start; + struct ext4_iloc iloc; + +@@ -1257,7 +1256,7 @@ int ext4_try_add_inline_entry(handle_t * + if (ret) + return ret; + +- down_write(&EXT4_I(dir)->xattr_sem); ++ ext4_write_lock_xattr(dir, &no_expand); + if (!ext4_has_inline_data(dir)) + goto out; + +@@ -1303,7 +1302,7 @@ int ext4_try_add_inline_entry(handle_t * + + out: + ext4_mark_inode_dirty(handle, dir); +- up_write(&EXT4_I(dir)->xattr_sem); ++ ext4_write_unlock_xattr(dir, &no_expand); + brelse(iloc.bh); + return ret; + } +@@ -1663,7 +1662,7 @@ int ext4_delete_inline_entry(handle_t *h + struct buffer_head *bh, + int *has_inline_data) + { +- int err, inline_size; ++ int err, inline_size, no_expand; + struct ext4_iloc iloc; + void *inline_start; + +@@ -1671,7 +1670,7 @@ int ext4_delete_inline_entry(handle_t *h + if (err) + return err; + +- down_write(&EXT4_I(dir)->xattr_sem); ++ ext4_write_lock_xattr(dir, &no_expand); + if (!ext4_has_inline_data(dir)) { + *has_inline_data = 0; + goto out; +@@ -1705,7 +1704,7 @@ int ext4_delete_inline_entry(handle_t *h + + ext4_show_inline_dir(dir, iloc.bh, inline_start, inline_size); + out: +- up_write(&EXT4_I(dir)->xattr_sem); ++ ext4_write_unlock_xattr(dir, &no_expand); + brelse(iloc.bh); + if (err != -ENOENT) + ext4_std_error(dir->i_sb, err); +@@ -1804,11 +1803,11 @@ out: + + int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) + { +- int ret; ++ int ret, no_expand; + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + ret = ext4_destroy_inline_data_nolock(handle, inode); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + + return ret; + } +@@ -1893,7 +1892,7 @@ out: + void ext4_inline_data_truncate(struct inode *inode, int *has_inline) + { + handle_t *handle; +- int inline_size, value_len, needed_blocks; ++ int inline_size, value_len, needed_blocks, no_expand; + size_t i_size; + void *value = NULL; + struct ext4_xattr_ibody_find is = { +@@ -1910,7 +1909,7 @@ void ext4_inline_data_truncate(struct in + if (IS_ERR(handle)) + return; + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + if (!ext4_has_inline_data(inode)) { + *has_inline = 0; + ext4_journal_stop(handle); +@@ -1968,7 +1967,7 @@ out_error: + up_write(&EXT4_I(inode)->i_data_sem); + out: + brelse(is.iloc.bh); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + kfree(value); + if (inode->i_nlink) + ext4_orphan_del(handle, inode); +@@ -1984,7 +1983,7 @@ out: + + int ext4_convert_inline_data(struct inode *inode) + { +- int error, needed_blocks; ++ int error, needed_blocks, no_expand; + handle_t *handle; + struct ext4_iloc iloc; + +@@ -2006,15 +2005,10 @@ int ext4_convert_inline_data(struct inod + goto out_free; + } + +- down_write(&EXT4_I(inode)->xattr_sem); +- if (!ext4_has_inline_data(inode)) { +- up_write(&EXT4_I(inode)->xattr_sem); +- goto out; +- } +- +- error = ext4_convert_inline_data_nolock(handle, inode, &iloc); +- up_write(&EXT4_I(inode)->xattr_sem); +-out: ++ ext4_write_lock_xattr(inode, &no_expand); ++ if (ext4_has_inline_data(inode)) ++ error = ext4_convert_inline_data_nolock(handle, inode, &iloc); ++ ext4_write_unlock_xattr(inode, &no_expand); + ext4_journal_stop(handle); + out_free: + brelse(iloc.bh); +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1174,16 +1174,14 @@ ext4_xattr_set_handle(handle_t *handle, + struct ext4_xattr_block_find bs = { + .s = { .not_found = -ENODATA, }, + }; +- unsigned long no_expand; ++ int no_expand; + int error; + + if (!name) + return -EINVAL; + if (strlen(name) > 255) + return -ERANGE; +- down_write(&EXT4_I(inode)->xattr_sem); +- no_expand = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND); +- ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ ext4_write_lock_xattr(inode, &no_expand); + + error = ext4_reserve_inode_write(handle, inode, &is.iloc); + if (error) +@@ -1251,7 +1249,7 @@ ext4_xattr_set_handle(handle_t *handle, + ext4_xattr_update_super_block(handle, inode->i_sb); + inode->i_ctime = ext4_current_time(inode); + if (!value) +- ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ no_expand = 0; + error = ext4_mark_iloc_dirty(handle, inode, &is.iloc); + /* + * The bh is consumed by ext4_mark_iloc_dirty, even with +@@ -1265,9 +1263,7 @@ ext4_xattr_set_handle(handle_t *handle, + cleanup: + brelse(is.iloc.bh); + brelse(bs.bh); +- if (no_expand == 0) +- ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + return error; + } + +@@ -1484,12 +1480,11 @@ int ext4_expand_extra_isize_ea(struct in + int error = 0, tried_min_extra_isize = 0; + int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize); + int isize_diff; /* How much do we need to grow i_extra_isize */ ++ int no_expand; ++ ++ if (ext4_write_trylock_xattr(inode, &no_expand) == 0) ++ return 0; + +- down_write(&EXT4_I(inode)->xattr_sem); +- /* +- * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty +- */ +- ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); + retry: + isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize; + if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) +@@ -1571,17 +1566,16 @@ shift: + EXT4_I(inode)->i_extra_isize = new_extra_isize; + brelse(bh); + out: +- ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + return 0; + + cleanup: + brelse(bh); + /* +- * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode +- * size expansion failed. ++ * Inode size expansion failed; don't try again + */ +- up_write(&EXT4_I(inode)->xattr_sem); ++ no_expand = 1; ++ ext4_write_unlock_xattr(inode, &no_expand); + return error; + } + +--- a/fs/ext4/xattr.h ++++ b/fs/ext4/xattr.h +@@ -102,6 +102,38 @@ extern const struct xattr_handler ext4_x + + #define EXT4_XATTR_NAME_ENCRYPTION_CONTEXT "c" + ++/* ++ * The EXT4_STATE_NO_EXPAND is overloaded and used for two purposes. ++ * The first is to signal that there the inline xattrs and data are ++ * taking up so much space that we might as well not keep trying to ++ * expand it. The second is that xattr_sem is taken for writing, so ++ * we shouldn't try to recurse into the inode expansion. For this ++ * second case, we need to make sure that we take save and restore the ++ * NO_EXPAND state flag appropriately. ++ */ ++static inline void ext4_write_lock_xattr(struct inode *inode, int *save) ++{ ++ down_write(&EXT4_I(inode)->xattr_sem); ++ *save = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); ++} ++ ++static inline int ext4_write_trylock_xattr(struct inode *inode, int *save) ++{ ++ if (down_write_trylock(&EXT4_I(inode)->xattr_sem) == 0) ++ return 0; ++ *save = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ return 1; ++} ++ ++static inline void ext4_write_unlock_xattr(struct inode *inode, int *save) ++{ ++ if (*save == 0) ++ ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ up_write(&EXT4_I(inode)->xattr_sem); ++} ++ + extern ssize_t ext4_listxattr(struct dentry *, char *, size_t); + + extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t); diff --git a/queue-4.9/lirc_dev-lirc_-g-s-et_rec_mode-do-not-work.patch b/queue-4.9/lirc_dev-lirc_-g-s-et_rec_mode-do-not-work.patch new file mode 100644 index 00000000000..31fb6d7d4e8 --- /dev/null +++ b/queue-4.9/lirc_dev-lirc_-g-s-et_rec_mode-do-not-work.patch @@ -0,0 +1,41 @@ +From bd291208d7f5d6b2d6a033fee449a429230b06df Mon Sep 17 00:00:00 2001 +From: Sean Young +Date: Fri, 2 Dec 2016 15:16:08 -0200 +Subject: [media] lirc_dev: LIRC_{G,S}ET_REC_MODE do not work + +From: Sean Young + +commit bd291208d7f5d6b2d6a033fee449a429230b06df upstream. + +Since "273b902 [media] lirc_dev: use LIRC_CAN_REC() define" these +ioctls no longer work. + +Signed-off-by: Sean Young +Reviewed-by: Andi Shyti +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/rc/lirc_dev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/media/rc/lirc_dev.c ++++ b/drivers/media/rc/lirc_dev.c +@@ -589,7 +589,7 @@ long lirc_dev_fop_ioctl(struct file *fil + result = put_user(ir->d.features, (__u32 __user *)arg); + break; + case LIRC_GET_REC_MODE: +- if (LIRC_CAN_REC(ir->d.features)) { ++ if (!LIRC_CAN_REC(ir->d.features)) { + result = -ENOTTY; + break; + } +@@ -599,7 +599,7 @@ long lirc_dev_fop_ioctl(struct file *fil + (__u32 __user *)arg); + break; + case LIRC_SET_REC_MODE: +- if (LIRC_CAN_REC(ir->d.features)) { ++ if (!LIRC_CAN_REC(ir->d.features)) { + result = -ENOTTY; + break; + } diff --git a/queue-4.9/media-fix-dm1105.c-build-error.patch b/queue-4.9/media-fix-dm1105.c-build-error.patch new file mode 100644 index 00000000000..e934084c046 --- /dev/null +++ b/queue-4.9/media-fix-dm1105.c-build-error.patch @@ -0,0 +1,36 @@ +From e3bb3cddd177550d63a3e4909cf1a7782f13414d Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Sat, 7 Jan 2017 23:08:49 -0200 +Subject: [media] media: fix dm1105.c build error + +From: Randy Dunlap + +commit e3bb3cddd177550d63a3e4909cf1a7782f13414d upstream. + +Fix dm1105 build error when CONFIG_I2C_ALGOBIT=m and +CONFIG_DVB_DM1105=y. + +drivers/built-in.o: In function `dm1105_probe': +dm1105.c:(.text+0x2836e7): undefined reference to `i2c_bit_add_bus' + +Signed-off-by: Randy Dunlap +Reported-by: kbuild test robot +Cc: Javier Martinez Canillas +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/pci/dm1105/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/pci/dm1105/Kconfig ++++ b/drivers/media/pci/dm1105/Kconfig +@@ -1,6 +1,6 @@ + config DVB_DM1105 + tristate "SDMC DM1105 based PCI cards" +- depends on DVB_CORE && PCI && I2C ++ depends on DVB_CORE && PCI && I2C && I2C_ALGOBIT + select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT + select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT diff --git a/queue-4.9/media-properly-pass-through-media-entity-types-in-entity-enumeration.patch b/queue-4.9/media-properly-pass-through-media-entity-types-in-entity-enumeration.patch new file mode 100644 index 00000000000..36ce4d02402 --- /dev/null +++ b/queue-4.9/media-properly-pass-through-media-entity-types-in-entity-enumeration.patch @@ -0,0 +1,37 @@ +From 98d85f3cb912fde14593ead54dea4c1a00b3966f Mon Sep 17 00:00:00 2001 +From: Sakari Ailus +Date: Mon, 2 Jan 2017 08:32:47 -0200 +Subject: [media] media: Properly pass through media entity types in entity enumeration + +From: Sakari Ailus + +commit 98d85f3cb912fde14593ead54dea4c1a00b3966f upstream. + +When the functions replaced media entity types, the range which was +allowed for the types was incorrect. This meant that media entity types +for specific devices were not passed correctly to the userspace through +MEDIA_IOC_ENUM_ENTITIES. Fix it. + +Fixes: commit b2cd27448b33 ("[media] media-device: map new functions into old types for legacy API") +Reported-and-tested-by: Antti Laakso + +Signed-off-by: Sakari Ailus +Acked-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/media-device.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/media-device.c ++++ b/drivers/media/media-device.c +@@ -130,7 +130,7 @@ static long media_device_enum_entities(s + * old range. + */ + if (ent->function < MEDIA_ENT_F_OLD_BASE || +- ent->function > MEDIA_ENT_T_DEVNODE_UNKNOWN) { ++ ent->function > MEDIA_ENT_F_TUNER) { + if (is_media_entity_v4l2_subdev(ent)) + entd->type = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; + else if (ent->function != MEDIA_ENT_F_IO_V4L) diff --git a/queue-4.9/mips-bcm47xx-fix-button-inversion-for-asus-wl-500w.patch b/queue-4.9/mips-bcm47xx-fix-button-inversion-for-asus-wl-500w.patch new file mode 100644 index 00000000000..fcc117e302f --- /dev/null +++ b/queue-4.9/mips-bcm47xx-fix-button-inversion-for-asus-wl-500w.patch @@ -0,0 +1,54 @@ +From bdfdaf1a016ef09cb941f2edad485a713510b8d5 Mon Sep 17 00:00:00 2001 +From: Mirko Parthey +Date: Wed, 15 Feb 2017 23:31:30 +0100 +Subject: MIPS: BCM47XX: Fix button inversion for Asus WL-500W +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mirko Parthey + +commit bdfdaf1a016ef09cb941f2edad485a713510b8d5 upstream. + +The Asus WL-500W buttons are active high, but the software treats them +as active low. Fix the inverted logic. + +Fixes: 3be972556fa1 ("MIPS: BCM47XX: Import buttons database from OpenWrt") +Signed-off-by: Mirko Parthey +Acked-by: Rafał Miłecki +Cc: Hauke Mehrtens +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15295/ +Signed-off-by: James Hogan +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/bcm47xx/buttons.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/arch/mips/bcm47xx/buttons.c ++++ b/arch/mips/bcm47xx/buttons.c +@@ -17,6 +17,12 @@ + .active_low = 1, \ + } + ++#define BCM47XX_GPIO_KEY_H(_gpio, _code) \ ++ { \ ++ .code = _code, \ ++ .gpio = _gpio, \ ++ } ++ + /* Asus */ + + static const struct gpio_keys_button +@@ -79,8 +85,8 @@ bcm47xx_buttons_asus_wl500gpv2[] __initc + + static const struct gpio_keys_button + bcm47xx_buttons_asus_wl500w[] __initconst = { +- BCM47XX_GPIO_KEY(6, KEY_RESTART), +- BCM47XX_GPIO_KEY(7, KEY_WPS_BUTTON), ++ BCM47XX_GPIO_KEY_H(6, KEY_RESTART), ++ BCM47XX_GPIO_KEY_H(7, KEY_WPS_BUTTON), + }; + + static const struct gpio_keys_button diff --git a/queue-4.9/mips-calculate-micromips-ra-properly-when-unwinding-the-stack.patch b/queue-4.9/mips-calculate-micromips-ra-properly-when-unwinding-the-stack.patch new file mode 100644 index 00000000000..ff0d57a2676 --- /dev/null +++ b/queue-4.9/mips-calculate-micromips-ra-properly-when-unwinding-the-stack.patch @@ -0,0 +1,169 @@ +From bb9bc4689b9c635714fbcd5d335bad9934a7ebfc Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Mon, 7 Nov 2016 15:07:06 +0000 +Subject: MIPS: Calculate microMIPS ra properly when unwinding the stack + +From: Paul Burton + +commit bb9bc4689b9c635714fbcd5d335bad9934a7ebfc upstream. + +get_frame_info() calculates the offset of the return address within a +stack frame simply by dividing a the bottom 16 bits of the instruction, +treated as a signed integer, by the size of a long. Whilst this works +for MIPS32 & MIPS64 ISAs where the sw or sd instructions are used, it's +incorrect for microMIPS where encodings differ. The result is that we +typically completely fail to unwind the stack on microMIPS. + +Fix this by adjusting is_ra_save_ins() to calculate the return address +offset, and take into account the various different encodings there in +the same place as we consider whether an instruction is storing the +ra/$31 register. + +With this we are now able to unwind the stack for kernels targetting the +microMIPS ISA, for example we can produce: + + Call Trace: + [<80109e1f>] show_stack+0x63/0x7c + [<8011ea17>] __warn+0x9b/0xac + [<8011ea45>] warn_slowpath_fmt+0x1d/0x20 + [<8013fe53>] register_console+0x43/0x314 + [<8067c58d>] of_setup_earlycon+0x1dd/0x1ec + [<8067f63f>] early_init_dt_scan_chosen_stdout+0xe7/0xf8 + [<8066c115>] do_early_param+0x75/0xac + [<801302f9>] parse_args+0x1dd/0x308 + [<8066c459>] parse_early_options+0x25/0x28 + [<8066c48b>] parse_early_param+0x2f/0x38 + [<8066e8cf>] setup_arch+0x113/0x488 + [<8066c4f3>] start_kernel+0x57/0x328 + ---[ end trace 0000000000000000 ]--- + +Whereas previously we only produced: + + Call Trace: + [<80109e1f>] show_stack+0x63/0x7c + ---[ end trace 0000000000000000 ]--- + +Signed-off-by: Paul Burton +Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.") +Cc: Leonid Yegoshin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/14532/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/process.c | 85 +++++++++++++++++++++++++++++++++------------ + 1 file changed, 64 insertions(+), 21 deletions(-) + +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -195,7 +195,7 @@ struct mips_frame_info { + #define J_TARGET(pc,target) \ + (((unsigned long)(pc) & 0xf0000000) | ((target) << 2)) + +-static inline int is_ra_save_ins(union mips_instruction *ip) ++static inline int is_ra_save_ins(union mips_instruction *ip, int *poff) + { + #ifdef CONFIG_CPU_MICROMIPS + /* +@@ -208,25 +208,70 @@ static inline int is_ra_save_ins(union m + * microMIPS is way more fun... + */ + if (mm_insn_16bit(ip->halfword[1])) { +- return (ip->mm16_r5_format.opcode == mm_swsp16_op && +- ip->mm16_r5_format.rt == 31) || +- (ip->mm16_m_format.opcode == mm_pool16c_op && +- ip->mm16_m_format.func == mm_swm16_op); +- } +- else { +- return (ip->mm_m_format.opcode == mm_pool32b_op && +- ip->mm_m_format.rd > 9 && +- ip->mm_m_format.base == 29 && +- ip->mm_m_format.func == mm_swm32_func) || +- (ip->i_format.opcode == mm_sw32_op && +- ip->i_format.rs == 29 && +- ip->i_format.rt == 31); ++ switch (ip->mm16_r5_format.opcode) { ++ case mm_swsp16_op: ++ if (ip->mm16_r5_format.rt != 31) ++ return 0; ++ ++ *poff = ip->mm16_r5_format.simmediate; ++ *poff = (*poff << 2) / sizeof(ulong); ++ return 1; ++ ++ case mm_pool16c_op: ++ switch (ip->mm16_m_format.func) { ++ case mm_swm16_op: ++ *poff = ip->mm16_m_format.imm; ++ *poff += 1 + ip->mm16_m_format.rlist; ++ *poff = (*poff << 2) / sizeof(ulong); ++ return 1; ++ ++ default: ++ return 0; ++ } ++ ++ default: ++ return 0; ++ } ++ } ++ ++ switch (ip->i_format.opcode) { ++ case mm_sw32_op: ++ if (ip->i_format.rs != 29) ++ return 0; ++ if (ip->i_format.rt != 31) ++ return 0; ++ ++ *poff = ip->i_format.simmediate / sizeof(ulong); ++ return 1; ++ ++ case mm_pool32b_op: ++ switch (ip->mm_m_format.func) { ++ case mm_swm32_func: ++ if (ip->mm_m_format.rd < 0x10) ++ return 0; ++ if (ip->mm_m_format.base != 29) ++ return 0; ++ ++ *poff = ip->mm_m_format.simmediate; ++ *poff += (ip->mm_m_format.rd & 0xf) * sizeof(u32); ++ *poff /= sizeof(ulong); ++ return 1; ++ default: ++ return 0; ++ } ++ ++ default: ++ return 0; + } + #else + /* sw / sd $ra, offset($sp) */ +- return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) && +- ip->i_format.rs == 29 && +- ip->i_format.rt == 31; ++ if ((ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) && ++ ip->i_format.rs == 29 && ip->i_format.rt == 31) { ++ *poff = ip->i_format.simmediate / sizeof(ulong); ++ return 1; ++ } ++ ++ return 0; + #endif + } + +@@ -349,11 +394,9 @@ static int get_frame_info(struct mips_fr + } + continue; + } +- if (info->pc_offset == -1 && is_ra_save_ins(&insn)) { +- info->pc_offset = +- ip->i_format.simmediate / sizeof(long); ++ if (info->pc_offset == -1 && ++ is_ra_save_ins(&insn, &info->pc_offset)) + break; +- } + } + if (info->frame_size && info->pc_offset >= 0) /* nested */ + return 0; diff --git a/queue-4.9/mips-clear-isa-bit-correctly-in-get_frame_info.patch b/queue-4.9/mips-clear-isa-bit-correctly-in-get_frame_info.patch new file mode 100644 index 00000000000..4bc23e80ce8 --- /dev/null +++ b/queue-4.9/mips-clear-isa-bit-correctly-in-get_frame_info.patch @@ -0,0 +1,55 @@ +From ccaf7caf2c73c6db920772bf08bf1d47b2170634 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Mon, 7 Nov 2016 15:07:02 +0000 +Subject: MIPS: Clear ISA bit correctly in get_frame_info() + +From: Paul Burton + +commit ccaf7caf2c73c6db920772bf08bf1d47b2170634 upstream. + +get_frame_info() can be called in microMIPS kernels with the ISA bit +already clear. For example this happens when unwind_stack_by_address() +is called because we begin with a PC that has the ISA bit set & subtract +the (odd) offset from the preceding symbol (which does not have the ISA +bit set). Since get_frame_info() unconditionally subtracts 1 from the PC +in microMIPS kernels it incorrectly misaligns the address it then +attempts to access code at, leading to an address error exception. + +Fix this by using msk_isa16_mode() to clear the ISA bit, which allows +get_frame_info() to function regardless of whether it is provided with a +PC that has the ISA bit set or not. + +Signed-off-by: Paul Burton +Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.") +Cc: Leonid Yegoshin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/14528/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/process.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -303,17 +303,14 @@ static inline int is_sp_move_ins(union m + + static int get_frame_info(struct mips_frame_info *info) + { +-#ifdef CONFIG_CPU_MICROMIPS +- union mips_instruction *ip = (void *) (((char *) info->func) - 1); +-#else +- union mips_instruction *ip = info->func; +-#endif ++ union mips_instruction *ip; + unsigned max_insns = info->func_size / sizeof(union mips_instruction); + unsigned i; + + info->pc_offset = -1; + info->frame_size = 0; + ++ ip = (void *)msk_isa16_mode((ulong)info->func); + if (!ip) + goto err; + diff --git a/queue-4.9/mips-fix-get_frame_info-handling-of-micromips-function-size.patch b/queue-4.9/mips-fix-get_frame_info-handling-of-micromips-function-size.patch new file mode 100644 index 00000000000..0e3c9485b84 --- /dev/null +++ b/queue-4.9/mips-fix-get_frame_info-handling-of-micromips-function-size.patch @@ -0,0 +1,61 @@ +From b6c7a324df37bf05ef7a2c1580683cf10d082d97 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Mon, 7 Nov 2016 15:07:04 +0000 +Subject: MIPS: Fix get_frame_info() handling of microMIPS function size + +From: Paul Burton + +commit b6c7a324df37bf05ef7a2c1580683cf10d082d97 upstream. + +get_frame_info() is meant to iterate over up to the first 128 +instructions within a function, but for microMIPS kernels it will not +reach that many instructions unless the function is 512 bytes long since +we calculate the maximum number of instructions to check by dividing the +function length by the 4 byte size of a union mips_instruction. In +microMIPS kernels this won't do since instructions are variable length. + +Fix this by instead checking whether the pointer to the current +instruction has reached the end of the function, and use max_insns as a +simple constant to check the number of iterations against. + +Signed-off-by: Paul Burton +Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.") +Cc: Leonid Yegoshin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/14530/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/process.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -293,9 +293,9 @@ static inline int is_sp_move_ins(union m + static int get_frame_info(struct mips_frame_info *info) + { + bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS); +- union mips_instruction insn, *ip; +- unsigned max_insns = info->func_size / sizeof(union mips_instruction); +- unsigned i; ++ union mips_instruction insn, *ip, *ip_end; ++ const unsigned int max_insns = 128; ++ unsigned int i; + + info->pc_offset = -1; + info->frame_size = 0; +@@ -304,11 +304,9 @@ static int get_frame_info(struct mips_fr + if (!ip) + goto err; + +- if (max_insns == 0) +- max_insns = 128U; /* unknown function size */ +- max_insns = min(128U, max_insns); ++ ip_end = (void *)ip + info->func_size; + +- for (i = 0; i < max_insns; i++, ip++) { ++ for (i = 0; i < max_insns && ip < ip_end; i++, ip++) { + if (is_mmips && mm_insn_16bit(ip->halfword[0])) { + insn.halfword[0] = 0; + insn.halfword[1] = ip->halfword[0]; diff --git a/queue-4.9/mips-fix-is_jump_ins-handling-of-16b-micromips-instructions.patch b/queue-4.9/mips-fix-is_jump_ins-handling-of-16b-micromips-instructions.patch new file mode 100644 index 00000000000..85ad1ee0ba3 --- /dev/null +++ b/queue-4.9/mips-fix-is_jump_ins-handling-of-16b-micromips-instructions.patch @@ -0,0 +1,45 @@ +From 67c75057709a6d85c681c78b9b2f9b71191f01a2 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Mon, 7 Nov 2016 15:07:05 +0000 +Subject: MIPS: Fix is_jump_ins() handling of 16b microMIPS instructions + +From: Paul Burton + +commit 67c75057709a6d85c681c78b9b2f9b71191f01a2 upstream. + +is_jump_ins() checks 16b instruction fields without verifying that the +instruction is indeed 16b, as is done by is_ra_save_ins() & +is_sp_move_ins(). Add the appropriate check. + +Signed-off-by: Paul Burton +Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.") +Cc: Leonid Yegoshin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/14531/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/process.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -241,9 +241,14 @@ static inline int is_jump_ins(union mips + * + * microMIPS is kind of more fun... + */ +- if ((ip->mm16_r5_format.opcode == mm_pool16c_op && +- (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) || +- ip->j_format.opcode == mm_jal32_op) ++ if (mm_insn_16bit(ip->halfword[1])) { ++ if ((ip->mm16_r5_format.opcode == mm_pool16c_op && ++ (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op)) ++ return 1; ++ return 0; ++ } ++ ++ if (ip->j_format.opcode == mm_jal32_op) + return 1; + if (ip->r_format.opcode != mm_pool32a_op || + ip->r_format.func != mm_pool32axf_op) diff --git a/queue-4.9/mips-fix-special-case-in-64-bit-ip-checksumming.patch b/queue-4.9/mips-fix-special-case-in-64-bit-ip-checksumming.patch new file mode 100644 index 00000000000..cd86f73cae7 --- /dev/null +++ b/queue-4.9/mips-fix-special-case-in-64-bit-ip-checksumming.patch @@ -0,0 +1,37 @@ +From 66fd848cadaa6be974a8c780fbeb328f0af4d3bd Mon Sep 17 00:00:00 2001 +From: Ralf Baechle +Date: Thu, 26 Jan 2017 02:16:47 +0100 +Subject: MIPS: Fix special case in 64 bit IP checksumming. + +From: Ralf Baechle + +commit 66fd848cadaa6be974a8c780fbeb328f0af4d3bd upstream. + +For certain arguments such as saddr = 0xc0a8fd60, daddr = 0xc0a8fda1, +len = 80, proto = 17, sum = 0x7eae049d there will be a carry when +folding the intermediate 64 bit checksum to 32 bit but the code doesn't +add the carry back to the one's complement sum, thus an incorrect result +will be generated. + +Reported-by: Mark Zhang +Signed-off-by: Ralf Baechle +Reviewed-by: James Hogan +Signed-off-by: James Hogan +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/include/asm/checksum.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/mips/include/asm/checksum.h ++++ b/arch/mips/include/asm/checksum.h +@@ -186,7 +186,9 @@ static inline __wsum csum_tcpudp_nofold( + " daddu %0, %4 \n" + " dsll32 $1, %0, 0 \n" + " daddu %0, $1 \n" ++ " sltu $1, %0, $1 \n" + " dsra32 %0, %0, 0 \n" ++ " addu %0, $1 \n" + #endif + " .set pop" + : "=r" (sum) diff --git a/queue-4.9/mips-handle-micromips-jumps-in-the-same-way-as-mips32-mips64-jumps.patch b/queue-4.9/mips-handle-micromips-jumps-in-the-same-way-as-mips32-mips64-jumps.patch new file mode 100644 index 00000000000..fd7f61964e1 --- /dev/null +++ b/queue-4.9/mips-handle-micromips-jumps-in-the-same-way-as-mips32-mips64-jumps.patch @@ -0,0 +1,38 @@ +From 096a0de427ea333f56f0ee00328cff2a2731bcf1 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Mon, 7 Nov 2016 15:07:07 +0000 +Subject: MIPS: Handle microMIPS jumps in the same way as MIPS32/MIPS64 jumps + +From: Paul Burton + +commit 096a0de427ea333f56f0ee00328cff2a2731bcf1 upstream. + +is_jump_ins() checks for plain jump ("j") instructions since commit +e7438c4b893e ("MIPS: Fix sibling call handling in get_frame_info") but +that commit didn't make the same change to the microMIPS code, leaving +it inconsistent with the MIPS32/MIPS64 code. Handle the microMIPS +encoding of the jump instruction too such that it behaves consistently. + +Signed-off-by: Paul Burton +Fixes: e7438c4b893e ("MIPS: Fix sibling call handling in get_frame_info") +Cc: Tony Wu +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/14533/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/process.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -293,6 +293,8 @@ static inline int is_jump_ins(union mips + return 0; + } + ++ if (ip->j_format.opcode == mm_j32_op) ++ return 1; + if (ip->j_format.opcode == mm_jal32_op) + return 1; + if (ip->r_format.opcode != mm_pool32a_op || diff --git a/queue-4.9/mips-lantiq-keep-ethernet-enabled-during-boot.patch b/queue-4.9/mips-lantiq-keep-ethernet-enabled-during-boot.patch new file mode 100644 index 00000000000..af51a506aa5 --- /dev/null +++ b/queue-4.9/mips-lantiq-keep-ethernet-enabled-during-boot.patch @@ -0,0 +1,64 @@ +From 774f0c6419bb8f9d83901d33582c7fe3ba6a6cb3 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 19 Jan 2017 14:20:09 +0100 +Subject: MIPS: Lantiq: Keep ethernet enabled during boot + +From: Felix Fietkau + +commit 774f0c6419bb8f9d83901d33582c7fe3ba6a6cb3 upstream. + +Disabling ethernet during reboot (only to enable it again when the +ethernet driver attaches) can put the chip into a faulty state where it +corrupts the header of all incoming packets. + +This happens if packets arrive during the time window where the core is +disabled, and it can be easily reproduced by rebooting while sending a +flood ping to the broadcast address. + +Fixes: 95135bfa7ead ("MIPS: Lantiq: Deactivate most of the devices by default") +Signed-off-by: Felix Fietkau +Acked-by: John Crispin +Cc: hauke.mehrtens@lantiq.com +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/15078/ +Signed-off-by: James Hogan +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/lantiq/xway/sysctrl.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/mips/lantiq/xway/sysctrl.c ++++ b/arch/mips/lantiq/xway/sysctrl.c +@@ -545,7 +545,7 @@ void __init ltq_soc_init(void) + clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI); + clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI); + clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL); +- clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH | PMU_PPE_DP); ++ clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP); + clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); + clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); + } else if (of_machine_is_compatible("lantiq,ar10")) { +@@ -553,7 +553,7 @@ void __init ltq_soc_init(void) + ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz()); + clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); + clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); +- clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH | ++ clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH | + PMU_PPE_DP | PMU_PPE_TC); + clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); + clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY); +@@ -575,11 +575,11 @@ void __init ltq_soc_init(void) + clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS); + + clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); +- clkdev_add_pmu("1e108000.eth", NULL, 1, 0, ++ clkdev_add_pmu("1e108000.eth", NULL, 0, 0, + PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | + PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | + PMU_PPE_QSB | PMU_PPE_TOP); +- clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY); ++ clkdev_add_pmu("1f203000.rcu", "gphy", 0, 0, PMU_GPHY); + clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); + clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); + clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); diff --git a/queue-4.9/mips-octeon-fix-copy_from_user-fault-handling-for-large-buffers.patch b/queue-4.9/mips-octeon-fix-copy_from_user-fault-handling-for-large-buffers.patch new file mode 100644 index 00000000000..0b3c93ecb6d --- /dev/null +++ b/queue-4.9/mips-octeon-fix-copy_from_user-fault-handling-for-large-buffers.patch @@ -0,0 +1,83 @@ +From 884b426917e4b3c85f33b382c792a94305dfdd62 Mon Sep 17 00:00:00 2001 +From: James Cowgill +Date: Mon, 9 Jan 2017 16:52:28 +0000 +Subject: MIPS: OCTEON: Fix copy_from_user fault handling for large buffers + +From: James Cowgill + +commit 884b426917e4b3c85f33b382c792a94305dfdd62 upstream. + +If copy_from_user is called with a large buffer (>= 128 bytes) and the +userspace buffer refers partially to unreadable memory, then it is +possible for Octeon's copy_from_user to report the wrong number of bytes +have been copied. In the case where the buffer size is an exact multiple +of 128 and the fault occurs in the last 64 bytes, copy_from_user will +report that all the bytes were copied successfully but leave some +garbage in the destination buffer. + +The bug is in the main __copy_user_common loop in octeon-memcpy.S where +in the middle of the loop, src and dst are incremented by 128 bytes. The +l_exc_copy fault handler is used after this but that assumes that +"src < THREAD_BUADDR($28)". This is not the case if src has already been +incremented. + +Fix by adding an extra fault handler which rewinds the src and dst +pointers 128 bytes before falling though to l_exc_copy. + +Thanks to the pwritev test from the strace test suite for originally +highlighting this bug! + +Fixes: 5b3b16880f40 ("MIPS: Add Cavium OCTEON processor support ...") +Signed-off-by: James Cowgill +Acked-by: David Daney +Reviewed-by: James Hogan +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/14978/ +Signed-off-by: James Hogan +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/cavium-octeon/octeon-memcpy.S | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +--- a/arch/mips/cavium-octeon/octeon-memcpy.S ++++ b/arch/mips/cavium-octeon/octeon-memcpy.S +@@ -208,18 +208,18 @@ EXC( STORE t2, UNIT(6)(dst), s_exc_p10u) + ADD src, src, 16*NBYTES + EXC( STORE t3, UNIT(7)(dst), s_exc_p9u) + ADD dst, dst, 16*NBYTES +-EXC( LOAD t0, UNIT(-8)(src), l_exc_copy) +-EXC( LOAD t1, UNIT(-7)(src), l_exc_copy) +-EXC( LOAD t2, UNIT(-6)(src), l_exc_copy) +-EXC( LOAD t3, UNIT(-5)(src), l_exc_copy) ++EXC( LOAD t0, UNIT(-8)(src), l_exc_copy_rewind16) ++EXC( LOAD t1, UNIT(-7)(src), l_exc_copy_rewind16) ++EXC( LOAD t2, UNIT(-6)(src), l_exc_copy_rewind16) ++EXC( LOAD t3, UNIT(-5)(src), l_exc_copy_rewind16) + EXC( STORE t0, UNIT(-8)(dst), s_exc_p8u) + EXC( STORE t1, UNIT(-7)(dst), s_exc_p7u) + EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u) + EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u) +-EXC( LOAD t0, UNIT(-4)(src), l_exc_copy) +-EXC( LOAD t1, UNIT(-3)(src), l_exc_copy) +-EXC( LOAD t2, UNIT(-2)(src), l_exc_copy) +-EXC( LOAD t3, UNIT(-1)(src), l_exc_copy) ++EXC( LOAD t0, UNIT(-4)(src), l_exc_copy_rewind16) ++EXC( LOAD t1, UNIT(-3)(src), l_exc_copy_rewind16) ++EXC( LOAD t2, UNIT(-2)(src), l_exc_copy_rewind16) ++EXC( LOAD t3, UNIT(-1)(src), l_exc_copy_rewind16) + EXC( STORE t0, UNIT(-4)(dst), s_exc_p4u) + EXC( STORE t1, UNIT(-3)(dst), s_exc_p3u) + EXC( STORE t2, UNIT(-2)(dst), s_exc_p2u) +@@ -383,6 +383,10 @@ done: + nop + END(memcpy) + ++l_exc_copy_rewind16: ++ /* Rewind src and dst by 16*NBYTES for l_exc_copy */ ++ SUB src, src, 16*NBYTES ++ SUB dst, dst, 16*NBYTES + l_exc_copy: + /* + * Copy bytes from src until faulting load address (or until a diff --git a/queue-4.9/mips-pic32mzda-fix-linker-error-for-pic32_get_pbclk.patch b/queue-4.9/mips-pic32mzda-fix-linker-error-for-pic32_get_pbclk.patch new file mode 100644 index 00000000000..e97d6e98289 --- /dev/null +++ b/queue-4.9/mips-pic32mzda-fix-linker-error-for-pic32_get_pbclk.patch @@ -0,0 +1,44 @@ +From a726f1d2dd4fee179aa4513176d688ad309de6cc Mon Sep 17 00:00:00 2001 +From: Purna Chandra Mandal +Date: Thu, 2 Jun 2016 14:51:42 +0530 +Subject: MIPS: pic32mzda: Fix linker error for pic32_get_pbclk() + +From: Purna Chandra Mandal + +commit a726f1d2dd4fee179aa4513176d688ad309de6cc upstream. + +Early clock API pic32_get_pbclk() is defined in early_clk.c and used by +time.c and early_console.c. When CONFIG_EARLY_PRINTK isn't set, +early_clk.c isn't compiled and time.c fails to link. + +Fix it by compiling early_clk.c always. Also sort files in alphabetical +order. + +Fixes: 6e4ad1b41360 ("MIPS: pic32mzda: fix getting timer clock rate.") +Reported-by: Harvey Hunt +Signed-off-by: Purna Chandra Mandal +Reviewed-by: Harvey Hunt +Cc: Ralf Baechle +Cc: Joshua Henderson +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/13383/ +Signed-off-by: James Hogan +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/pic32/pic32mzda/Makefile | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/arch/mips/pic32/pic32mzda/Makefile ++++ b/arch/mips/pic32/pic32mzda/Makefile +@@ -2,8 +2,7 @@ + # Joshua Henderson, + # Copyright (C) 2015 Microchip Technology, Inc. All rights reserved. + # +-obj-y := init.o time.o config.o ++obj-y := config.o early_clk.o init.o time.o + + obj-$(CONFIG_EARLY_PRINTK) += early_console.o \ +- early_pin.o \ +- early_clk.o ++ early_pin.o diff --git a/queue-4.9/mips-prevent-unaligned-accesses-during-stack-unwinding.patch b/queue-4.9/mips-prevent-unaligned-accesses-during-stack-unwinding.patch new file mode 100644 index 00000000000..603527d86a0 --- /dev/null +++ b/queue-4.9/mips-prevent-unaligned-accesses-during-stack-unwinding.patch @@ -0,0 +1,164 @@ +From a3552dace7d1d0cabf573e88fc3025cb90c4a601 Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Mon, 7 Nov 2016 15:07:03 +0000 +Subject: MIPS: Prevent unaligned accesses during stack unwinding + +From: Paul Burton + +commit a3552dace7d1d0cabf573e88fc3025cb90c4a601 upstream. + +During stack unwinding we call a number of functions to determine what +type of instruction we're looking at. The union mips_instruction pointer +provided to them may be pointing at a 2 byte, but not 4 byte, aligned +address & we thus cannot directly access the 4 byte wide members of the +union mips_instruction. To avoid this is_ra_save_ins() copies the +required half-words of the microMIPS instruction to a correctly aligned +union mips_instruction on the stack, which it can then access safely. +The is_jump_ins() & is_sp_move_ins() functions do not correctly perform +this temporary copy, and instead attempt to directly dereference 4 byte +fields which may be misaligned and lead to an address exception. + +Fix this by copying the instruction halfwords to a temporary union +mips_instruction in get_frame_info() such that we can provide a 4 byte +aligned union mips_instruction to the is_*_ins() functions and they do +not need to deal with misalignment themselves. + +Signed-off-by: Paul Burton +Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.") +Cc: Leonid Yegoshin +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/14529/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/process.c | 70 ++++++++++++++++++++++----------------------- + 1 file changed, 35 insertions(+), 35 deletions(-) + +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -198,8 +198,6 @@ struct mips_frame_info { + static inline int is_ra_save_ins(union mips_instruction *ip) + { + #ifdef CONFIG_CPU_MICROMIPS +- union mips_instruction mmi; +- + /* + * swsp ra,offset + * swm16 reglist,offset(sp) +@@ -209,23 +207,20 @@ static inline int is_ra_save_ins(union m + * + * microMIPS is way more fun... + */ +- if (mm_insn_16bit(ip->halfword[0])) { +- mmi.word = (ip->halfword[0] << 16); +- return (mmi.mm16_r5_format.opcode == mm_swsp16_op && +- mmi.mm16_r5_format.rt == 31) || +- (mmi.mm16_m_format.opcode == mm_pool16c_op && +- mmi.mm16_m_format.func == mm_swm16_op); ++ if (mm_insn_16bit(ip->halfword[1])) { ++ return (ip->mm16_r5_format.opcode == mm_swsp16_op && ++ ip->mm16_r5_format.rt == 31) || ++ (ip->mm16_m_format.opcode == mm_pool16c_op && ++ ip->mm16_m_format.func == mm_swm16_op); + } + else { +- mmi.halfword[0] = ip->halfword[1]; +- mmi.halfword[1] = ip->halfword[0]; +- return (mmi.mm_m_format.opcode == mm_pool32b_op && +- mmi.mm_m_format.rd > 9 && +- mmi.mm_m_format.base == 29 && +- mmi.mm_m_format.func == mm_swm32_func) || +- (mmi.i_format.opcode == mm_sw32_op && +- mmi.i_format.rs == 29 && +- mmi.i_format.rt == 31); ++ return (ip->mm_m_format.opcode == mm_pool32b_op && ++ ip->mm_m_format.rd > 9 && ++ ip->mm_m_format.base == 29 && ++ ip->mm_m_format.func == mm_swm32_func) || ++ (ip->i_format.opcode == mm_sw32_op && ++ ip->i_format.rs == 29 && ++ ip->i_format.rt == 31); + } + #else + /* sw / sd $ra, offset($sp) */ +@@ -246,12 +241,8 @@ static inline int is_jump_ins(union mips + * + * microMIPS is kind of more fun... + */ +- union mips_instruction mmi; +- +- mmi.word = (ip->halfword[0] << 16); +- +- if ((mmi.mm16_r5_format.opcode == mm_pool16c_op && +- (mmi.mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) || ++ if ((ip->mm16_r5_format.opcode == mm_pool16c_op && ++ (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) || + ip->j_format.opcode == mm_jal32_op) + return 1; + if (ip->r_format.opcode != mm_pool32a_op || +@@ -280,15 +271,13 @@ static inline int is_sp_move_ins(union m + * + * microMIPS is not more fun... + */ +- if (mm_insn_16bit(ip->halfword[0])) { +- union mips_instruction mmi; +- +- mmi.word = (ip->halfword[0] << 16); +- return (mmi.mm16_r3_format.opcode == mm_pool16d_op && +- mmi.mm16_r3_format.simmediate && mm_addiusp_func) || +- (mmi.mm16_r5_format.opcode == mm_pool16d_op && +- mmi.mm16_r5_format.rt == 29); ++ if (mm_insn_16bit(ip->halfword[1])) { ++ return (ip->mm16_r3_format.opcode == mm_pool16d_op && ++ ip->mm16_r3_format.simmediate && mm_addiusp_func) || ++ (ip->mm16_r5_format.opcode == mm_pool16d_op && ++ ip->mm16_r5_format.rt == 29); + } ++ + return ip->mm_i_format.opcode == mm_addiu32_op && + ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29; + #else +@@ -303,7 +292,8 @@ static inline int is_sp_move_ins(union m + + static int get_frame_info(struct mips_frame_info *info) + { +- union mips_instruction *ip; ++ bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS); ++ union mips_instruction insn, *ip; + unsigned max_insns = info->func_size / sizeof(union mips_instruction); + unsigned i; + +@@ -319,11 +309,21 @@ static int get_frame_info(struct mips_fr + max_insns = min(128U, max_insns); + + for (i = 0; i < max_insns; i++, ip++) { ++ if (is_mmips && mm_insn_16bit(ip->halfword[0])) { ++ insn.halfword[0] = 0; ++ insn.halfword[1] = ip->halfword[0]; ++ } else if (is_mmips) { ++ insn.halfword[0] = ip->halfword[1]; ++ insn.halfword[1] = ip->halfword[0]; ++ } else { ++ insn.word = ip->word; ++ } + +- if (is_jump_ins(ip)) ++ if (is_jump_ins(&insn)) + break; ++ + if (!info->frame_size) { +- if (is_sp_move_ins(ip)) ++ if (is_sp_move_ins(&insn)) + { + #ifdef CONFIG_CPU_MICROMIPS + if (mm_insn_16bit(ip->halfword[0])) +@@ -346,7 +346,7 @@ static int get_frame_info(struct mips_fr + } + continue; + } +- if (info->pc_offset == -1 && is_ra_save_ins(ip)) { ++ if (info->pc_offset == -1 && is_ra_save_ins(&insn)) { + info->pc_offset = + ip->i_format.simmediate / sizeof(long); + break; diff --git a/queue-4.9/mmc-sdhci-acpi-support-deferred-probe.patch b/queue-4.9/mmc-sdhci-acpi-support-deferred-probe.patch new file mode 100644 index 00000000000..1c982f12af1 --- /dev/null +++ b/queue-4.9/mmc-sdhci-acpi-support-deferred-probe.patch @@ -0,0 +1,42 @@ +From e28d6f048799acb0014491e6b74e580d84bd7916 Mon Sep 17 00:00:00 2001 +From: Zhang Rui +Date: Wed, 18 Jan 2017 17:46:18 +0800 +Subject: mmc: sdhci-acpi: support deferred probe + +From: Zhang Rui + +commit e28d6f048799acb0014491e6b74e580d84bd7916 upstream. + +With commit 67bf5156edc4 ("gpio / ACPI: fix returned error from +acpi_dev_gpio_irq_get()"), mmc_gpiod_request_cd() returns -EPROBE_DEFER if +GPIO is not ready when sdhci-acpi driver is probed, and sdhci-acpi driver +should be probed again later in this case. + +This fixes an order issue when both GPIO and sdhci-acpi drivers are built +as modules. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=177101 +Tested-by: Jonas Aaberg +Signed-off-by: Zhang Rui +Acked-by: Adrian Hunter +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mmc/host/sdhci-acpi.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/sdhci-acpi.c ++++ b/drivers/mmc/host/sdhci-acpi.c +@@ -466,7 +466,10 @@ static int sdhci_acpi_probe(struct platf + if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) { + bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL); + +- if (mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL)) { ++ err = mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL); ++ if (err) { ++ if (err == -EPROBE_DEFER) ++ goto err_free; + dev_warn(dev, "failed to setup card detect gpio\n"); + c->use_runtime_pm = false; + } diff --git a/queue-4.9/uvcvideo-fix-a-wrong-macro.patch b/queue-4.9/uvcvideo-fix-a-wrong-macro.patch new file mode 100644 index 00000000000..4016f668175 --- /dev/null +++ b/queue-4.9/uvcvideo-fix-a-wrong-macro.patch @@ -0,0 +1,33 @@ +From 17c341ec0115837a610b2da15e32546e26068234 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski +Date: Mon, 12 Dec 2016 09:16:51 -0200 +Subject: [media] uvcvideo: Fix a wrong macro + +From: Guennadi Liakhovetski + +commit 17c341ec0115837a610b2da15e32546e26068234 upstream. + +Don't mix up UVC_BUF_STATE_* and VB2_BUF_STATE_* codes. + +Fixes: 6998b6fb4b1c ("[media] uvcvideo: Use videobuf2-vmalloc") + +Signed-off-by: Guennadi Liakhovetski +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/uvc/uvc_queue.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/usb/uvc/uvc_queue.c ++++ b/drivers/media/usb/uvc/uvc_queue.c +@@ -412,7 +412,7 @@ struct uvc_buffer *uvc_queue_next_buffer + nextbuf = NULL; + spin_unlock_irqrestore(&queue->irqlock, flags); + +- buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE; ++ buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE; + vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused); + vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE); +