]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 Mar 2017 07:00:00 +0000 (08:00 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 Mar 2017 07:00:00 +0000 (08:00 +0100)
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

19 files changed:
queue-4.9/am437x-vpfe-always-assign-bpp-variable.patch [new file with mode: 0644]
queue-4.9/cxd2820r-fix-gpio-null-pointer-dereference.patch [new file with mode: 0644]
queue-4.9/ext4-fix-deadlock-between-inline_data-and-ext4_expand_extra_isize_ea.patch [new file with mode: 0644]
queue-4.9/lirc_dev-lirc_-g-s-et_rec_mode-do-not-work.patch [new file with mode: 0644]
queue-4.9/media-fix-dm1105.c-build-error.patch [new file with mode: 0644]
queue-4.9/media-properly-pass-through-media-entity-types-in-entity-enumeration.patch [new file with mode: 0644]
queue-4.9/mips-bcm47xx-fix-button-inversion-for-asus-wl-500w.patch [new file with mode: 0644]
queue-4.9/mips-calculate-micromips-ra-properly-when-unwinding-the-stack.patch [new file with mode: 0644]
queue-4.9/mips-clear-isa-bit-correctly-in-get_frame_info.patch [new file with mode: 0644]
queue-4.9/mips-fix-get_frame_info-handling-of-micromips-function-size.patch [new file with mode: 0644]
queue-4.9/mips-fix-is_jump_ins-handling-of-16b-micromips-instructions.patch [new file with mode: 0644]
queue-4.9/mips-fix-special-case-in-64-bit-ip-checksumming.patch [new file with mode: 0644]
queue-4.9/mips-handle-micromips-jumps-in-the-same-way-as-mips32-mips64-jumps.patch [new file with mode: 0644]
queue-4.9/mips-lantiq-keep-ethernet-enabled-during-boot.patch [new file with mode: 0644]
queue-4.9/mips-octeon-fix-copy_from_user-fault-handling-for-large-buffers.patch [new file with mode: 0644]
queue-4.9/mips-pic32mzda-fix-linker-error-for-pic32_get_pbclk.patch [new file with mode: 0644]
queue-4.9/mips-prevent-unaligned-accesses-during-stack-unwinding.patch [new file with mode: 0644]
queue-4.9/mmc-sdhci-acpi-support-deferred-probe.patch [new file with mode: 0644]
queue-4.9/uvcvideo-fix-a-wrong-macro.patch [new file with mode: 0644]

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 (file)
index 0000000..4a73e08
--- /dev/null
@@ -0,0 +1,41 @@
+From 6ebf75774f823ddbdbd10921006989d4df222f4a Mon Sep 17 00:00:00 2001
+From: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
+Date: Tue, 27 Dec 2016 16:02:36 -0200
+Subject: [media] am437x-vpfe: always assign bpp variable
+
+From: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
+
+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 <nicolas.iooss_linux@m4x.org>
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..9dda082
--- /dev/null
@@ -0,0 +1,49 @@
+From 0ffb94b6cc5df6376ab6bff5b80075641f6716f8 Mon Sep 17 00:00:00 2001
+From: Antti Palosaari <crope@iki.fi>
+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 <crope@iki.fi>
+
+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 <rankincj@gmail.com>
+Tested-by: Chris Rankin <rankincj@gmail.com>
+Tested-by: Håkan Lennestål <hakan.lennestal@gmail.com>
+Signed-off-by: Antti Palosaari <crope@iki.fi>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..418a52e
--- /dev/null
@@ -0,0 +1,472 @@
+From c755e251357a0cee0679081f08c3f4ba797a8009 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+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 <tytso@mit.edu>
+
+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: [<c1225a4b>] ext4_expand_extra_isize_ea+0x3d/0x4cd
+[   11.161960]
+[   11.161960] but task is already holding lock:
+[   11.161960]  (&ei->xattr_sem){++++..}, at: [<c1227941>] 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: [<c11a2414>] mnt_want_write+0x1e/0x3e
+[   11.161960]  #1:  (&type->i_mutex_dir_key){++++++}, at: [<c119508b>] path_openat+0x338/0x67a
+[   11.161960]  #2:  (jbd2_handle){++++..}, at: [<c123314a>] start_this_handle+0x582/0x622
+[   11.161960]  #3:  (&ei->xattr_sem){++++..}, at: [<c1227941>] 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 <linux@sciencehorizons.net>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..31fb6d7
--- /dev/null
@@ -0,0 +1,41 @@
+From bd291208d7f5d6b2d6a033fee449a429230b06df Mon Sep 17 00:00:00 2001
+From: Sean Young <sean@mess.org>
+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 <sean@mess.org>
+
+commit bd291208d7f5d6b2d6a033fee449a429230b06df upstream.
+
+Since "273b902 [media] lirc_dev: use LIRC_CAN_REC() define" these
+ioctls no longer work.
+
+Signed-off-by: Sean Young <sean@mess.org>
+Reviewed-by: Andi Shyti <andi.shyti@samsung.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..e934084
--- /dev/null
@@ -0,0 +1,36 @@
+From e3bb3cddd177550d63a3e4909cf1a7782f13414d Mon Sep 17 00:00:00 2001
+From: Randy Dunlap <rdunlap@infradead.org>
+Date: Sat, 7 Jan 2017 23:08:49 -0200
+Subject: [media] media: fix dm1105.c build error
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+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 <rdunlap@infradead.org>
+Reported-by: kbuild test robot <fengguang.wu@intel.com>
+Cc: Javier Martinez Canillas <javier@osg.samsung.com>
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..36ce4d0
--- /dev/null
@@ -0,0 +1,37 @@
+From 98d85f3cb912fde14593ead54dea4c1a00b3966f Mon Sep 17 00:00:00 2001
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+Date: Mon, 2 Jan 2017 08:32:47 -0200
+Subject: [media] media: Properly pass through media entity types in entity enumeration
+
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+
+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 <antti.laakso@intel.com>
+
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..fcc117e
--- /dev/null
@@ -0,0 +1,54 @@
+From bdfdaf1a016ef09cb941f2edad485a713510b8d5 Mon Sep 17 00:00:00 2001
+From: Mirko Parthey <mirko.parthey@web.de>
+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 <mirko.parthey@web.de>
+
+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 <mirko.parthey@web.de>
+Acked-by: Rafał Miłecki <rafal@milecki.pl>
+Cc: Hauke Mehrtens <hauke@hauke-m.de>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/15295/
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..ff0d57a
--- /dev/null
@@ -0,0 +1,169 @@
+From bb9bc4689b9c635714fbcd5d335bad9934a7ebfc Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Mon, 7 Nov 2016 15:07:06 +0000
+Subject: MIPS: Calculate microMIPS ra properly when unwinding the stack
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+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 <paul.burton@imgtec.com>
+Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
+Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/14532/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..4bc23e8
--- /dev/null
@@ -0,0 +1,55 @@
+From ccaf7caf2c73c6db920772bf08bf1d47b2170634 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Mon, 7 Nov 2016 15:07:02 +0000
+Subject: MIPS: Clear ISA bit correctly in get_frame_info()
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+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 <paul.burton@imgtec.com>
+Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
+Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/14528/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..0e3c948
--- /dev/null
@@ -0,0 +1,61 @@
+From b6c7a324df37bf05ef7a2c1580683cf10d082d97 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Mon, 7 Nov 2016 15:07:04 +0000
+Subject: MIPS: Fix get_frame_info() handling of microMIPS function size
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+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 <paul.burton@imgtec.com>
+Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
+Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/14530/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..85ad1ee
--- /dev/null
@@ -0,0 +1,45 @@
+From 67c75057709a6d85c681c78b9b2f9b71191f01a2 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Mon, 7 Nov 2016 15:07:05 +0000
+Subject: MIPS: Fix is_jump_ins() handling of 16b microMIPS instructions
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+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 <paul.burton@imgtec.com>
+Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
+Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/14531/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..cd86f73
--- /dev/null
@@ -0,0 +1,37 @@
+From 66fd848cadaa6be974a8c780fbeb328f0af4d3bd Mon Sep 17 00:00:00 2001
+From: Ralf Baechle <ralf@linux-mips.org>
+Date: Thu, 26 Jan 2017 02:16:47 +0100
+Subject: MIPS: Fix special case in 64 bit IP checksumming.
+
+From: Ralf Baechle <ralf@linux-mips.org>
+
+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 <bomb.zhang@gmail.com>
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..fd7f619
--- /dev/null
@@ -0,0 +1,38 @@
+From 096a0de427ea333f56f0ee00328cff2a2731bcf1 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+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 <paul.burton@imgtec.com>
+
+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 <paul.burton@imgtec.com>
+Fixes: e7438c4b893e ("MIPS: Fix sibling call handling in get_frame_info")
+Cc: Tony Wu <tung7970@gmail.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/14533/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..af51a50
--- /dev/null
@@ -0,0 +1,64 @@
+From 774f0c6419bb8f9d83901d33582c7fe3ba6a6cb3 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 19 Jan 2017 14:20:09 +0100
+Subject: MIPS: Lantiq: Keep ethernet enabled during boot
+
+From: Felix Fietkau <nbd@nbd.name>
+
+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 <nbd@nbd.name>
+Acked-by: John Crispin <john@phrozen.org>
+Cc: hauke.mehrtens@lantiq.com
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/15078/
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..0b3c93e
--- /dev/null
@@ -0,0 +1,83 @@
+From 884b426917e4b3c85f33b382c792a94305dfdd62 Mon Sep 17 00:00:00 2001
+From: James Cowgill <James.Cowgill@imgtec.com>
+Date: Mon, 9 Jan 2017 16:52:28 +0000
+Subject: MIPS: OCTEON: Fix copy_from_user fault handling for large buffers
+
+From: James Cowgill <James.Cowgill@imgtec.com>
+
+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 <James.Cowgill@imgtec.com>
+Acked-by: David Daney <david.daney@cavium.com>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/14978/
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..e97d6e9
--- /dev/null
@@ -0,0 +1,44 @@
+From a726f1d2dd4fee179aa4513176d688ad309de6cc Mon Sep 17 00:00:00 2001
+From: Purna Chandra Mandal <purna.mandal@microchip.com>
+Date: Thu, 2 Jun 2016 14:51:42 +0530
+Subject: MIPS: pic32mzda: Fix linker error for pic32_get_pbclk()
+
+From: Purna Chandra Mandal <purna.mandal@microchip.com>
+
+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 <harvey.hunt@imgtec.com>
+Signed-off-by: Purna Chandra Mandal <purna.mandal@microchip.com>
+Reviewed-by: Harvey Hunt <harvey.hunt@imgtec.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: Joshua Henderson <digitalpeer@digitalpeer.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/13383/
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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, <joshua.henderson@microchip.com>
+ # 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 (file)
index 0000000..603527d
--- /dev/null
@@ -0,0 +1,164 @@
+From a3552dace7d1d0cabf573e88fc3025cb90c4a601 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@imgtec.com>
+Date: Mon, 7 Nov 2016 15:07:03 +0000
+Subject: MIPS: Prevent unaligned accesses during stack unwinding
+
+From: Paul Burton <paul.burton@imgtec.com>
+
+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 <paul.burton@imgtec.com>
+Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
+Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/14529/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..1c982f1
--- /dev/null
@@ -0,0 +1,42 @@
+From e28d6f048799acb0014491e6b74e580d84bd7916 Mon Sep 17 00:00:00 2001
+From: Zhang Rui <rui.zhang@intel.com>
+Date: Wed, 18 Jan 2017 17:46:18 +0800
+Subject: mmc: sdhci-acpi: support deferred probe
+
+From: Zhang Rui <rui.zhang@intel.com>
+
+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 <cja@gmx.net>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..4016f66
--- /dev/null
@@ -0,0 +1,33 @@
+From 17c341ec0115837a610b2da15e32546e26068234 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Mon, 12 Dec 2016 09:16:51 -0200
+Subject: [media] uvcvideo: Fix a wrong macro
+
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+
+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 <guennadi.liakhovetski@intel.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);