From: Greg Kroah-Hartman Date: Thu, 15 Feb 2018 14:37:43 +0000 (+0100) Subject: 4.15-stable patches X-Git-Tag: v4.15.4~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5b44ad35bace4f5a425c428e1469f8857ecd838e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.15-stable patches 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 --- 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 index 00000000000..f23faf68d2c --- /dev/null +++ b/queue-4.15/acpi-nfit-fix-register-dimm-error-handling.patch @@ -0,0 +1,37 @@ +From 23fbd7c70aec7600e3227eb24259fc55bf6e4881 Mon Sep 17 00:00:00 2001 +From: Toshi Kani +Date: Fri, 2 Feb 2018 14:00:36 -0700 +Subject: acpi, nfit: fix register dimm error handling + +From: Toshi Kani + +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 +Cc: "Rafael J. Wysocki" +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1f31c494e89 --- /dev/null +++ b/queue-4.15/acpi-sbshc-remove-raw-pointer-from-printk-message.patch @@ -0,0 +1,35 @@ +From 43cdd1b716b26f6af16da4e145b6578f98798bf6 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Fri, 19 Jan 2018 10:06:03 +0100 +Subject: ACPI: sbshc: remove raw pointer from printk() message + +From: Greg Kroah-Hartman + +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 +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..bfc314233ef --- /dev/null +++ b/queue-4.15/arm64-dts-marvell-add-ethernet-aliases.patch @@ -0,0 +1,72 @@ +From 474c5885582c4a79c21bcf01ed98f98c935f1f4a Mon Sep 17 00:00:00 2001 +From: Yan Markman +Date: Wed, 3 Jan 2018 16:18:52 +0100 +Subject: arm64: dts: marvell: add Ethernet aliases + +From: Yan Markman + +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 +[Antoine: commit message, small fixes] +Signed-off-by: Antoine Tenart +Signed-off-by: Gregory CLEMENT +Signed-off-by: Greg Kroah-Hartman + + +--- + 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 index 00000000000..5cf953466e8 --- /dev/null +++ b/queue-4.15/devpts-fix-error-handling-in-devpts_mntget.patch @@ -0,0 +1,60 @@ +From c9cc8d01fb04117928830449388512a5047569c9 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Wed, 31 Jan 2018 00:49:18 -0800 +Subject: devpts: fix error handling in devpts_mntget() + +From: Eric Biggers + +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 + #include + #include + #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 +Signed-off-by: Eric Biggers +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..10206cea5aa --- /dev/null +++ b/queue-4.15/drm-i915-avoid-pps-hw-sw-state-mismatch-due-to-rounding.patch @@ -0,0 +1,48 @@ +From 5643205c6340b565a3be0fe0e7305dc4aa551c74 Mon Sep 17 00:00:00 2001 +From: Imre Deak +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 + +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 +Signed-off-by: Imre Deak +Reviewed-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20171129175137.2889-1-imre.deak@intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8be4430afbc --- /dev/null +++ b/queue-4.15/ftrace-remove-incorrect-setting-of-glob-search-field.patch @@ -0,0 +1,52 @@ +From 7b6586562708d2b3a04fe49f217ddbadbbbb0546 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Mon, 5 Feb 2018 22:05:31 -0500 +Subject: ftrace: Remove incorrect setting of glob search field + +From: Steven Rostedt (VMware) + +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 +Reported-by: Al Viro +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + 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, ¬); + 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 index 00000000000..9f31e352f8a --- /dev/null +++ b/queue-4.15/mn10300-misalignment-use-sigsegv-segv_maperr-to-report-a-failed-user-copy.patch @@ -0,0 +1,37 @@ +From 6ac1dc736b323011a55ecd1fc5897c24c4f77cbd Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +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 + +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 +Cc: Masakazu Urade +Cc: Koichi Yasutake +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..81e9baaf1aa --- /dev/null +++ b/queue-4.15/objtool-fix-switch-table-detection.patch @@ -0,0 +1,129 @@ +From 99ce7962d52d1948ad6f2785e308d48e76e0a6ef Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Thu, 8 Feb 2018 14:02:32 +0100 +Subject: objtool: Fix switch-table detection + +From: Peter Zijlstra + +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 +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Josh Poimboeuf +Cc: Borislav Petkov +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Link: http://lkml.kernel.org/r/20180208130232.GF25235@hirez.programming.kicks-ass.net +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..97d7cdd5f71 --- /dev/null +++ b/queue-4.15/ovl-fix-failure-to-fsync-lower-dir.patch @@ -0,0 +1,53 @@ +From d796e77f1dd541fe34481af2eee6454688d13982 Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +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 + +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 +Signed-off-by: Amir Goldstein +Tested-by: Raphaël Hertzog +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..676235286af --- /dev/null +++ b/queue-4.15/ovl-force-r-o-mount-when-index-dir-creation-fails.patch @@ -0,0 +1,68 @@ +From 972d0093c2f7b1bd57e47a1780a552dde528fd16 Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Tue, 19 Sep 2017 12:14:18 +0300 +Subject: ovl: force r/o mount when index dir creation fails + +From: Amir Goldstein + +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 +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..870b9a335d7 --- /dev/null +++ b/queue-4.15/ovl-hash-directory-inodes-for-fsnotify.patch @@ -0,0 +1,149 @@ +From 31747eda41ef3c30c09c5c096b380bf54013746a Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Sun, 14 Jan 2018 18:35:40 +0200 +Subject: ovl: hash directory inodes for fsnotify + +From: Amir Goldstein + +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 +Signed-off-by: Amir Goldstein +Signed-off-by: Miklos Szeredi +Tested-by: Niklas Cassel +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..80c721fb1a1 --- /dev/null +++ b/queue-4.15/ovl-take-mnt_want_write-for-removing-impure-xattr.patch @@ -0,0 +1,41 @@ +From a5a927a7c82e28ea76599dee4019c41e372c911f Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Wed, 3 Jan 2018 18:54:42 +0200 +Subject: ovl: take mnt_want_write() for removing impure xattr + +From: Amir Goldstein + +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 +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d4120aba99a --- /dev/null +++ b/queue-4.15/ovl-take-mnt_want_write-for-work-index-dir-setup.patch @@ -0,0 +1,118 @@ +From 2ba9d57e65044859f7ff133bcb0a902769bf3bc6 Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Wed, 3 Jan 2018 18:54:41 +0200 +Subject: ovl: take mnt_want_write() for work/index dir setup + +From: Amir Goldstein + +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 +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d95d421fc85 --- /dev/null +++ b/queue-4.15/scsi-core-ensure-that-the-scsi-error-handler-gets-woken-up.patch @@ -0,0 +1,182 @@ +From 3bd6f43f5cb3714f70c591514f344389df593501 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +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 + +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 +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 +Reviewed-by: Pavel Tikhomirov +Tested-by: Stuart Hayes +Cc: Konstantin Khorenko +Cc: Stuart Hayes +Cc: Pavel Tikhomirov +Cc: Christoph Hellwig +Cc: Hannes Reinecke +Cc: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..888a2f88c1f --- /dev/null +++ b/queue-4.15/scsi-cxlflash-reset-command-ioasc.patch @@ -0,0 +1,41 @@ +From 96cf727fe8f102bf92150b741db71ee39fb8c521 Mon Sep 17 00:00:00 2001 +From: Uma Krishnan +Date: Wed, 3 Jan 2018 16:54:02 -0600 +Subject: scsi: cxlflash: Reset command ioasc + +From: Uma Krishnan + +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 +Acked-by: Matthew R. Ochs +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1b3b21b4265 --- /dev/null +++ b/queue-4.15/scsi-lpfc-fix-crash-after-bad-bar-setup-on-driver-attachment.patch @@ -0,0 +1,149 @@ +From e4b9794efdce13242f4af6682f3ed48ce3864a87 Mon Sep 17 00:00:00 2001 +From: James Smart +Date: Mon, 20 Nov 2017 16:00:31 -0800 +Subject: scsi: lpfc: Fix crash after bad bar setup on driver attachment + +From: James Smart + +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 +Signed-off-by: James Smart +Reviewed-by: Hannes Reinecke +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.15/series b/queue-4.15/series index ee3ad623fba..31c6d9ceaf0 100644 --- a/queue-4.15/series +++ b/queue-4.15/series @@ -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