]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Feb 2018 14:37:43 +0000 (15:37 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Feb 2018 14:37:43 +0000 (15:37 +0100)
added patches:
acpi-nfit-fix-register-dimm-error-handling.patch
acpi-sbshc-remove-raw-pointer-from-printk-message.patch
arm64-dts-marvell-add-ethernet-aliases.patch
devpts-fix-error-handling-in-devpts_mntget.patch
drm-i915-avoid-pps-hw-sw-state-mismatch-due-to-rounding.patch
ftrace-remove-incorrect-setting-of-glob-search-field.patch
mn10300-misalignment-use-sigsegv-segv_maperr-to-report-a-failed-user-copy.patch
objtool-fix-switch-table-detection.patch
ovl-fix-failure-to-fsync-lower-dir.patch
ovl-force-r-o-mount-when-index-dir-creation-fails.patch
ovl-hash-directory-inodes-for-fsnotify.patch
ovl-take-mnt_want_write-for-removing-impure-xattr.patch
ovl-take-mnt_want_write-for-work-index-dir-setup.patch
scsi-core-ensure-that-the-scsi-error-handler-gets-woken-up.patch
scsi-cxlflash-reset-command-ioasc.patch
scsi-lpfc-fix-crash-after-bad-bar-setup-on-driver-attachment.patch

17 files changed:
queue-4.15/acpi-nfit-fix-register-dimm-error-handling.patch [new file with mode: 0644]
queue-4.15/acpi-sbshc-remove-raw-pointer-from-printk-message.patch [new file with mode: 0644]
queue-4.15/arm64-dts-marvell-add-ethernet-aliases.patch [new file with mode: 0644]
queue-4.15/devpts-fix-error-handling-in-devpts_mntget.patch [new file with mode: 0644]
queue-4.15/drm-i915-avoid-pps-hw-sw-state-mismatch-due-to-rounding.patch [new file with mode: 0644]
queue-4.15/ftrace-remove-incorrect-setting-of-glob-search-field.patch [new file with mode: 0644]
queue-4.15/mn10300-misalignment-use-sigsegv-segv_maperr-to-report-a-failed-user-copy.patch [new file with mode: 0644]
queue-4.15/objtool-fix-switch-table-detection.patch [new file with mode: 0644]
queue-4.15/ovl-fix-failure-to-fsync-lower-dir.patch [new file with mode: 0644]
queue-4.15/ovl-force-r-o-mount-when-index-dir-creation-fails.patch [new file with mode: 0644]
queue-4.15/ovl-hash-directory-inodes-for-fsnotify.patch [new file with mode: 0644]
queue-4.15/ovl-take-mnt_want_write-for-removing-impure-xattr.patch [new file with mode: 0644]
queue-4.15/ovl-take-mnt_want_write-for-work-index-dir-setup.patch [new file with mode: 0644]
queue-4.15/scsi-core-ensure-that-the-scsi-error-handler-gets-woken-up.patch [new file with mode: 0644]
queue-4.15/scsi-cxlflash-reset-command-ioasc.patch [new file with mode: 0644]
queue-4.15/scsi-lpfc-fix-crash-after-bad-bar-setup-on-driver-attachment.patch [new file with mode: 0644]
queue-4.15/series

diff --git a/queue-4.15/acpi-nfit-fix-register-dimm-error-handling.patch b/queue-4.15/acpi-nfit-fix-register-dimm-error-handling.patch
new file mode 100644 (file)
index 0000000..f23faf6
--- /dev/null
@@ -0,0 +1,37 @@
+From 23fbd7c70aec7600e3227eb24259fc55bf6e4881 Mon Sep 17 00:00:00 2001
+From: Toshi Kani <toshi.kani@hpe.com>
+Date: Fri, 2 Feb 2018 14:00:36 -0700
+Subject: acpi, nfit: fix register dimm error handling
+
+From: Toshi Kani <toshi.kani@hpe.com>
+
+commit 23fbd7c70aec7600e3227eb24259fc55bf6e4881 upstream.
+
+A NULL pointer reference kernel bug was observed when
+acpi_nfit_add_dimm() called in acpi_nfit_register_dimms() failed. This
+error path does not set nfit_mem->nvdimm, but the 2nd
+list_for_each_entry() loop in the function assumes it's always set. Add
+a check to nfit_mem->nvdimm.
+
+Fixes: ba9c8dd3c222 ("acpi, nfit: add dimm device notification support")
+Signed-off-by: Toshi Kani <toshi.kani@hpe.com>
+Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/nfit/core.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -1867,6 +1867,9 @@ static int acpi_nfit_register_dimms(stru
+               struct kernfs_node *nfit_kernfs;
+               nvdimm = nfit_mem->nvdimm;
++              if (!nvdimm)
++                      continue;
++
+               nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit");
+               if (nfit_kernfs)
+                       nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs,
diff --git a/queue-4.15/acpi-sbshc-remove-raw-pointer-from-printk-message.patch b/queue-4.15/acpi-sbshc-remove-raw-pointer-from-printk-message.patch
new file mode 100644 (file)
index 0000000..1f31c49
--- /dev/null
@@ -0,0 +1,35 @@
+From 43cdd1b716b26f6af16da4e145b6578f98798bf6 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Fri, 19 Jan 2018 10:06:03 +0100
+Subject: ACPI: sbshc: remove raw pointer from printk() message
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+commit 43cdd1b716b26f6af16da4e145b6578f98798bf6 upstream.
+
+There's no need to be printing a raw kernel pointer to the kernel log at
+every boot.  So just remove it, and change the whole message to use the
+correct dev_info() call at the same time.
+
+Reported-by: Wang Qize <wang_qize@venustech.com.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/sbshc.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/acpi/sbshc.c
++++ b/drivers/acpi/sbshc.c
+@@ -275,8 +275,8 @@ static int acpi_smbus_hc_add(struct acpi
+       device->driver_data = hc;
+       acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
+-      printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
+-              hc->ec, hc->offset, hc->query_bit);
++      dev_info(&device->dev, "SBS HC: offset = 0x%0x, query_bit = 0x%0x\n",
++               hc->offset, hc->query_bit);
+       return 0;
+ }
diff --git a/queue-4.15/arm64-dts-marvell-add-ethernet-aliases.patch b/queue-4.15/arm64-dts-marvell-add-ethernet-aliases.patch
new file mode 100644 (file)
index 0000000..bfc3142
--- /dev/null
@@ -0,0 +1,72 @@
+From 474c5885582c4a79c21bcf01ed98f98c935f1f4a Mon Sep 17 00:00:00 2001
+From: Yan Markman <ymarkman@marvell.com>
+Date: Wed, 3 Jan 2018 16:18:52 +0100
+Subject: arm64: dts: marvell: add Ethernet aliases
+
+From: Yan Markman <ymarkman@marvell.com>
+
+commit 474c5885582c4a79c21bcf01ed98f98c935f1f4a upstream.
+
+This patch adds Ethernet aliases in the Marvell Armada 7040 DB, 8040 DB
+and 8040 mcbin device trees so that the bootloader setup the MAC
+addresses correctly.
+
+Signed-off-by: Yan Markman <ymarkman@marvell.com>
+[Antoine: commit message, small fixes]
+Signed-off-by: Antoine Tenart <antoine.tenart@free-electrons.com>
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ arch/arm64/boot/dts/marvell/armada-7040-db.dts    |    6 ++++++
+ arch/arm64/boot/dts/marvell/armada-8040-db.dts    |    7 +++++++
+ arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts |    6 ++++++
+ 3 files changed, 19 insertions(+)
+
+--- a/arch/arm64/boot/dts/marvell/armada-7040-db.dts
++++ b/arch/arm64/boot/dts/marvell/armada-7040-db.dts
+@@ -61,6 +61,12 @@
+               reg = <0x0 0x0 0x0 0x80000000>;
+       };
++      aliases {
++              ethernet0 = &cpm_eth0;
++              ethernet1 = &cpm_eth1;
++              ethernet2 = &cpm_eth2;
++      };
++
+       cpm_reg_usb3_0_vbus: cpm-usb3-0-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb3h0-vbus";
+--- a/arch/arm64/boot/dts/marvell/armada-8040-db.dts
++++ b/arch/arm64/boot/dts/marvell/armada-8040-db.dts
+@@ -61,6 +61,13 @@
+               reg = <0x0 0x0 0x0 0x80000000>;
+       };
++      aliases {
++              ethernet0 = &cpm_eth0;
++              ethernet1 = &cpm_eth2;
++              ethernet2 = &cps_eth0;
++              ethernet3 = &cps_eth1;
++      };
++
+       cpm_reg_usb3_0_vbus: cpm-usb3-0-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "cpm-usb3h0-vbus";
+--- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
++++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
+@@ -62,6 +62,12 @@
+               reg = <0x0 0x0 0x0 0x80000000>;
+       };
++      aliases {
++              ethernet0 = &cpm_eth0;
++              ethernet1 = &cps_eth0;
++              ethernet2 = &cps_eth1;
++      };
++
+       /* Regulator labels correspond with schematics */
+       v_3_3: regulator-3-3v {
+               compatible = "regulator-fixed";
diff --git a/queue-4.15/devpts-fix-error-handling-in-devpts_mntget.patch b/queue-4.15/devpts-fix-error-handling-in-devpts_mntget.patch
new file mode 100644 (file)
index 0000000..5cf9534
--- /dev/null
@@ -0,0 +1,60 @@
+From c9cc8d01fb04117928830449388512a5047569c9 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 31 Jan 2018 00:49:18 -0800
+Subject: devpts: fix error handling in devpts_mntget()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit c9cc8d01fb04117928830449388512a5047569c9 upstream.
+
+If devpts_ptmx_path() returns an error code, then devpts_mntget()
+dereferences an ERR_PTR():
+
+    BUG: unable to handle kernel paging request at fffffffffffffff5
+    IP: devpts_mntget+0x13f/0x280 fs/devpts/inode.c:173
+
+Fix it by returning early in the error paths.
+
+Reproducer:
+
+    #define _GNU_SOURCE
+    #include <fcntl.h>
+    #include <sched.h>
+    #include <sys/ioctl.h>
+    #define TIOCGPTPEER _IO('T', 0x41)
+
+    int main()
+    {
+        for (;;) {
+            int fd = open("/dev/ptmx", 0);
+            unshare(CLONE_NEWNS);
+            ioctl(fd, TIOCGPTPEER, 0);
+        }
+    }
+
+Fixes: 311fc65c9fb9 ("pty: Repair TIOCGPTPEER")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/devpts/inode.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/devpts/inode.c
++++ b/fs/devpts/inode.c
+@@ -168,11 +168,11 @@ struct vfsmount *devpts_mntget(struct fi
+       dput(path.dentry);
+       if (err) {
+               mntput(path.mnt);
+-              path.mnt = ERR_PTR(err);
++              return ERR_PTR(err);
+       }
+       if (DEVPTS_SB(path.mnt->mnt_sb) != fsi) {
+               mntput(path.mnt);
+-              path.mnt = ERR_PTR(-ENODEV);
++              return ERR_PTR(-ENODEV);
+       }
+       return path.mnt;
+ }
diff --git a/queue-4.15/drm-i915-avoid-pps-hw-sw-state-mismatch-due-to-rounding.patch b/queue-4.15/drm-i915-avoid-pps-hw-sw-state-mismatch-due-to-rounding.patch
new file mode 100644 (file)
index 0000000..10206ce
--- /dev/null
@@ -0,0 +1,48 @@
+From 5643205c6340b565a3be0fe0e7305dc4aa551c74 Mon Sep 17 00:00:00 2001
+From: Imre Deak <imre.deak@intel.com>
+Date: Wed, 29 Nov 2017 19:51:37 +0200
+Subject: drm/i915: Avoid PPS HW/SW state mismatch due to rounding
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Imre Deak <imre.deak@intel.com>
+
+commit 5643205c6340b565a3be0fe0e7305dc4aa551c74 upstream.
+
+We store a SW state of the t11_t12 timing in 100usec units but have to
+program it in 100msec as required by HW. The rounding used during
+programming means there will be a mismatch between the SW and HW states
+of this value triggering a "PPS state mismatch" error. Avoid this by
+storing the already rounded-up value in the SW state.
+
+Note that we still calculate panel_power_cycle_delay with the finer
+100usec granularity to avoid any needless waits using that version of
+the delay.
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103903
+Cc: joks <joks@linux.pl>
+Signed-off-by: Imre Deak <imre.deak@intel.com>
+Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20171129175137.2889-1-imre.deak@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_dp.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -5336,6 +5336,12 @@ intel_dp_init_panel_power_sequencer(stru
+        */
+       final->t8 = 1;
+       final->t9 = 1;
++
++      /*
++       * HW has only a 100msec granularity for t11_t12 so round it up
++       * accordingly.
++       */
++      final->t11_t12 = roundup(final->t11_t12, 100 * 10);
+ }
+ static void
diff --git a/queue-4.15/ftrace-remove-incorrect-setting-of-glob-search-field.patch b/queue-4.15/ftrace-remove-incorrect-setting-of-glob-search-field.patch
new file mode 100644 (file)
index 0000000..8be4430
--- /dev/null
@@ -0,0 +1,52 @@
+From 7b6586562708d2b3a04fe49f217ddbadbbbb0546 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Mon, 5 Feb 2018 22:05:31 -0500
+Subject: ftrace: Remove incorrect setting of glob search field
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit 7b6586562708d2b3a04fe49f217ddbadbbbb0546 upstream.
+
+__unregister_ftrace_function_probe() will incorrectly parse the glob filter
+because it resets the search variable that was setup by filter_parse_regex().
+
+Al Viro reported this:
+
+    After that call of filter_parse_regex() we could have func_g.search not
+    equal to glob only if glob started with '!' or '*'.  In the former case
+    we would've buggered off with -EINVAL (not = 1).  In the latter we
+    would've set func_g.search equal to glob + 1, calculated the length of
+    that thing in func_g.len and proceeded to reset func_g.search back to
+    glob.
+
+    Suppose the glob is e.g. *foo*.  We end up with
+           func_g.type = MATCH_MIDDLE_ONLY;
+           func_g.len = 3;
+           func_g.search = "*foo";
+    Feeding that to ftrace_match_record() will not do anything sane - we
+    will be looking for names containing "*foo" (->len is ignored for that
+    one).
+
+Link: http://lkml.kernel.org/r/20180127031706.GE13338@ZenIV.linux.org.uk
+
+Fixes: 3ba009297149f ("ftrace: Introduce ftrace_glob structure")
+Reviewed-by: Dmitry Safonov <0x7f454c46@gmail.com>
+Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
+Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/ftrace.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -4456,7 +4456,6 @@ unregister_ftrace_function_probe_func(ch
+               func_g.type = filter_parse_regex(glob, strlen(glob),
+                                                &func_g.search, &not);
+               func_g.len = strlen(func_g.search);
+-              func_g.search = glob;
+               /* we do not support '!' for function probes */
+               if (WARN_ON(not))
diff --git a/queue-4.15/mn10300-misalignment-use-sigsegv-segv_maperr-to-report-a-failed-user-copy.patch b/queue-4.15/mn10300-misalignment-use-sigsegv-segv_maperr-to-report-a-failed-user-copy.patch
new file mode 100644 (file)
index 0000000..9f31e35
--- /dev/null
@@ -0,0 +1,37 @@
+From 6ac1dc736b323011a55ecd1fc5897c24c4f77cbd Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Tue, 1 Aug 2017 05:02:38 -0500
+Subject: mn10300/misalignment: Use SIGSEGV SEGV_MAPERR to report a failed user copy
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+commit 6ac1dc736b323011a55ecd1fc5897c24c4f77cbd upstream.
+
+Setting si_code to 0 is the same a setting si_code to SI_USER which is definitely
+not correct.  With si_code set to SI_USER si_pid and si_uid will be copied to
+userspace instead of si_addr.  Which is very wrong.
+
+So fix this by using a sensible si_code (SEGV_MAPERR) for this failure.
+
+Fixes: b920de1b77b7 ("mn10300: add the MN10300/AM33 architecture to the kernel")
+Cc: David Howells <dhowells@redhat.com>
+Cc: Masakazu Urade <urade.masakazu@jp.panasonic.com>
+Cc: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mn10300/mm/misalignment.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mn10300/mm/misalignment.c
++++ b/arch/mn10300/mm/misalignment.c
+@@ -437,7 +437,7 @@ transfer_failed:
+       info.si_signo   = SIGSEGV;
+       info.si_errno   = 0;
+-      info.si_code    = 0;
++      info.si_code    = SEGV_MAPERR;
+       info.si_addr    = (void *) regs->pc;
+       force_sig_info(SIGSEGV, &info, current);
+       return;
diff --git a/queue-4.15/objtool-fix-switch-table-detection.patch b/queue-4.15/objtool-fix-switch-table-detection.patch
new file mode 100644 (file)
index 0000000..81e9baa
--- /dev/null
@@ -0,0 +1,129 @@
+From 99ce7962d52d1948ad6f2785e308d48e76e0a6ef Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Thu, 8 Feb 2018 14:02:32 +0100
+Subject: objtool: Fix switch-table detection
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+commit 99ce7962d52d1948ad6f2785e308d48e76e0a6ef upstream.
+
+Linus reported that GCC-7.3 generated a switch-table construct that
+confused objtool. It turns out that, in particular due to KASAN, it is
+possible to have unrelated .rodata usage in between the .rodata setup
+for the switch-table and the following indirect jump.
+
+The simple linear reverse search from the indirect jump would hit upon
+the KASAN .rodata usage first and fail to find a switch_table,
+resulting in a spurious 'sibling call with modified stack frame'
+warning.
+
+Fix this by creating a 'jump-stack' which we can 'unwind' during
+reversal, thereby skipping over much of the in-between code.
+
+This is not fool proof by any means, but is sufficient to make the
+known cases work. Future work would be to construct more comprehensive
+flow analysis code.
+
+Reported-and-tested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/20180208130232.GF25235@hirez.programming.kicks-ass.net
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/objtool/check.c |   41 +++++++++++++++++++++++++++++++++++++++--
+ tools/objtool/check.h |    1 +
+ 2 files changed, 40 insertions(+), 2 deletions(-)
+
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -851,8 +851,14 @@ static int add_switch_table(struct objto
+  *    This is a fairly uncommon pattern which is new for GCC 6.  As of this
+  *    writing, there are 11 occurrences of it in the allmodconfig kernel.
+  *
++ *    As of GCC 7 there are quite a few more of these and the 'in between' code
++ *    is significant. Esp. with KASAN enabled some of the code between the mov
++ *    and jmpq uses .rodata itself, which can confuse things.
++ *
+  *    TODO: Once we have DWARF CFI and smarter instruction decoding logic,
+  *    ensure the same register is used in the mov and jump instructions.
++ *
++ *    NOTE: RETPOLINE made it harder still to decode dynamic jumps.
+  */
+ static struct rela *find_switch_table(struct objtool_file *file,
+                                     struct symbol *func,
+@@ -874,12 +880,25 @@ static struct rela *find_switch_table(st
+                                               text_rela->addend + 4);
+               if (!rodata_rela)
+                       return NULL;
++
+               file->ignore_unreachables = true;
+               return rodata_rela;
+       }
+       /* case 3 */
+-      func_for_each_insn_continue_reverse(file, func, insn) {
++      /*
++       * Backward search using the @first_jump_src links, these help avoid
++       * much of the 'in between' code. Which avoids us getting confused by
++       * it.
++       */
++      for (insn = list_prev_entry(insn, list);
++
++           &insn->list != &file->insn_list &&
++           insn->sec == func->sec &&
++           insn->offset >= func->offset;
++
++           insn = insn->first_jump_src ?: list_prev_entry(insn, list)) {
++
+               if (insn->type == INSN_JUMP_DYNAMIC)
+                       break;
+@@ -909,14 +928,32 @@ static struct rela *find_switch_table(st
+       return NULL;
+ }
++
+ static int add_func_switch_tables(struct objtool_file *file,
+                                 struct symbol *func)
+ {
+-      struct instruction *insn, *prev_jump = NULL;
++      struct instruction *insn, *last = NULL, *prev_jump = NULL;
+       struct rela *rela, *prev_rela = NULL;
+       int ret;
+       func_for_each_insn(file, func, insn) {
++              if (!last)
++                      last = insn;
++
++              /*
++               * Store back-pointers for unconditional forward jumps such
++               * that find_switch_table() can back-track using those and
++               * avoid some potentially confusing code.
++               */
++              if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest &&
++                  insn->offset > last->offset &&
++                  insn->jump_dest->offset > insn->offset &&
++                  !insn->jump_dest->first_jump_src) {
++
++                      insn->jump_dest->first_jump_src = insn;
++                      last = insn->jump_dest;
++              }
++
+               if (insn->type != INSN_JUMP_DYNAMIC)
+                       continue;
+--- a/tools/objtool/check.h
++++ b/tools/objtool/check.h
+@@ -47,6 +47,7 @@ struct instruction {
+       bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts;
+       struct symbol *call_dest;
+       struct instruction *jump_dest;
++      struct instruction *first_jump_src;
+       struct list_head alts;
+       struct symbol *func;
+       struct stack_op stack_op;
diff --git a/queue-4.15/ovl-fix-failure-to-fsync-lower-dir.patch b/queue-4.15/ovl-fix-failure-to-fsync-lower-dir.patch
new file mode 100644 (file)
index 0000000..97d7cdd
--- /dev/null
@@ -0,0 +1,53 @@
+From d796e77f1dd541fe34481af2eee6454688d13982 Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Wed, 8 Nov 2017 09:39:46 +0200
+Subject: ovl: fix failure to fsync lower dir
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+commit d796e77f1dd541fe34481af2eee6454688d13982 upstream.
+
+As a writable mount, it is not expected for overlayfs to return
+EINVAL/EROFS for fsync, even if dir/file is not changed.
+
+This commit fixes the case of fsync of directory, which is easier to
+address, because overlayfs already implements fsync file operation for
+directories.
+
+The problem reported by Raphael is that new PostgreSQL 10.0 with a
+database in overlayfs where lower layer in squashfs fails to start.
+The failure is due to fsync error, when PostgreSQL does fsync on all
+existing db directories on startup and a specific directory exists
+lower layer with no changes.
+
+Reported-by: Raphael Hertzog <raphael@ouaza.com>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Tested-by: Raphaël Hertzog <hertzog@debian.org>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/readdir.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/overlayfs/readdir.c
++++ b/fs/overlayfs/readdir.c
+@@ -769,10 +769,14 @@ static int ovl_dir_fsync(struct file *fi
+       struct dentry *dentry = file->f_path.dentry;
+       struct file *realfile = od->realfile;
++      /* Nothing to sync for lower */
++      if (!OVL_TYPE_UPPER(ovl_path_type(dentry)))
++              return 0;
++
+       /*
+        * Need to check if we started out being a lower dir, but got copied up
+        */
+-      if (!od->is_upper && OVL_TYPE_UPPER(ovl_path_type(dentry))) {
++      if (!od->is_upper) {
+               struct inode *inode = file_inode(file);
+               realfile = READ_ONCE(od->upperfile);
diff --git a/queue-4.15/ovl-force-r-o-mount-when-index-dir-creation-fails.patch b/queue-4.15/ovl-force-r-o-mount-when-index-dir-creation-fails.patch
new file mode 100644 (file)
index 0000000..6762352
--- /dev/null
@@ -0,0 +1,68 @@
+From 972d0093c2f7b1bd57e47a1780a552dde528fd16 Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Tue, 19 Sep 2017 12:14:18 +0300
+Subject: ovl: force r/o mount when index dir creation fails
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+commit 972d0093c2f7b1bd57e47a1780a552dde528fd16 upstream.
+
+When work dir creation fails, a warning is emitted and overlay is
+mounted r/o. Trying to remount r/w will fail with no work dir.
+
+When index dir creation fails, the same warning is emitted and overlay
+is mounted r/o, but trying to remount r/w will succeed. This may cause
+unintentional corruption of filesystem consistency.
+
+Adjust the behavior of index dir creation failure to that of work dir
+creation failure and do not allow to remount r/w. User needs to state
+an explicitly intention to work without an index by mounting with
+option 'index=off' to allow r/w mount with no index dir.
+
+When mounting with option 'index=on' and no 'upperdir', index is
+implicitly disabled, so do not warn about no file handle support.
+
+The issue was introduced with inodes index feature in v4.13, but this
+patch will not apply cleanly before ovl_fill_super() re-factoring in
+v4.15.
+
+Fixes: 02bcd1577400 ("ovl: introduce the inodes index dir feature")
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/super.c |   12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -703,7 +703,8 @@ static int ovl_lower_dir(const char *nam
+        * The inodes index feature needs to encode and decode file
+        * handles, so it requires that all layers support them.
+        */
+-      if (ofs->config.index && !ovl_can_decode_fh(path->dentry->d_sb)) {
++      if (ofs->config.index && ofs->config.upperdir &&
++          !ovl_can_decode_fh(path->dentry->d_sb)) {
+               ofs->config.index = false;
+               pr_warn("overlayfs: fs on '%s' does not support file handles, falling back to index=off.\n", name);
+       }
+@@ -1257,11 +1258,16 @@ static int ovl_fill_super(struct super_b
+               if (err)
+                       goto out_free_oe;
+-              if (!ofs->indexdir)
++              /* Force r/o mount with no index dir */
++              if (!ofs->indexdir) {
++                      dput(ofs->workdir);
++                      ofs->workdir = NULL;
+                       sb->s_flags |= SB_RDONLY;
++              }
++
+       }
+-      /* Show index=off/on in /proc/mounts for any of the reasons above */
++      /* Show index=off in /proc/mounts for forced r/o mount */
+       if (!ofs->indexdir)
+               ofs->config.index = false;
diff --git a/queue-4.15/ovl-hash-directory-inodes-for-fsnotify.patch b/queue-4.15/ovl-hash-directory-inodes-for-fsnotify.patch
new file mode 100644 (file)
index 0000000..870b9a3
--- /dev/null
@@ -0,0 +1,149 @@
+From 31747eda41ef3c30c09c5c096b380bf54013746a Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Sun, 14 Jan 2018 18:35:40 +0200
+Subject: ovl: hash directory inodes for fsnotify
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+commit 31747eda41ef3c30c09c5c096b380bf54013746a upstream.
+
+fsnotify pins a watched directory inode in cache, but if directory dentry
+is released, new lookup will allocate a new dentry and a new inode.
+Directory events will be notified on the new inode, while fsnotify listener
+is watching the old pinned inode.
+
+Hash all directory inodes to reuse the pinned inode on lookup. Pure upper
+dirs are hashes by real upper inode, merge and lower dirs are hashed by
+real lower inode.
+
+The reference to lower inode was being held by the lower dentry object
+in the overlay dentry (oe->lowerstack[0]). Releasing the overlay dentry
+may drop lower inode refcount to zero. Add a refcount on behalf of the
+overlay inode to prevent that.
+
+As a by-product, hashing directory inodes also detects multiple
+redirected dirs to the same lower dir and uncovered redirected dir
+target on and returns -ESTALE on lookup.
+
+The reported issue dates back to initial version of overlayfs, but this
+patch depends on ovl_inode code that was introduced in kernel v4.13.
+
+Reported-by: Niklas Cassel <niklas.cassel@axis.com>
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Tested-by: Niklas Cassel <niklas.cassel@axis.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/inode.c |   39 ++++++++++++++++++++++++++++-----------
+ fs/overlayfs/super.c |    1 +
+ fs/overlayfs/util.c  |    4 ++--
+ 3 files changed, 31 insertions(+), 13 deletions(-)
+
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -606,6 +606,16 @@ static int ovl_inode_set(struct inode *i
+ static bool ovl_verify_inode(struct inode *inode, struct dentry *lowerdentry,
+                            struct dentry *upperdentry)
+ {
++      if (S_ISDIR(inode->i_mode)) {
++              /* Real lower dir moved to upper layer under us? */
++              if (!lowerdentry && ovl_inode_lower(inode))
++                      return false;
++
++              /* Lookup of an uncovered redirect origin? */
++              if (!upperdentry && ovl_inode_upper(inode))
++                      return false;
++      }
++
+       /*
+        * Allow non-NULL lower inode in ovl_inode even if lowerdentry is NULL.
+        * This happens when finding a copied up overlay inode for a renamed
+@@ -633,6 +643,8 @@ struct inode *ovl_get_inode(struct dentr
+       struct inode *inode;
+       /* Already indexed or could be indexed on copy up? */
+       bool indexed = (index || (ovl_indexdir(dentry->d_sb) && !upperdentry));
++      struct dentry *origin = indexed ? lowerdentry : NULL;
++      bool is_dir;
+       if (WARN_ON(upperdentry && indexed && !lowerdentry))
+               return ERR_PTR(-EIO);
+@@ -641,15 +653,19 @@ struct inode *ovl_get_inode(struct dentr
+               realinode = d_inode(lowerdentry);
+       /*
+-       * Copy up origin (lower) may exist for non-indexed upper, but we must
+-       * not use lower as hash key in that case.
+-       * Hash inodes that are or could be indexed by origin inode and
+-       * non-indexed upper inodes that could be hard linked by upper inode.
++       * Copy up origin (lower) may exist for non-indexed non-dir upper, but
++       * we must not use lower as hash key in that case.
++       * Hash non-dir that is or could be indexed by origin inode.
++       * Hash dir that is or could be merged by origin inode.
++       * Hash pure upper and non-indexed non-dir by upper inode.
+        */
+-      if (!S_ISDIR(realinode->i_mode) && (upperdentry || indexed)) {
+-              struct inode *key = d_inode(indexed ? lowerdentry :
+-                                                    upperdentry);
+-              unsigned int nlink;
++      is_dir = S_ISDIR(realinode->i_mode);
++      if (is_dir)
++              origin = lowerdentry;
++
++      if (upperdentry || origin) {
++              struct inode *key = d_inode(origin ?: upperdentry);
++              unsigned int nlink = is_dir ? 1 : realinode->i_nlink;
+               inode = iget5_locked(dentry->d_sb, (unsigned long) key,
+                                    ovl_inode_test, ovl_inode_set, key);
+@@ -670,8 +686,9 @@ struct inode *ovl_get_inode(struct dentr
+                       goto out;
+               }
+-              nlink = ovl_get_nlink(lowerdentry, upperdentry,
+-                                    realinode->i_nlink);
++              /* Recalculate nlink for non-dir due to indexing */
++              if (!is_dir)
++                      nlink = ovl_get_nlink(lowerdentry, upperdentry, nlink);
+               set_nlink(inode, nlink);
+       } else {
+               inode = new_inode(dentry->d_sb);
+@@ -685,7 +702,7 @@ struct inode *ovl_get_inode(struct dentr
+               ovl_set_flag(OVL_IMPURE, inode);
+       /* Check for non-merge dir that may have whiteouts */
+-      if (S_ISDIR(realinode->i_mode)) {
++      if (is_dir) {
+               struct ovl_entry *oe = dentry->d_fsdata;
+               if (((upperdentry && lowerdentry) || oe->numlower > 1) ||
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -211,6 +211,7 @@ static void ovl_destroy_inode(struct ino
+       struct ovl_inode *oi = OVL_I(inode);
+       dput(oi->__upperdentry);
++      iput(oi->lower);
+       kfree(oi->redirect);
+       ovl_dir_cache_free(inode);
+       mutex_destroy(&oi->lock);
+--- a/fs/overlayfs/util.c
++++ b/fs/overlayfs/util.c
+@@ -257,7 +257,7 @@ void ovl_inode_init(struct inode *inode,
+       if (upperdentry)
+               OVL_I(inode)->__upperdentry = upperdentry;
+       if (lowerdentry)
+-              OVL_I(inode)->lower = d_inode(lowerdentry);
++              OVL_I(inode)->lower = igrab(d_inode(lowerdentry));
+       ovl_copyattr(d_inode(upperdentry ?: lowerdentry), inode);
+ }
+@@ -273,7 +273,7 @@ void ovl_inode_update(struct inode *inod
+        */
+       smp_wmb();
+       OVL_I(inode)->__upperdentry = upperdentry;
+-      if (!S_ISDIR(upperinode->i_mode) && inode_unhashed(inode)) {
++      if (inode_unhashed(inode)) {
+               inode->i_private = upperinode;
+               __insert_inode_hash(inode, (unsigned long) upperinode);
+       }
diff --git a/queue-4.15/ovl-take-mnt_want_write-for-removing-impure-xattr.patch b/queue-4.15/ovl-take-mnt_want_write-for-removing-impure-xattr.patch
new file mode 100644 (file)
index 0000000..80c721f
--- /dev/null
@@ -0,0 +1,41 @@
+From a5a927a7c82e28ea76599dee4019c41e372c911f Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Wed, 3 Jan 2018 18:54:42 +0200
+Subject: ovl: take mnt_want_write() for removing impure xattr
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+commit a5a927a7c82e28ea76599dee4019c41e372c911f upstream.
+
+The optimization in ovl_cache_get_impure() that tries to remove an
+unneeded "impure" xattr needs to take mnt_want_write() on upper fs.
+
+Fixes: 4edb83bb1041 ("ovl: constant d_ino for non-merge dirs")
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/readdir.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/fs/overlayfs/readdir.c
++++ b/fs/overlayfs/readdir.c
+@@ -593,8 +593,15 @@ static struct ovl_dir_cache *ovl_cache_g
+               return ERR_PTR(res);
+       }
+       if (list_empty(&cache->entries)) {
+-              /* Good oportunity to get rid of an unnecessary "impure" flag */
+-              ovl_do_removexattr(ovl_dentry_upper(dentry), OVL_XATTR_IMPURE);
++              /*
++               * A good opportunity to get rid of an unneeded "impure" flag.
++               * Removing the "impure" xattr is best effort.
++               */
++              if (!ovl_want_write(dentry)) {
++                      ovl_do_removexattr(ovl_dentry_upper(dentry),
++                                         OVL_XATTR_IMPURE);
++                      ovl_drop_write(dentry);
++              }
+               ovl_clear_flag(OVL_IMPURE, d_inode(dentry));
+               kfree(cache);
+               return NULL;
diff --git a/queue-4.15/ovl-take-mnt_want_write-for-work-index-dir-setup.patch b/queue-4.15/ovl-take-mnt_want_write-for-work-index-dir-setup.patch
new file mode 100644 (file)
index 0000000..d4120ab
--- /dev/null
@@ -0,0 +1,118 @@
+From 2ba9d57e65044859f7ff133bcb0a902769bf3bc6 Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Wed, 3 Jan 2018 18:54:41 +0200
+Subject: ovl: take mnt_want_write() for work/index dir setup
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+commit 2ba9d57e65044859f7ff133bcb0a902769bf3bc6 upstream.
+
+There are several write operations on upper fs not covered by
+mnt_want_write():
+
+- test set/remove OPAQUE xattr
+- test create O_TMPFILE
+- set ORIGIN xattr in ovl_verify_origin()
+- cleanup of index entries in ovl_indexdir_cleanup()
+
+Some of these go way back, but this patch only applies over the
+v4.14 re-factoring of ovl_fill_super().
+
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/super.c |   25 +++++++++++++++++--------
+ 1 file changed, 17 insertions(+), 8 deletions(-)
+
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -520,10 +520,6 @@ static struct dentry *ovl_workdir_create
+       bool retried = false;
+       bool locked = false;
+-      err = mnt_want_write(mnt);
+-      if (err)
+-              goto out_err;
+-
+       inode_lock_nested(dir, I_MUTEX_PARENT);
+       locked = true;
+@@ -588,7 +584,6 @@ retry:
+               goto out_err;
+       }
+ out_unlock:
+-      mnt_drop_write(mnt);
+       if (locked)
+               inode_unlock(dir);
+@@ -930,12 +925,17 @@ out:
+ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
+ {
++      struct vfsmount *mnt = ofs->upper_mnt;
+       struct dentry *temp;
+       int err;
++      err = mnt_want_write(mnt);
++      if (err)
++              return err;
++
+       ofs->workdir = ovl_workdir_create(ofs, OVL_WORKDIR_NAME, false);
+       if (!ofs->workdir)
+-              return 0;
++              goto out;
+       /*
+        * Upper should support d_type, else whiteouts are visible.  Given
+@@ -945,7 +945,7 @@ static int ovl_make_workdir(struct ovl_f
+        */
+       err = ovl_check_d_type_supported(workpath);
+       if (err < 0)
+-              return err;
++              goto out;
+       /*
+        * We allowed this configuration and don't want to break users over
+@@ -969,6 +969,7 @@ static int ovl_make_workdir(struct ovl_f
+       if (err) {
+               ofs->noxattr = true;
+               pr_warn("overlayfs: upper fs does not support xattr.\n");
++              err = 0;
+       } else {
+               vfs_removexattr(ofs->workdir, OVL_XATTR_OPAQUE);
+       }
+@@ -980,7 +981,9 @@ static int ovl_make_workdir(struct ovl_f
+               pr_warn("overlayfs: upper fs does not support file handles, falling back to index=off.\n");
+       }
+-      return 0;
++out:
++      mnt_drop_write(mnt);
++      return err;
+ }
+ static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath)
+@@ -1027,8 +1030,13 @@ out:
+ static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe,
+                           struct path *upperpath)
+ {
++      struct vfsmount *mnt = ofs->upper_mnt;
+       int err;
++      err = mnt_want_write(mnt);
++      if (err)
++              return err;
++
+       /* Verify lower root is upper root origin */
+       err = ovl_verify_origin(upperpath->dentry, oe->lowerstack[0].dentry,
+                               false, true);
+@@ -1056,6 +1064,7 @@ static int ovl_get_indexdir(struct ovl_f
+               pr_warn("overlayfs: try deleting index dir or mounting with '-o index=off' to disable inodes index.\n");
+ out:
++      mnt_drop_write(mnt);
+       return err;
+ }
diff --git a/queue-4.15/scsi-core-ensure-that-the-scsi-error-handler-gets-woken-up.patch b/queue-4.15/scsi-core-ensure-that-the-scsi-error-handler-gets-woken-up.patch
new file mode 100644 (file)
index 0000000..d95d421
--- /dev/null
@@ -0,0 +1,182 @@
+From 3bd6f43f5cb3714f70c591514f344389df593501 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@wdc.com>
+Date: Mon, 4 Dec 2017 10:06:23 -0800
+Subject: scsi: core: Ensure that the SCSI error handler gets woken up
+
+From: Bart Van Assche <bart.vanassche@wdc.com>
+
+commit 3bd6f43f5cb3714f70c591514f344389df593501 upstream.
+
+If scsi_eh_scmd_add() is called concurrently with
+scsi_host_queue_ready() while shost->host_blocked > 0 then it can
+happen that neither function wakes up the SCSI error handler. Fix
+this by making every function that decreases the host_busy counter
+wake up the error handler if necessary and by protecting the
+host_failed checks with the SCSI host lock.
+
+Reported-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+References: https://marc.info/?l=linux-kernel&m=150461610630736
+Fixes: commit 746650160866 ("scsi: convert host_busy to atomic_t")
+Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
+Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Tested-by: Stuart Hayes <stuart.w.hayes@gmail.com>
+Cc: Konstantin Khorenko <khorenko@virtuozzo.com>
+Cc: Stuart Hayes <stuart.w.hayes@gmail.com>
+Cc: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Hannes Reinecke <hare@suse.com>
+Cc: Johannes Thumshirn <jthumshirn@suse.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/hosts.c      |    6 ++++++
+ drivers/scsi/scsi_error.c |   18 ++++++++++++++++--
+ drivers/scsi/scsi_lib.c   |   39 ++++++++++++++++++++++++++++-----------
+ include/scsi/scsi_host.h  |    2 ++
+ 4 files changed, 52 insertions(+), 13 deletions(-)
+
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -318,6 +318,9 @@ static void scsi_host_dev_release(struct
+       scsi_proc_hostdir_rm(shost->hostt);
++      /* Wait for functions invoked through call_rcu(&shost->rcu, ...) */
++      rcu_barrier();
++
+       if (shost->tmf_work_q)
+               destroy_workqueue(shost->tmf_work_q);
+       if (shost->ehandler)
+@@ -325,6 +328,8 @@ static void scsi_host_dev_release(struct
+       if (shost->work_q)
+               destroy_workqueue(shost->work_q);
++      destroy_rcu_head(&shost->rcu);
++
+       if (shost->shost_state == SHOST_CREATED) {
+               /*
+                * Free the shost_dev device name here if scsi_host_alloc()
+@@ -399,6 +404,7 @@ struct Scsi_Host *scsi_host_alloc(struct
+       INIT_LIST_HEAD(&shost->starved_list);
+       init_waitqueue_head(&shost->host_wait);
+       mutex_init(&shost->scan_mutex);
++      init_rcu_head(&shost->rcu);
+       index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL);
+       if (index < 0)
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -220,6 +220,17 @@ static void scsi_eh_reset(struct scsi_cm
+       }
+ }
++static void scsi_eh_inc_host_failed(struct rcu_head *head)
++{
++      struct Scsi_Host *shost = container_of(head, typeof(*shost), rcu);
++      unsigned long flags;
++
++      spin_lock_irqsave(shost->host_lock, flags);
++      shost->host_failed++;
++      scsi_eh_wakeup(shost);
++      spin_unlock_irqrestore(shost->host_lock, flags);
++}
++
+ /**
+  * scsi_eh_scmd_add - add scsi cmd to error handling.
+  * @scmd:     scmd to run eh on.
+@@ -242,9 +253,12 @@ void scsi_eh_scmd_add(struct scsi_cmnd *
+       scsi_eh_reset(scmd);
+       list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
+-      shost->host_failed++;
+-      scsi_eh_wakeup(shost);
+       spin_unlock_irqrestore(shost->host_lock, flags);
++      /*
++       * Ensure that all tasks observe the host state change before the
++       * host_failed change.
++       */
++      call_rcu(&shost->rcu, scsi_eh_inc_host_failed);
+ }
+ /**
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -318,22 +318,39 @@ static void scsi_init_cmd_errh(struct sc
+               cmd->cmd_len = scsi_command_size(cmd->cmnd);
+ }
+-void scsi_device_unbusy(struct scsi_device *sdev)
++/*
++ * Decrement the host_busy counter and wake up the error handler if necessary.
++ * Avoid as follows that the error handler is not woken up if shost->host_busy
++ * == shost->host_failed: use call_rcu() in scsi_eh_scmd_add() in combination
++ * with an RCU read lock in this function to ensure that this function in its
++ * entirety either finishes before scsi_eh_scmd_add() increases the
++ * host_failed counter or that it notices the shost state change made by
++ * scsi_eh_scmd_add().
++ */
++static void scsi_dec_host_busy(struct Scsi_Host *shost)
+ {
+-      struct Scsi_Host *shost = sdev->host;
+-      struct scsi_target *starget = scsi_target(sdev);
+       unsigned long flags;
++      rcu_read_lock();
+       atomic_dec(&shost->host_busy);
+-      if (starget->can_queue > 0)
+-              atomic_dec(&starget->target_busy);
+-
+-      if (unlikely(scsi_host_in_recovery(shost) &&
+-                   (shost->host_failed || shost->host_eh_scheduled))) {
++      if (unlikely(scsi_host_in_recovery(shost))) {
+               spin_lock_irqsave(shost->host_lock, flags);
+-              scsi_eh_wakeup(shost);
++              if (shost->host_failed || shost->host_eh_scheduled)
++                      scsi_eh_wakeup(shost);
+               spin_unlock_irqrestore(shost->host_lock, flags);
+       }
++      rcu_read_unlock();
++}
++
++void scsi_device_unbusy(struct scsi_device *sdev)
++{
++      struct Scsi_Host *shost = sdev->host;
++      struct scsi_target *starget = scsi_target(sdev);
++
++      scsi_dec_host_busy(shost);
++
++      if (starget->can_queue > 0)
++              atomic_dec(&starget->target_busy);
+       atomic_dec(&sdev->device_busy);
+ }
+@@ -1532,7 +1549,7 @@ starved:
+               list_add_tail(&sdev->starved_entry, &shost->starved_list);
+       spin_unlock_irq(shost->host_lock);
+ out_dec:
+-      atomic_dec(&shost->host_busy);
++      scsi_dec_host_busy(shost);
+       return 0;
+ }
+@@ -2020,7 +2037,7 @@ static blk_status_t scsi_queue_rq(struct
+       return BLK_STS_OK;
+ out_dec_host_busy:
+-       atomic_dec(&shost->host_busy);
++      scsi_dec_host_busy(shost);
+ out_dec_target_busy:
+       if (scsi_target(sdev)->can_queue > 0)
+               atomic_dec(&scsi_target(sdev)->target_busy);
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -571,6 +571,8 @@ struct Scsi_Host {
+               struct blk_mq_tag_set   tag_set;
+       };
++      struct rcu_head rcu;
++
+       atomic_t host_busy;                /* commands actually active on low-level */
+       atomic_t host_blocked;
diff --git a/queue-4.15/scsi-cxlflash-reset-command-ioasc.patch b/queue-4.15/scsi-cxlflash-reset-command-ioasc.patch
new file mode 100644 (file)
index 0000000..888a2f8
--- /dev/null
@@ -0,0 +1,41 @@
+From 96cf727fe8f102bf92150b741db71ee39fb8c521 Mon Sep 17 00:00:00 2001
+From: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
+Date: Wed, 3 Jan 2018 16:54:02 -0600
+Subject: scsi: cxlflash: Reset command ioasc
+
+From: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
+
+commit 96cf727fe8f102bf92150b741db71ee39fb8c521 upstream.
+
+In the event of a command failure, cxlflash returns the failure to the upper
+layers to process. After processing the error, when the command is queued
+again, the private command structure will not be zeroed and the ioasc could be
+stale. Per the SISLite specification, the AFU only sets the ioasc in the
+presence of a failure. Thus, even though the original command succeeds the
+second time, the command is considered a failure due to stale ioasc. This
+cycle repeats indefinitely and can cause a hang or IO failure.
+
+To fix the issue, clear the ioasc before queuing any command.
+
+[mkp: added Cc: stable per request]
+
+Fixes: 479ad8e9d48c ("scsi: cxlflash: Remove zeroing of private command data")
+Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
+Acked-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/cxlflash/main.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/scsi/cxlflash/main.c
++++ b/drivers/scsi/cxlflash/main.c
+@@ -620,6 +620,7 @@ static int cxlflash_queuecommand(struct
+       cmd->parent = afu;
+       cmd->hwq_index = hwq_index;
++      cmd->sa.ioasc = 0;
+       cmd->rcb.ctx_id = hwq->ctx_hndl;
+       cmd->rcb.msi = SISL_MSI_RRQ_UPDATED;
+       cmd->rcb.port_sel = CHAN2PORTMASK(scp->device->channel);
diff --git a/queue-4.15/scsi-lpfc-fix-crash-after-bad-bar-setup-on-driver-attachment.patch b/queue-4.15/scsi-lpfc-fix-crash-after-bad-bar-setup-on-driver-attachment.patch
new file mode 100644 (file)
index 0000000..1b3b21b
--- /dev/null
@@ -0,0 +1,149 @@
+From e4b9794efdce13242f4af6682f3ed48ce3864a87 Mon Sep 17 00:00:00 2001
+From: James Smart <jsmart2021@gmail.com>
+Date: Mon, 20 Nov 2017 16:00:31 -0800
+Subject: scsi: lpfc: Fix crash after bad bar setup on driver attachment
+
+From: James Smart <jsmart2021@gmail.com>
+
+commit e4b9794efdce13242f4af6682f3ed48ce3864a87 upstream.
+
+In test cases where an instance of the driver is detached and
+reattached, the driver will crash on reattachment. There is a compound
+if statement that will skip over the bar setup if the pci_resource_start
+call is not successful. The driver erroneously returns success to its
+bar setup in this scenario even though the bars aren't properly
+configured.
+
+Rework the offending code segment for proper initialization steps.  If
+the pci_resource_start call fails, -ENOMEM is now returned.
+
+Sample stack:
+
+rport-5:0-10: blocked FC remote port time out: removing rport
+BUG: unable to handle kernel NULL pointer dereference at           (null)
+... lpfc_sli4_wait_bmbx_ready+0x32/0x70 [lpfc]
+...
+...  RIP: 0010:...  ... lpfc_sli4_wait_bmbx_ready+0x32/0x70 [lpfc]
+ Call Trace:
+  ... lpfc_sli4_post_sync_mbox+0x106/0x4d0 [lpfc]
+  ... ? __alloc_pages_nodemask+0x176/0x420
+  ... ? __kmalloc+0x2e/0x230
+  ... lpfc_sli_issue_mbox_s4+0x533/0x720 [lpfc]
+  ... ? mempool_alloc+0x69/0x170
+  ... ? dma_generic_alloc_coherent+0x8f/0x140
+  ... lpfc_sli_issue_mbox+0xf/0x20 [lpfc]
+  ... lpfc_sli4_driver_resource_setup+0xa6f/0x1130 [lpfc]
+  ... ? lpfc_pci_probe_one+0x23e/0x16f0 [lpfc]
+  ... lpfc_pci_probe_one+0x445/0x16f0 [lpfc]
+  ... local_pci_probe+0x45/0xa0
+  ... work_for_cpu_fn+0x14/0x20
+  ... process_one_work+0x17a/0x440
+
+Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
+Signed-off-by: James Smart <james.smart@broadcom.com>
+Reviewed-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/lpfc/lpfc_init.c |   84 +++++++++++++++++++++++++-----------------
+ 1 file changed, 51 insertions(+), 33 deletions(-)
+
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -9421,44 +9421,62 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba
+               lpfc_sli4_bar0_register_memmap(phba, if_type);
+       }
+-      if ((if_type == LPFC_SLI_INTF_IF_TYPE_0) &&
+-          (pci_resource_start(pdev, PCI_64BIT_BAR2))) {
+-              /*
+-               * Map SLI4 if type 0 HBA Control Register base to a kernel
+-               * virtual address and setup the registers.
+-               */
+-              phba->pci_bar1_map = pci_resource_start(pdev, PCI_64BIT_BAR2);
+-              bar1map_len = pci_resource_len(pdev, PCI_64BIT_BAR2);
+-              phba->sli4_hba.ctrl_regs_memmap_p =
+-                              ioremap(phba->pci_bar1_map, bar1map_len);
+-              if (!phba->sli4_hba.ctrl_regs_memmap_p) {
+-                      dev_printk(KERN_ERR, &pdev->dev,
+-                         "ioremap failed for SLI4 HBA control registers.\n");
++      if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
++              if (pci_resource_start(pdev, PCI_64BIT_BAR2)) {
++                      /*
++                       * Map SLI4 if type 0 HBA Control Register base to a
++                       * kernel virtual address and setup the registers.
++                       */
++                      phba->pci_bar1_map = pci_resource_start(pdev,
++                                                              PCI_64BIT_BAR2);
++                      bar1map_len = pci_resource_len(pdev, PCI_64BIT_BAR2);
++                      phba->sli4_hba.ctrl_regs_memmap_p =
++                                      ioremap(phba->pci_bar1_map,
++                                              bar1map_len);
++                      if (!phba->sli4_hba.ctrl_regs_memmap_p) {
++                              dev_err(&pdev->dev,
++                                         "ioremap failed for SLI4 HBA "
++                                          "control registers.\n");
++                              error = -ENOMEM;
++                              goto out_iounmap_conf;
++                      }
++                      phba->pci_bar2_memmap_p =
++                                       phba->sli4_hba.ctrl_regs_memmap_p;
++                      lpfc_sli4_bar1_register_memmap(phba);
++              } else {
++                      error = -ENOMEM;
+                       goto out_iounmap_conf;
+               }
+-              phba->pci_bar2_memmap_p = phba->sli4_hba.ctrl_regs_memmap_p;
+-              lpfc_sli4_bar1_register_memmap(phba);
+       }
+-      if ((if_type == LPFC_SLI_INTF_IF_TYPE_0) &&
+-          (pci_resource_start(pdev, PCI_64BIT_BAR4))) {
+-              /*
+-               * Map SLI4 if type 0 HBA Doorbell Register base to a kernel
+-               * virtual address and setup the registers.
+-               */
+-              phba->pci_bar2_map = pci_resource_start(pdev, PCI_64BIT_BAR4);
+-              bar2map_len = pci_resource_len(pdev, PCI_64BIT_BAR4);
+-              phba->sli4_hba.drbl_regs_memmap_p =
+-                              ioremap(phba->pci_bar2_map, bar2map_len);
+-              if (!phba->sli4_hba.drbl_regs_memmap_p) {
+-                      dev_printk(KERN_ERR, &pdev->dev,
+-                         "ioremap failed for SLI4 HBA doorbell registers.\n");
+-                      goto out_iounmap_ctrl;
+-              }
+-              phba->pci_bar4_memmap_p = phba->sli4_hba.drbl_regs_memmap_p;
+-              error = lpfc_sli4_bar2_register_memmap(phba, LPFC_VF0);
+-              if (error)
++      if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
++              if (pci_resource_start(pdev, PCI_64BIT_BAR4)) {
++                      /*
++                       * Map SLI4 if type 0 HBA Doorbell Register base to
++                       * a kernel virtual address and setup the registers.
++                       */
++                      phba->pci_bar2_map = pci_resource_start(pdev,
++                                                              PCI_64BIT_BAR4);
++                      bar2map_len = pci_resource_len(pdev, PCI_64BIT_BAR4);
++                      phba->sli4_hba.drbl_regs_memmap_p =
++                                      ioremap(phba->pci_bar2_map,
++                                              bar2map_len);
++                      if (!phba->sli4_hba.drbl_regs_memmap_p) {
++                              dev_err(&pdev->dev,
++                                         "ioremap failed for SLI4 HBA"
++                                         " doorbell registers.\n");
++                              error = -ENOMEM;
++                              goto out_iounmap_ctrl;
++                      }
++                      phba->pci_bar4_memmap_p =
++                                      phba->sli4_hba.drbl_regs_memmap_p;
++                      error = lpfc_sli4_bar2_register_memmap(phba, LPFC_VF0);
++                      if (error)
++                              goto out_iounmap_all;
++              } else {
++                      error = -ENOMEM;
+                       goto out_iounmap_all;
++              }
+       }
+       return 0;
index ee3ad623fbafa78769189ea2b4c1c89596d42c90..31c6d9ceaf0ecfc29be956635db4c2e451004214 100644 (file)
@@ -184,3 +184,19 @@ blk-mq-quiesce-queue-before-freeing-queue.patch
 clocksource-drivers-stm32-fix-kernel-panic-with-multiple-timers.patch
 lib-ubsan.c-s-missaligned-misaligned.patch
 lib-ubsan-add-type-mismatch-handler-for-new-gcc-clang.patch
+objtool-fix-switch-table-detection.patch
+arm64-dts-marvell-add-ethernet-aliases.patch
+drm-i915-avoid-pps-hw-sw-state-mismatch-due-to-rounding.patch
+acpi-sbshc-remove-raw-pointer-from-printk-message.patch
+acpi-nfit-fix-register-dimm-error-handling.patch
+ovl-force-r-o-mount-when-index-dir-creation-fails.patch
+ovl-fix-failure-to-fsync-lower-dir.patch
+ovl-take-mnt_want_write-for-work-index-dir-setup.patch
+ovl-take-mnt_want_write-for-removing-impure-xattr.patch
+ovl-hash-directory-inodes-for-fsnotify.patch
+mn10300-misalignment-use-sigsegv-segv_maperr-to-report-a-failed-user-copy.patch
+devpts-fix-error-handling-in-devpts_mntget.patch
+ftrace-remove-incorrect-setting-of-glob-search-field.patch
+scsi-core-ensure-that-the-scsi-error-handler-gets-woken-up.patch
+scsi-lpfc-fix-crash-after-bad-bar-setup-on-driver-attachment.patch
+scsi-cxlflash-reset-command-ioasc.patch