]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jan 2017 14:00:19 +0000 (15:00 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jan 2017 14:00:19 +0000 (15:00 +0100)
added patches:
arm-xen-use-alloc_percpu-rather-than-__alloc_percpu.patch
cifs-decrease-verbosity-of-ioctl-call.patch
cifs-fix-a-possible-double-locking-of-mutex-during-reconnect.patch
cifs-fix-a-possible-memory-corruption-during-reconnect.patch
cifs-fix-a-possible-memory-corruption-in-push-locks.patch
cifs-fix-missing-nls-unload-in-smb2_reconnect.patch
cifs-fix-smbencrypt-to-stop-pointing-a-scatterlist-at-the-stack.patch
kernel-debug-debug_core.c-more-properly-delay-for-secondary-cpus.patch
kernel-watchdog-use-nmi-registers-snapshot-in-hardlockup-handler.patch
tpm-xen-remove-bogus-tpm_chip_unregister.patch
watchdog-mei_wdt-request-stop-on-reboot-to-prevent-false-positive-event.patch
watchdog-qcom-fix-kernel-panic-due-to-external-abort-on-non-linefetch.patch
xen-gntdev-use-vm_mixedmap-instead-of-vm_io-to-avoid-numa-balancing.patch
xfs-fix-up-xfs_swap_extent_forks-inline-extent-handling.patch
xfs-set-agi-buffer-type-in-xlog_recover_clear_agi_bucket.patch

16 files changed:
queue-4.9/arm-xen-use-alloc_percpu-rather-than-__alloc_percpu.patch [new file with mode: 0644]
queue-4.9/cifs-decrease-verbosity-of-ioctl-call.patch [new file with mode: 0644]
queue-4.9/cifs-fix-a-possible-double-locking-of-mutex-during-reconnect.patch [new file with mode: 0644]
queue-4.9/cifs-fix-a-possible-memory-corruption-during-reconnect.patch [new file with mode: 0644]
queue-4.9/cifs-fix-a-possible-memory-corruption-in-push-locks.patch [new file with mode: 0644]
queue-4.9/cifs-fix-missing-nls-unload-in-smb2_reconnect.patch [new file with mode: 0644]
queue-4.9/cifs-fix-smbencrypt-to-stop-pointing-a-scatterlist-at-the-stack.patch [new file with mode: 0644]
queue-4.9/kernel-debug-debug_core.c-more-properly-delay-for-secondary-cpus.patch [new file with mode: 0644]
queue-4.9/kernel-watchdog-use-nmi-registers-snapshot-in-hardlockup-handler.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/tpm-xen-remove-bogus-tpm_chip_unregister.patch [new file with mode: 0644]
queue-4.9/watchdog-mei_wdt-request-stop-on-reboot-to-prevent-false-positive-event.patch [new file with mode: 0644]
queue-4.9/watchdog-qcom-fix-kernel-panic-due-to-external-abort-on-non-linefetch.patch [new file with mode: 0644]
queue-4.9/xen-gntdev-use-vm_mixedmap-instead-of-vm_io-to-avoid-numa-balancing.patch [new file with mode: 0644]
queue-4.9/xfs-fix-up-xfs_swap_extent_forks-inline-extent-handling.patch [new file with mode: 0644]
queue-4.9/xfs-set-agi-buffer-type-in-xlog_recover_clear_agi_bucket.patch [new file with mode: 0644]

diff --git a/queue-4.9/arm-xen-use-alloc_percpu-rather-than-__alloc_percpu.patch b/queue-4.9/arm-xen-use-alloc_percpu-rather-than-__alloc_percpu.patch
new file mode 100644 (file)
index 0000000..0178345
--- /dev/null
@@ -0,0 +1,108 @@
+From 24d5373dda7c00a438d26016bce140299fae675e Mon Sep 17 00:00:00 2001
+From: Julien Grall <julien.grall@arm.com>
+Date: Wed, 7 Dec 2016 12:24:40 +0000
+Subject: arm/xen: Use alloc_percpu rather than __alloc_percpu
+
+From: Julien Grall <julien.grall@arm.com>
+
+commit 24d5373dda7c00a438d26016bce140299fae675e upstream.
+
+The function xen_guest_init is using __alloc_percpu with an alignment
+which are not power of two.
+
+However, the percpu allocator never supported alignments which are not power
+of two and has always behaved incorectly in thise case.
+
+Commit 3ca45a4 "percpu: ensure requested alignment is power of two"
+introduced a check which trigger a warning [1] when booting linux-next
+on Xen. But in reality this bug was always present.
+
+This can be fixed by replacing the call to __alloc_percpu with
+alloc_percpu. The latter will use an alignment which are a power of two.
+
+[1]
+
+[    0.023921] illegal size (48) or align (48) for percpu allocation
+[    0.024167] ------------[ cut here ]------------
+[    0.024344] WARNING: CPU: 0 PID: 1 at linux/mm/percpu.c:892 pcpu_alloc+0x88/0x6c0
+[    0.024584] Modules linked in:
+[    0.024708]
+[    0.024804] CPU: 0 PID: 1 Comm: swapper/0 Not tainted
+4.9.0-rc7-next-20161128 #473
+[    0.025012] Hardware name: Foundation-v8A (DT)
+[    0.025162] task: ffff80003d870000 task.stack: ffff80003d844000
+[    0.025351] PC is at pcpu_alloc+0x88/0x6c0
+[    0.025490] LR is at pcpu_alloc+0x88/0x6c0
+[    0.025624] pc : [<ffff00000818e678>] lr : [<ffff00000818e678>]
+pstate: 60000045
+[    0.025830] sp : ffff80003d847cd0
+[    0.025946] x29: ffff80003d847cd0 x28: 0000000000000000
+[    0.026147] x27: 0000000000000000 x26: 0000000000000000
+[    0.026348] x25: 0000000000000000 x24: 0000000000000000
+[    0.026549] x23: 0000000000000000 x22: 00000000024000c0
+[    0.026752] x21: ffff000008e97000 x20: 0000000000000000
+[    0.026953] x19: 0000000000000030 x18: 0000000000000010
+[    0.027155] x17: 0000000000000a3f x16: 00000000deadbeef
+[    0.027357] x15: 0000000000000006 x14: ffff000088f79c3f
+[    0.027573] x13: ffff000008f79c4d x12: 0000000000000041
+[    0.027782] x11: 0000000000000006 x10: 0000000000000042
+[    0.027995] x9 : ffff80003d847a40 x8 : 6f697461636f6c6c
+[    0.028208] x7 : 6120757063726570 x6 : ffff000008f79c84
+[    0.028419] x5 : 0000000000000005 x4 : 0000000000000000
+[    0.028628] x3 : 0000000000000000 x2 : 000000000000017f
+[    0.028840] x1 : ffff80003d870000 x0 : 0000000000000035
+[    0.029056]
+[    0.029152] ---[ end trace 0000000000000000 ]---
+[    0.029297] Call trace:
+[    0.029403] Exception stack(0xffff80003d847b00 to
+                               0xffff80003d847c30)
+[    0.029621] 7b00: 0000000000000030 0001000000000000
+ffff80003d847cd0 ffff00000818e678
+[    0.029901] 7b20: 0000000000000002 0000000000000004
+ffff000008f7c060 0000000000000035
+[    0.030153] 7b40: ffff000008f79000 ffff000008c4cd88
+ffff80003d847bf0 ffff000008101778
+[    0.030402] 7b60: 0000000000000030 0000000000000000
+ffff000008e97000 00000000024000c0
+[    0.030647] 7b80: 0000000000000000 0000000000000000
+0000000000000000 0000000000000000
+[    0.030895] 7ba0: 0000000000000035 ffff80003d870000
+000000000000017f 0000000000000000
+[    0.031144] 7bc0: 0000000000000000 0000000000000005
+ffff000008f79c84 6120757063726570
+[    0.031394] 7be0: 6f697461636f6c6c ffff80003d847a40
+0000000000000042 0000000000000006
+[    0.031643] 7c00: 0000000000000041 ffff000008f79c4d
+ffff000088f79c3f 0000000000000006
+[    0.031877] 7c20: 00000000deadbeef 0000000000000a3f
+[    0.032051] [<ffff00000818e678>] pcpu_alloc+0x88/0x6c0
+[    0.032229] [<ffff00000818ece8>] __alloc_percpu+0x18/0x20
+[    0.032409] [<ffff000008d9606c>] xen_guest_init+0x174/0x2f4
+[    0.032591] [<ffff0000080830f8>] do_one_initcall+0x38/0x130
+[    0.032783] [<ffff000008d90c34>] kernel_init_freeable+0xe0/0x248
+[    0.032995] [<ffff00000899a890>] kernel_init+0x10/0x100
+[    0.033172] [<ffff000008082ec0>] ret_from_fork+0x10/0x50
+
+Reported-by: Wei Chen <wei.chen@arm.com>
+Link: https://lkml.org/lkml/2016/11/28/669
+Signed-off-by: Julien Grall <julien.grall@arm.com>
+Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
+Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/xen/enlighten.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/arm/xen/enlighten.c
++++ b/arch/arm/xen/enlighten.c
+@@ -372,8 +372,7 @@ static int __init xen_guest_init(void)
+        * for secondary CPUs as they are brought up.
+        * For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
+        */
+-      xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info),
+-                                             sizeof(struct vcpu_info));
++      xen_vcpu_info = alloc_percpu(struct vcpu_info);
+       if (xen_vcpu_info == NULL)
+               return -ENOMEM;
diff --git a/queue-4.9/cifs-decrease-verbosity-of-ioctl-call.patch b/queue-4.9/cifs-decrease-verbosity-of-ioctl-call.patch
new file mode 100644 (file)
index 0000000..7641b82
--- /dev/null
@@ -0,0 +1,29 @@
+From b0a752b5ce76bd1d8b733a53757c3263511dcb69 Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Wed, 16 Nov 2016 15:17:15 -0800
+Subject: CIFS: Decrease verbosity of ioctl call
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+commit b0a752b5ce76bd1d8b733a53757c3263511dcb69 upstream.
+
+Reviewed-by: Aurelien Aptel <aaptel@suse.com>
+Acked-by: Sachin Prabhu <sprabhu@redhat.com>
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/ioctl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/ioctl.c
++++ b/fs/cifs/ioctl.c
+@@ -189,7 +189,7 @@ long cifs_ioctl(struct file *filep, unsi
+       xid = get_xid();
+       cifs_sb = CIFS_SB(inode->i_sb);
+-      cifs_dbg(VFS, "cifs ioctl 0x%x\n", command);
++      cifs_dbg(FYI, "cifs ioctl 0x%x\n", command);
+       switch (command) {
+               case FS_IOC_GETFLAGS:
+                       if (pSMBFile == NULL)
diff --git a/queue-4.9/cifs-fix-a-possible-double-locking-of-mutex-during-reconnect.patch b/queue-4.9/cifs-fix-a-possible-double-locking-of-mutex-during-reconnect.patch
new file mode 100644 (file)
index 0000000..521bca1
--- /dev/null
@@ -0,0 +1,126 @@
+From 96a988ffeb90dba33a71c3826086fe67c897a183 Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Tue, 29 Nov 2016 11:31:23 -0800
+Subject: CIFS: Fix a possible double locking of mutex during reconnect
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+commit 96a988ffeb90dba33a71c3826086fe67c897a183 upstream.
+
+With the current code it is possible to lock a mutex twice when
+a subsequent reconnects are triggered. On the 1st reconnect we
+reconnect sessions and tcons and then persistent file handles.
+If the 2nd reconnect happens during the reconnecting of persistent
+file handles then the following sequence of calls is observed:
+
+cifs_reopen_file -> SMB2_open -> small_smb2_init -> smb2_reconnect
+-> cifs_reopen_persistent_file_handles -> cifs_reopen_file (again!).
+
+So, we are trying to acquire the same cfile->fh_mutex twice which
+is wrong. Fix this by moving reconnecting of persistent handles to
+the delayed work (smb2_reconnect_server) and submitting this work
+every time we reconnect tcon in SMB2 commands handling codepath.
+
+This can also lead to corruption of a temporary file list in
+cifs_reopen_persistent_file_handles() because we can recursively
+call this function twice.
+
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsglob.h |    1 +
+ fs/cifs/file.c     |    8 +++++++-
+ fs/cifs/smb2pdu.c  |   14 +++++++++-----
+ fs/cifs/smb2pdu.h  |    2 ++
+ 4 files changed, 19 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -925,6 +925,7 @@ struct cifs_tcon {
+       bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
+       bool broken_sparse_sup; /* if server or share does not support sparse */
+       bool need_reconnect:1; /* connection reset, tid now invalid */
++      bool need_reopen_files:1; /* need to reopen tcon file handles */
+       bool use_resilient:1; /* use resilient instead of durable handles */
+       bool use_persistent:1; /* use persistent instead of durable handles */
+ #ifdef CONFIG_CIFS_SMB2
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -777,6 +777,11 @@ cifs_reopen_persistent_handles(struct ci
+       struct list_head *tmp1;
+       struct list_head tmp_list;
++      if (!tcon->use_persistent || !tcon->need_reopen_files)
++              return;
++
++      tcon->need_reopen_files = false;
++
+       cifs_dbg(FYI, "Reopen persistent handles");
+       INIT_LIST_HEAD(&tmp_list);
+@@ -793,7 +798,8 @@ cifs_reopen_persistent_handles(struct ci
+       list_for_each_safe(tmp, tmp1, &tmp_list) {
+               open_file = list_entry(tmp, struct cifsFileInfo, rlist);
+-              cifs_reopen_file(open_file, false /* do not flush */);
++              if (cifs_reopen_file(open_file, false /* do not flush */))
++                      tcon->need_reopen_files = true;
+               list_del_init(&open_file->rlist);
+               cifsFileInfo_put(open_file);
+       }
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -250,16 +250,19 @@ smb2_reconnect(__le16 smb2_command, stru
+       }
+       cifs_mark_open_files_invalid(tcon);
++      if (tcon->use_persistent)
++              tcon->need_reopen_files = true;
+       rc = SMB2_tcon(0, tcon->ses, tcon->treeName, tcon, nls_codepage);
+       mutex_unlock(&tcon->ses->session_mutex);
+-      if (tcon->use_persistent)
+-              cifs_reopen_persistent_handles(tcon);
+-
+       cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
+       if (rc)
+               goto out;
++
++      if (smb2_command != SMB2_INTERNAL_CMD)
++              queue_delayed_work(cifsiod_wq, &server->reconnect, 0);
++
+       atomic_inc(&tconInfoReconnectCount);
+ out:
+       /*
+@@ -1990,7 +1993,7 @@ void smb2_reconnect_server(struct work_s
+       spin_lock(&cifs_tcp_ses_lock);
+       list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+               list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+-                      if (tcon->need_reconnect) {
++                      if (tcon->need_reconnect || tcon->need_reopen_files) {
+                               tcon->tc_count++;
+                               list_add_tail(&tcon->rlist, &tmp_list);
+                               tcon_exist = true;
+@@ -2007,7 +2010,8 @@ void smb2_reconnect_server(struct work_s
+       spin_unlock(&cifs_tcp_ses_lock);
+       list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
+-              smb2_reconnect(SMB2_ECHO, tcon);
++              if (!smb2_reconnect(SMB2_INTERNAL_CMD, tcon))
++                      cifs_reopen_persistent_handles(tcon);
+               list_del_init(&tcon->rlist);
+               cifs_put_tcon(tcon);
+       }
+--- a/fs/cifs/smb2pdu.h
++++ b/fs/cifs/smb2pdu.h
+@@ -80,6 +80,8 @@
+ #define SMB2_SET_INFO         cpu_to_le16(SMB2_SET_INFO_HE)
+ #define SMB2_OPLOCK_BREAK     cpu_to_le16(SMB2_OPLOCK_BREAK_HE)
++#define SMB2_INTERNAL_CMD     cpu_to_le16(0xFFFF)
++
+ #define NUMBER_OF_SMB2_COMMANDS       0x0013
+ /* BB FIXME - analyze following length BB */
diff --git a/queue-4.9/cifs-fix-a-possible-memory-corruption-during-reconnect.patch b/queue-4.9/cifs-fix-a-possible-memory-corruption-during-reconnect.patch
new file mode 100644 (file)
index 0000000..94f2f71
--- /dev/null
@@ -0,0 +1,260 @@
+From 53e0e11efe9289535b060a51d4cf37c25e0d0f2b Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Fri, 4 Nov 2016 11:50:31 -0700
+Subject: CIFS: Fix a possible memory corruption during reconnect
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+commit 53e0e11efe9289535b060a51d4cf37c25e0d0f2b upstream.
+
+We can not unlock/lock cifs_tcp_ses_lock while walking through ses
+and tcon lists because it can corrupt list iterator pointers and
+a tcon structure can be released if we don't hold an extra reference.
+Fix it by moving a reconnect process to a separate delayed work
+and acquiring a reference to every tcon that needs to be reconnected.
+Also do not send an echo request on newly established connections.
+
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsglob.h  |    3 ++
+ fs/cifs/cifsproto.h |    3 ++
+ fs/cifs/connect.c   |   34 ++++++++++++++++++-----
+ fs/cifs/smb2pdu.c   |   75 +++++++++++++++++++++++++++++++++++-----------------
+ fs/cifs/smb2proto.h |    1 
+ 5 files changed, 85 insertions(+), 31 deletions(-)
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -646,6 +646,8 @@ struct TCP_Server_Info {
+       unsigned int    max_read;
+       unsigned int    max_write;
+       __u8            preauth_hash[512];
++      struct delayed_work reconnect; /* reconnect workqueue job */
++      struct mutex reconnect_mutex; /* prevent simultaneous reconnects */
+ #endif /* CONFIG_CIFS_SMB2 */
+       unsigned long echo_interval;
+ };
+@@ -849,6 +851,7 @@ cap_unix(struct cifs_ses *ses)
+ struct cifs_tcon {
+       struct list_head tcon_list;
+       int tc_count;
++      struct list_head rlist; /* reconnect list */
+       struct list_head openFileList;
+       spinlock_t open_file_lock; /* protects list above */
+       struct cifs_ses *ses;   /* pointer to session associated with */
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -206,6 +206,9 @@ extern void cifs_add_pending_open_locked
+                                        struct tcon_link *tlink,
+                                        struct cifs_pending_open *open);
+ extern void cifs_del_pending_open(struct cifs_pending_open *open);
++extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
++                               int from_reconnect);
++extern void cifs_put_tcon(struct cifs_tcon *tcon);
+ #if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL)
+ extern void cifs_dfs_release_automount_timer(void);
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -52,6 +52,9 @@
+ #include "nterr.h"
+ #include "rfc1002pdu.h"
+ #include "fscache.h"
++#ifdef CONFIG_CIFS_SMB2
++#include "smb2proto.h"
++#endif
+ #define CIFS_PORT 445
+ #define RFC1001_PORT 139
+@@ -2100,8 +2103,8 @@ cifs_find_tcp_session(struct smb_vol *vo
+       return NULL;
+ }
+-static void
+-cifs_put_tcp_session(struct TCP_Server_Info *server)
++void
++cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
+ {
+       struct task_struct *task;
+@@ -2118,6 +2121,19 @@ cifs_put_tcp_session(struct TCP_Server_I
+       cancel_delayed_work_sync(&server->echo);
++#ifdef CONFIG_CIFS_SMB2
++      if (from_reconnect)
++              /*
++               * Avoid deadlock here: reconnect work calls
++               * cifs_put_tcp_session() at its end. Need to be sure
++               * that reconnect work does nothing with server pointer after
++               * that step.
++               */
++              cancel_delayed_work(&server->reconnect);
++      else
++              cancel_delayed_work_sync(&server->reconnect);
++#endif
++
+       spin_lock(&GlobalMid_Lock);
+       server->tcpStatus = CifsExiting;
+       spin_unlock(&GlobalMid_Lock);
+@@ -2182,6 +2198,10 @@ cifs_get_tcp_session(struct smb_vol *vol
+       INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
+       INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
+       INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
++#ifdef CONFIG_CIFS_SMB2
++      INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
++      mutex_init(&tcp_ses->reconnect_mutex);
++#endif
+       memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
+              sizeof(tcp_ses->srcaddr));
+       memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
+@@ -2340,7 +2360,7 @@ cifs_put_smb_ses(struct cifs_ses *ses)
+       spin_unlock(&cifs_tcp_ses_lock);
+       sesInfoFree(ses);
+-      cifs_put_tcp_session(server);
++      cifs_put_tcp_session(server, 0);
+ }
+ #ifdef CONFIG_KEYS
+@@ -2514,7 +2534,7 @@ cifs_get_smb_ses(struct TCP_Server_Info
+               mutex_unlock(&ses->session_mutex);
+               /* existing SMB ses has a server reference already */
+-              cifs_put_tcp_session(server);
++              cifs_put_tcp_session(server, 0);
+               free_xid(xid);
+               return ses;
+       }
+@@ -2604,7 +2624,7 @@ cifs_find_tcon(struct cifs_ses *ses, con
+       return NULL;
+ }
+-static void
++void
+ cifs_put_tcon(struct cifs_tcon *tcon)
+ {
+       unsigned int xid;
+@@ -3792,7 +3812,7 @@ mount_fail_check:
+               else if (ses)
+                       cifs_put_smb_ses(ses);
+               else
+-                      cifs_put_tcp_session(server);
++                      cifs_put_tcp_session(server, 0);
+               bdi_destroy(&cifs_sb->bdi);
+       }
+@@ -4103,7 +4123,7 @@ cifs_construct_tcon(struct cifs_sb_info
+       ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
+       if (IS_ERR(ses)) {
+               tcon = (struct cifs_tcon *)ses;
+-              cifs_put_tcp_session(master_tcon->ses->server);
++              cifs_put_tcp_session(master_tcon->ses->server, 0);
+               goto out;
+       }
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1972,6 +1972,54 @@ smb2_echo_callback(struct mid_q_entry *m
+       add_credits(server, credits_received, CIFS_ECHO_OP);
+ }
++void smb2_reconnect_server(struct work_struct *work)
++{
++      struct TCP_Server_Info *server = container_of(work,
++                                      struct TCP_Server_Info, reconnect.work);
++      struct cifs_ses *ses;
++      struct cifs_tcon *tcon, *tcon2;
++      struct list_head tmp_list;
++      int tcon_exist = false;
++
++      /* Prevent simultaneous reconnects that can corrupt tcon->rlist list */
++      mutex_lock(&server->reconnect_mutex);
++
++      INIT_LIST_HEAD(&tmp_list);
++      cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
++
++      spin_lock(&cifs_tcp_ses_lock);
++      list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++              list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
++                      if (tcon->need_reconnect) {
++                              tcon->tc_count++;
++                              list_add_tail(&tcon->rlist, &tmp_list);
++                              tcon_exist = true;
++                      }
++              }
++      }
++      /*
++       * Get the reference to server struct to be sure that the last call of
++       * cifs_put_tcon() in the loop below won't release the server pointer.
++       */
++      if (tcon_exist)
++              server->srv_count++;
++
++      spin_unlock(&cifs_tcp_ses_lock);
++
++      list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
++              smb2_reconnect(SMB2_ECHO, tcon);
++              list_del_init(&tcon->rlist);
++              cifs_put_tcon(tcon);
++      }
++
++      cifs_dbg(FYI, "Reconnecting tcons finished\n");
++      mutex_unlock(&server->reconnect_mutex);
++
++      /* now we can safely release srv struct */
++      if (tcon_exist)
++              cifs_put_tcp_session(server, 1);
++}
++
+ int
+ SMB2_echo(struct TCP_Server_Info *server)
+ {
+@@ -1984,32 +2032,11 @@ SMB2_echo(struct TCP_Server_Info *server
+       cifs_dbg(FYI, "In echo request\n");
+       if (server->tcpStatus == CifsNeedNegotiate) {
+-              struct list_head *tmp, *tmp2;
+-              struct cifs_ses *ses;
+-              struct cifs_tcon *tcon;
+-
+-              cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
+-              spin_lock(&cifs_tcp_ses_lock);
+-              list_for_each(tmp, &server->smb_ses_list) {
+-                      ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+-                      list_for_each(tmp2, &ses->tcon_list) {
+-                              tcon = list_entry(tmp2, struct cifs_tcon,
+-                                                tcon_list);
+-                              /* add check for persistent handle reconnect */
+-                              if (tcon && tcon->need_reconnect) {
+-                                      spin_unlock(&cifs_tcp_ses_lock);
+-                                      rc = smb2_reconnect(SMB2_ECHO, tcon);
+-                                      spin_lock(&cifs_tcp_ses_lock);
+-                              }
+-                      }
+-              }
+-              spin_unlock(&cifs_tcp_ses_lock);
++              /* No need to send echo on newly established connections */
++              queue_delayed_work(cifsiod_wq, &server->reconnect, 0);
++              return rc;
+       }
+-      /* if no session, renegotiate failed above */
+-      if (server->tcpStatus == CifsNeedNegotiate)
+-              return -EIO;
+-
+       rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
+       if (rc)
+               return rc;
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -96,6 +96,7 @@ extern int smb2_open_file(const unsigned
+ extern int smb2_unlock_range(struct cifsFileInfo *cfile,
+                            struct file_lock *flock, const unsigned int xid);
+ extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
++extern void smb2_reconnect_server(struct work_struct *work);
+ /*
+  * SMB2 Worker functions - most of protocol specific implementation details
diff --git a/queue-4.9/cifs-fix-a-possible-memory-corruption-in-push-locks.patch b/queue-4.9/cifs-fix-a-possible-memory-corruption-in-push-locks.patch
new file mode 100644 (file)
index 0000000..aefc83c
--- /dev/null
@@ -0,0 +1,30 @@
+From e3d240e9d505fc67f8f8735836df97a794bbd946 Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Tue, 29 Nov 2016 16:14:43 -0800
+Subject: CIFS: Fix a possible memory corruption in push locks
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+commit e3d240e9d505fc67f8f8735836df97a794bbd946 upstream.
+
+If maxBuf is not 0 but less than a size of SMB2 lock structure
+we can end up with a memory corruption.
+
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2file.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/smb2file.c
++++ b/fs/cifs/smb2file.c
+@@ -260,7 +260,7 @@ smb2_push_mandatory_locks(struct cifsFil
+        * and check it for zero before using.
+        */
+       max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf;
+-      if (!max_buf) {
++      if (max_buf < sizeof(struct smb2_lock_element)) {
+               free_xid(xid);
+               return -EINVAL;
+       }
diff --git a/queue-4.9/cifs-fix-missing-nls-unload-in-smb2_reconnect.patch b/queue-4.9/cifs-fix-missing-nls-unload-in-smb2_reconnect.patch
new file mode 100644 (file)
index 0000000..bddcafa
--- /dev/null
@@ -0,0 +1,28 @@
+From 4772c79599564bd08ee6682715a7d3516f67433f Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Tue, 29 Nov 2016 11:30:58 -0800
+Subject: CIFS: Fix missing nls unload in smb2_reconnect()
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+commit 4772c79599564bd08ee6682715a7d3516f67433f upstream.
+
+Acked-by: Sachin Prabhu <sprabhu@redhat.com>
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2pdu.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -280,7 +280,7 @@ out:
+       case SMB2_CHANGE_NOTIFY:
+       case SMB2_QUERY_INFO:
+       case SMB2_SET_INFO:
+-              return -EAGAIN;
++              rc = -EAGAIN;
+       }
+       unload_nls(nls_codepage);
+       return rc;
diff --git a/queue-4.9/cifs-fix-smbencrypt-to-stop-pointing-a-scatterlist-at-the-stack.patch b/queue-4.9/cifs-fix-smbencrypt-to-stop-pointing-a-scatterlist-at-the-stack.patch
new file mode 100644 (file)
index 0000000..5c5a00f
--- /dev/null
@@ -0,0 +1,93 @@
+From 06deeec77a5a689cc94b21a8a91a76e42176685d Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Mon, 12 Dec 2016 12:54:37 -0800
+Subject: cifs: Fix smbencrypt() to stop pointing a scatterlist at the stack
+
+From: Andy Lutomirski <luto@kernel.org>
+
+commit 06deeec77a5a689cc94b21a8a91a76e42176685d upstream.
+
+smbencrypt() points a scatterlist to the stack, which is breaks if
+CONFIG_VMAP_STACK=y.
+
+Fix it by switching to crypto_cipher_encrypt_one().  The new code
+should be considerably faster as an added benefit.
+
+This code is nearly identical to some code that Eric Biggers
+suggested.
+
+Reported-by: Eric Biggers <ebiggers3@gmail.com>
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Acked-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smbencrypt.c |   40 ++++++++--------------------------------
+ 1 file changed, 8 insertions(+), 32 deletions(-)
+
+--- a/fs/cifs/smbencrypt.c
++++ b/fs/cifs/smbencrypt.c
+@@ -23,7 +23,7 @@
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+-#include <crypto/skcipher.h>
++#include <linux/crypto.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+@@ -69,46 +69,22 @@ str_to_key(unsigned char *str, unsigned
+ static int
+ smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
+ {
+-      int rc;
+       unsigned char key2[8];
+-      struct crypto_skcipher *tfm_des;
+-      struct scatterlist sgin, sgout;
+-      struct skcipher_request *req;
++      struct crypto_cipher *tfm_des;
+       str_to_key(key, key2);
+-      tfm_des = crypto_alloc_skcipher("ecb(des)", 0, CRYPTO_ALG_ASYNC);
++      tfm_des = crypto_alloc_cipher("des", 0, 0);
+       if (IS_ERR(tfm_des)) {
+-              rc = PTR_ERR(tfm_des);
+               cifs_dbg(VFS, "could not allocate des crypto API\n");
+-              goto smbhash_err;
++              return PTR_ERR(tfm_des);
+       }
+-      req = skcipher_request_alloc(tfm_des, GFP_KERNEL);
+-      if (!req) {
+-              rc = -ENOMEM;
+-              cifs_dbg(VFS, "could not allocate des crypto API\n");
+-              goto smbhash_free_skcipher;
+-      }
+-
+-      crypto_skcipher_setkey(tfm_des, key2, 8);
+-
+-      sg_init_one(&sgin, in, 8);
+-      sg_init_one(&sgout, out, 8);
+-
+-      skcipher_request_set_callback(req, 0, NULL, NULL);
+-      skcipher_request_set_crypt(req, &sgin, &sgout, 8, NULL);
+-
+-      rc = crypto_skcipher_encrypt(req);
+-      if (rc)
+-              cifs_dbg(VFS, "could not encrypt crypt key rc: %d\n", rc);
+-
+-      skcipher_request_free(req);
++      crypto_cipher_setkey(tfm_des, key2, 8);
++      crypto_cipher_encrypt_one(tfm_des, out, in);
++      crypto_free_cipher(tfm_des);
+-smbhash_free_skcipher:
+-      crypto_free_skcipher(tfm_des);
+-smbhash_err:
+-      return rc;
++      return 0;
+ }
+ static int
diff --git a/queue-4.9/kernel-debug-debug_core.c-more-properly-delay-for-secondary-cpus.patch b/queue-4.9/kernel-debug-debug_core.c-more-properly-delay-for-secondary-cpus.patch
new file mode 100644 (file)
index 0000000..06f7bba
--- /dev/null
@@ -0,0 +1,56 @@
+From 2d13bb6494c807bcf3f78af0e96c0b8615a94385 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Wed, 14 Dec 2016 15:05:49 -0800
+Subject: kernel/debug/debug_core.c: more properly delay for secondary CPUs
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit 2d13bb6494c807bcf3f78af0e96c0b8615a94385 upstream.
+
+We've got a delay loop waiting for secondary CPUs.  That loop uses
+loops_per_jiffy.  However, loops_per_jiffy doesn't actually mean how
+many tight loops make up a jiffy on all architectures.  It is quite
+common to see things like this in the boot log:
+
+  Calibrating delay loop (skipped), value calculated using timer
+  frequency.. 48.00 BogoMIPS (lpj=24000)
+
+In my case I was seeing lots of cases where other CPUs timed out
+entering the debugger only to print their stack crawls shortly after the
+kdb> prompt was written.
+
+Elsewhere in kgdb we already use udelay(), so that should be safe enough
+to use to implement our timeout.  We'll delay 1 ms for 1000 times, which
+should give us a full second of delay (just like the old code wanted)
+but allow us to notice that we're done every 1 ms.
+
+[akpm@linux-foundation.org: simplifications, per Daniel]
+Link: http://lkml.kernel.org/r/1477091361-2039-1-git-send-email-dianders@chromium.org
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Cc: Jason Wessel <jason.wessel@windriver.com>
+Cc: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/debug/debug_core.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/kernel/debug/debug_core.c
++++ b/kernel/debug/debug_core.c
+@@ -598,11 +598,11 @@ return_normal:
+       /*
+        * Wait for the other CPUs to be notified and be waiting for us:
+        */
+-      time_left = loops_per_jiffy * HZ;
++      time_left = MSEC_PER_SEC;
+       while (kgdb_do_roundup && --time_left &&
+              (atomic_read(&masters_in_kgdb) + atomic_read(&slaves_in_kgdb)) !=
+                  online_cpus)
+-              cpu_relax();
++              udelay(1000);
+       if (!time_left)
+               pr_crit("Timed out waiting for secondary CPUs.\n");
diff --git a/queue-4.9/kernel-watchdog-use-nmi-registers-snapshot-in-hardlockup-handler.patch b/queue-4.9/kernel-watchdog-use-nmi-registers-snapshot-in-hardlockup-handler.patch
new file mode 100644 (file)
index 0000000..4f01564
--- /dev/null
@@ -0,0 +1,44 @@
+From 4d1f0fb096aedea7bb5489af93498a82e467c480 Mon Sep 17 00:00:00 2001
+From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Date: Wed, 14 Dec 2016 15:04:04 -0800
+Subject: kernel/watchdog: use nmi registers snapshot in hardlockup handler
+
+From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+
+commit 4d1f0fb096aedea7bb5489af93498a82e467c480 upstream.
+
+NMI handler doesn't call set_irq_regs(), it's set only by normal IRQ.
+Thus get_irq_regs() returns NULL or stale registers snapshot with IP/SP
+pointing to the code interrupted by IRQ which was interrupted by NMI.
+NULL isn't a problem: in this case watchdog calls dump_stack() and
+prints full stack trace including NMI.  But if we're stuck in IRQ
+handler then NMI watchlog will print stack trace without IRQ part at
+all.
+
+This patch uses registers snapshot passed into NMI handler as arguments:
+these registers point exactly to the instruction interrupted by NMI.
+
+Fixes: 55537871ef66 ("kernel/watchdog.c: perform all-CPU backtrace in case of hard lockup")
+Link: http://lkml.kernel.org/r/146771764784.86724.6006627197118544150.stgit@buzz
+Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Cc: Jiri Kosina <jkosina@suse.cz>
+Cc: Ulrich Obergfell <uobergfe@redhat.com>
+Cc: Aaron Tomlin <atomlin@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/watchdog.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -344,7 +344,6 @@ static void watchdog_overflow_callback(s
+        */
+       if (is_hardlockup()) {
+               int this_cpu = smp_processor_id();
+-              struct pt_regs *regs = get_irq_regs();
+               /* only print hardlockups once */
+               if (__this_cpu_read(hard_watchdog_warn) == true)
index ed427ccc2c0cc19162de31c11a742e519c9f827f..9372f6e9fb512f28ec34d683c6ed069ed843e000 100644 (file)
@@ -64,3 +64,18 @@ dm-rq-fix-a-race-condition-in-rq_completed.patch
 dm-raid-fix-discard-support-regression.patch
 dm-space-map-metadata-fix-struct-sm_metadata-leak-on-failed-create.patch
 asoc-intel-fix-crash-at-suspend-resume-without-card-registration.patch
+cifs-fix-smbencrypt-to-stop-pointing-a-scatterlist-at-the-stack.patch
+cifs-fix-a-possible-memory-corruption-during-reconnect.patch
+cifs-fix-missing-nls-unload-in-smb2_reconnect.patch
+cifs-fix-a-possible-double-locking-of-mutex-during-reconnect.patch
+cifs-decrease-verbosity-of-ioctl-call.patch
+cifs-fix-a-possible-memory-corruption-in-push-locks.patch
+kernel-watchdog-use-nmi-registers-snapshot-in-hardlockup-handler.patch
+watchdog-mei_wdt-request-stop-on-reboot-to-prevent-false-positive-event.patch
+watchdog-qcom-fix-kernel-panic-due-to-external-abort-on-non-linefetch.patch
+kernel-debug-debug_core.c-more-properly-delay-for-secondary-cpus.patch
+tpm-xen-remove-bogus-tpm_chip_unregister.patch
+xen-gntdev-use-vm_mixedmap-instead-of-vm_io-to-avoid-numa-balancing.patch
+arm-xen-use-alloc_percpu-rather-than-__alloc_percpu.patch
+xfs-fix-up-xfs_swap_extent_forks-inline-extent-handling.patch
+xfs-set-agi-buffer-type-in-xlog_recover_clear_agi_bucket.patch
diff --git a/queue-4.9/tpm-xen-remove-bogus-tpm_chip_unregister.patch b/queue-4.9/tpm-xen-remove-bogus-tpm_chip_unregister.patch
new file mode 100644 (file)
index 0000000..4c5ef4d
--- /dev/null
@@ -0,0 +1,31 @@
+From 1f0f30e404b3d8f4597a2d9b77fba55452f8fd0e Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Wed, 26 Oct 2016 16:28:45 -0600
+Subject: tpm xen: Remove bogus tpm_chip_unregister
+
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+
+commit 1f0f30e404b3d8f4597a2d9b77fba55452f8fd0e upstream.
+
+tpm_chip_unregister can only be called after tpm_chip_register.
+devm manages the allocation so no unwind is needed here.
+
+Fixes: afb5abc262e96 ("tpm: two-phase chip management functions")
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/xen-tpmfront.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/char/tpm/xen-tpmfront.c
++++ b/drivers/char/tpm/xen-tpmfront.c
+@@ -307,7 +307,6 @@ static int tpmfront_probe(struct xenbus_
+       rv = setup_ring(dev, priv);
+       if (rv) {
+               chip = dev_get_drvdata(&dev->dev);
+-              tpm_chip_unregister(chip);
+               ring_free(priv);
+               return rv;
+       }
diff --git a/queue-4.9/watchdog-mei_wdt-request-stop-on-reboot-to-prevent-false-positive-event.patch b/queue-4.9/watchdog-mei_wdt-request-stop-on-reboot-to-prevent-false-positive-event.patch
new file mode 100644 (file)
index 0000000..5edb54c
--- /dev/null
@@ -0,0 +1,39 @@
+From 9eff1140a82db8c5520f76e51c21827b4af670b3 Mon Sep 17 00:00:00 2001
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+Date: Tue, 8 Nov 2016 17:55:52 +0200
+Subject: watchdog: mei_wdt: request stop on reboot to prevent false positive event
+
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+
+commit 9eff1140a82db8c5520f76e51c21827b4af670b3 upstream.
+
+Systemd on reboot enables shutdown watchdog that leaves the watchdog
+device open to ensure that even if power down process get stuck the
+platform reboots nonetheless.
+The iamt_wdt is an alarm-only watchdog and can't reboot system, but the
+FW will generate an alarm event reboot was completed in time, as the
+watchdog is not automatically disabled during power cycle.
+So we should request stop watchdog on reboot to eliminate wrong alarm
+from the FW.
+
+Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
+Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/watchdog/mei_wdt.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/watchdog/mei_wdt.c
++++ b/drivers/watchdog/mei_wdt.c
+@@ -389,6 +389,8 @@ static int mei_wdt_register(struct mei_w
+       wdt->wdd.max_timeout = MEI_WDT_MAX_TIMEOUT;
+       watchdog_set_drvdata(&wdt->wdd, wdt);
++      watchdog_stop_on_reboot(&wdt->wdd);
++
+       ret = watchdog_register_device(&wdt->wdd);
+       if (ret) {
+               dev_err(dev, "unable to register watchdog device = %d.\n", ret);
diff --git a/queue-4.9/watchdog-qcom-fix-kernel-panic-due-to-external-abort-on-non-linefetch.patch b/queue-4.9/watchdog-qcom-fix-kernel-panic-due-to-external-abort-on-non-linefetch.patch
new file mode 100644 (file)
index 0000000..597c85a
--- /dev/null
@@ -0,0 +1,55 @@
+From f06f35c66fdbd5ac38901a3305ce763a0cd59375 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@googlemail.com>
+Date: Mon, 14 Nov 2016 02:11:16 +0100
+Subject: watchdog: qcom: fix kernel panic due to external abort on non-linefetch
+
+From: Christian Lamparter <chunkeey@googlemail.com>
+
+commit f06f35c66fdbd5ac38901a3305ce763a0cd59375 upstream.
+
+This patch fixes a off-by-one in the "watchdog: qcom: add option for
+standalone watchdog not in timer block" patch that causes the
+following panic on boot:
+
+> Unhandled fault: external abort on non-linefetch (0x1008) at 0xc8874002
+> pgd = c0204000
+> [c8874002] *pgd=87806811, *pte=0b017653, *ppte=0b017453
+> Internal error: : 1008 [#1] SMP ARM
+> CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.8.6 #0
+> Hardware name: Generic DT based system
+> PC is at 0xc02222f4
+> LR is at 0x1
+> pc : [<c02222f4>]    lr : [<00000001>]    psr: 00000113
+> sp : c782fc98  ip : 00000003  fp : 00000000
+> r10: 00000004  r9 : c782e000  r8 : c04ab98c
+> r7 : 00000001  r6 : c8874002  r5 : c782fe00  r4 : 00000002
+> r3 : 00000000  r2 : c782fe00  r1 : 00100000  r0 : c8874002
+> Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
+> Control: 10c5387d  Table: 8020406a  DAC: 00000051
+> Process swapper/0 (pid: 1, stack limit = 0xc782e210)
+> Stack: (0xc782fc98 to 0xc7830000)
+> [...]
+
+The WDT_STS (status) needs to be translated via wdt_addr as well.
+
+fixes: f0d9d0f4b44a ("watchdog: qcom: add option for standalone watchdog not in timer block")
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/watchdog/qcom-wdt.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/watchdog/qcom-wdt.c
++++ b/drivers/watchdog/qcom-wdt.c
+@@ -209,7 +209,7 @@ static int qcom_wdt_probe(struct platfor
+       wdt->wdd.parent = &pdev->dev;
+       wdt->layout = regs;
+-      if (readl(wdt->base + WDT_STS) & 1)
++      if (readl(wdt_addr(wdt, WDT_STS)) & 1)
+               wdt->wdd.bootstatus = WDIOF_CARDRESET;
+       /*
diff --git a/queue-4.9/xen-gntdev-use-vm_mixedmap-instead-of-vm_io-to-avoid-numa-balancing.patch b/queue-4.9/xen-gntdev-use-vm_mixedmap-instead-of-vm_io-to-avoid-numa-balancing.patch
new file mode 100644 (file)
index 0000000..115eb91
--- /dev/null
@@ -0,0 +1,60 @@
+From 30faaafdfa0c754c91bac60f216c9f34a2bfdf7e Mon Sep 17 00:00:00 2001
+From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Date: Mon, 21 Nov 2016 09:56:06 -0500
+Subject: xen/gntdev: Use VM_MIXEDMAP instead of VM_IO to avoid NUMA balancing
+
+From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+
+commit 30faaafdfa0c754c91bac60f216c9f34a2bfdf7e upstream.
+
+Commit 9c17d96500f7 ("xen/gntdev: Grant maps should not be subject to
+NUMA balancing") set VM_IO flag to prevent grant maps from being
+subjected to NUMA balancing.
+
+It was discovered recently that this flag causes get_user_pages() to
+always fail with -EFAULT.
+
+check_vma_flags
+__get_user_pages
+__get_user_pages_locked
+__get_user_pages_unlocked
+get_user_pages_fast
+iov_iter_get_pages
+dio_refill_pages
+do_direct_IO
+do_blockdev_direct_IO
+do_blockdev_direct_IO
+ext4_direct_IO_read
+generic_file_read_iter
+aio_run_iocb
+
+(which can happen if guest's vdisk has direct-io-safe option).
+
+To avoid this let's use VM_MIXEDMAP flag instead --- it prevents
+NUMA balancing just as VM_IO does and has no effect on
+check_vma_flags().
+
+
+Reported-by: Olaf Hering <olaf@aepfle.de>
+Suggested-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Acked-by: Hugh Dickins <hughd@google.com>
+Tested-by: Olaf Hering <olaf@aepfle.de>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/xen/gntdev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/xen/gntdev.c
++++ b/drivers/xen/gntdev.c
+@@ -1007,7 +1007,7 @@ static int gntdev_mmap(struct file *flip
+       vma->vm_ops = &gntdev_vmops;
+-      vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
++      vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_MIXEDMAP;
+       if (use_ptemod)
+               vma->vm_flags |= VM_DONTCOPY;
diff --git a/queue-4.9/xfs-fix-up-xfs_swap_extent_forks-inline-extent-handling.patch b/queue-4.9/xfs-fix-up-xfs_swap_extent_forks-inline-extent-handling.patch
new file mode 100644 (file)
index 0000000..1881de4
--- /dev/null
@@ -0,0 +1,94 @@
+From 4dfce57db6354603641132fac3c887614e3ebe81 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@sandeen.net>
+Date: Tue, 8 Nov 2016 12:55:18 +1100
+Subject: xfs: fix up xfs_swap_extent_forks inline extent handling
+
+From: Eric Sandeen <sandeen@sandeen.net>
+
+commit 4dfce57db6354603641132fac3c887614e3ebe81 upstream.
+
+There have been several reports over the years of NULL pointer
+dereferences in xfs_trans_log_inode during xfs_fsr processes,
+when the process is doing an fput and tearing down extents
+on the temporary inode, something like:
+
+BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
+PID: 29439  TASK: ffff880550584fa0  CPU: 6   COMMAND: "xfs_fsr"
+    [exception RIP: xfs_trans_log_inode+0x10]
+ #9 [ffff8800a57bbbe0] xfs_bunmapi at ffffffffa037398e [xfs]
+#10 [ffff8800a57bbce8] xfs_itruncate_extents at ffffffffa0391b29 [xfs]
+#11 [ffff8800a57bbd88] xfs_inactive_truncate at ffffffffa0391d0c [xfs]
+#12 [ffff8800a57bbdb8] xfs_inactive at ffffffffa0392508 [xfs]
+#13 [ffff8800a57bbdd8] xfs_fs_evict_inode at ffffffffa035907e [xfs]
+#14 [ffff8800a57bbe00] evict at ffffffff811e1b67
+#15 [ffff8800a57bbe28] iput at ffffffff811e23a5
+#16 [ffff8800a57bbe58] dentry_kill at ffffffff811dcfc8
+#17 [ffff8800a57bbe88] dput at ffffffff811dd06c
+#18 [ffff8800a57bbea8] __fput at ffffffff811c823b
+#19 [ffff8800a57bbef0] ____fput at ffffffff811c846e
+#20 [ffff8800a57bbf00] task_work_run at ffffffff81093b27
+#21 [ffff8800a57bbf30] do_notify_resume at ffffffff81013b0c
+#22 [ffff8800a57bbf50] int_signal at ffffffff8161405d
+
+As it turns out, this is because the i_itemp pointer, along
+with the d_ops pointer, has been overwritten with zeros
+when we tear down the extents during truncate.  When the in-core
+inode fork on the temporary inode used by xfs_fsr was originally
+set up during the extent swap, we mistakenly looked at di_nextents
+to determine whether all extents fit inline, but this misses extents
+generated by speculative preallocation; we should be using if_bytes
+instead.
+
+This mistake corrupts the in-memory inode, and code in
+xfs_iext_remove_inline eventually gets bad inputs, causing
+it to memmove and memset incorrect ranges; this became apparent
+because the two values in ifp->if_u2.if_inline_ext[1] contained
+what should have been in d_ops and i_itemp; they were memmoved due
+to incorrect array indexing and then the original locations
+were zeroed with memset, again due to an array overrun.
+
+Fix this by properly using i_df.if_bytes to determine the number
+of extents, not di_nextents.
+
+Thanks to dchinner for looking at this with me and spotting the
+root cause.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Signed-off-by: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_bmap_util.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/xfs_bmap_util.c
++++ b/fs/xfs/xfs_bmap_util.c
+@@ -1792,6 +1792,7 @@ xfs_swap_extent_forks(
+       struct xfs_ifork        tempifp, *ifp, *tifp;
+       int                     aforkblks = 0;
+       int                     taforkblks = 0;
++      xfs_extnum_t            nextents;
+       __uint64_t              tmp;
+       int                     error;
+@@ -1881,7 +1882,8 @@ xfs_swap_extent_forks(
+                * pointer.  Otherwise it's already NULL or
+                * pointing to the extent.
+                */
+-              if (ip->i_d.di_nextents <= XFS_INLINE_EXTS) {
++              nextents = ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
++              if (nextents <= XFS_INLINE_EXTS) {
+                       ifp->if_u1.if_extents =
+                               ifp->if_u2.if_inline_ext;
+               }
+@@ -1900,7 +1902,8 @@ xfs_swap_extent_forks(
+                * pointer.  Otherwise it's already NULL or
+                * pointing to the extent.
+                */
+-              if (tip->i_d.di_nextents <= XFS_INLINE_EXTS) {
++              nextents = tip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
++              if (nextents <= XFS_INLINE_EXTS) {
+                       tifp->if_u1.if_extents =
+                               tifp->if_u2.if_inline_ext;
+               }
diff --git a/queue-4.9/xfs-set-agi-buffer-type-in-xlog_recover_clear_agi_bucket.patch b/queue-4.9/xfs-set-agi-buffer-type-in-xlog_recover_clear_agi_bucket.patch
new file mode 100644 (file)
index 0000000..584a123
--- /dev/null
@@ -0,0 +1,39 @@
+From 6b10b23ca94451fae153a5cc8d62fd721bec2019 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@sandeen.net>
+Date: Mon, 5 Dec 2016 12:31:06 +1100
+Subject: xfs: set AGI buffer type in xlog_recover_clear_agi_bucket
+
+From: Eric Sandeen <sandeen@sandeen.net>
+
+commit 6b10b23ca94451fae153a5cc8d62fd721bec2019 upstream.
+
+xlog_recover_clear_agi_bucket didn't set the
+type to XFS_BLFT_AGI_BUF, so we got a warning during log
+replay (or an ASSERT on a debug build).
+
+    XFS (md0): Unknown buffer type 0!
+    XFS (md0): _xfs_buf_ioapply: no ops on block 0xaea8802/0x1
+
+Fix this, as was done in f19b872b for 2 other locations
+with the same problem.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_log_recover.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -4929,6 +4929,7 @@ xlog_recover_clear_agi_bucket(
+       agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
+       offset = offsetof(xfs_agi_t, agi_unlinked) +
+                (sizeof(xfs_agino_t) * bucket);
++      xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF);
+       xfs_trans_log_buf(tp, agibp, offset,
+                         (offset + sizeof(xfs_agino_t) - 1));