From: Greg Kroah-Hartman Date: Mon, 3 Sep 2018 13:32:10 +0000 (+0200) Subject: 4.18-stable patches X-Git-Tag: v3.18.121~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=13c5a9d49605c6a3868ad066a21f596d484463fc;p=thirdparty%2Fkernel%2Fstable-queue.git 4.18-stable patches added patches: cdrom-fix-info-leak-oob-read-in-cdrom_ioctl_drive_status.patch clk-npcm7xx-fix-memory-allocation.patch clk-rockchip-fix-clk_i2sout-parent-selection-bits-on-rk3399.patch iscsi-target-fix-session-creation-failure-handling.patch kprobes-arm-fix-p-uses-in-error-messages.patch kprobes-make-list-and-blacklist-root-user-read-only.patch kprobes-replace-p-with-other-pointer-types.patch kprobes-show-blacklist-addresses-as-same-as-kallsyms-does.patch mips-always-use-march-arch-not-arch-shortcuts.patch mips-change-definition-of-cpu_relax-for-loongson-3.patch mips-correct-the-64-bit-dsp-accumulator-register-size.patch mips-lib-provide-mips64r6-__multi3-for-gcc-7.patch mips-memset.s-fix-byte_fixup-for-mipsr6.patch mtd-rawnand-fsmc-stop-using-chip-read_buf.patch mtd-rawnand-hynix-use-exec_op-in-hynix_nand_reg_write_op.patch mtd-rawnand-marvell-add-suspend-and-resume-hooks.patch mtd-rawnand-qcom-wait-for-desc-completion-in-all-bam-channels.patch pm-clk-signedness-bug-in-of_pm_clk_add_clks.patch power-generic-adc-battery-check-for-duplicate-properties-copied-from-iio-channels.patch power-generic-adc-battery-fix-out-of-bounds-write-when-copying-channel-properties.patch s390-fix-br_r1_trampoline-for-machines-without-exrl.patch s390-lib-use-expoline-for-all-bcr-instructions.patch s390-mm-fix-addressing-exception-after-suspend-resume.patch s390-numa-move-initial-setup-of-node_to_cpumask_map.patch s390-pci-fix-out-of-bounds-access-during-irq-setup.patch s390-purgatory-add-missing-force-to-makefile-targets.patch s390-purgatory-fix-crash-with-expoline-enabled.patch s390-qdio-reset-old-sbal_state-flags.patch scsi-core-avoid-that-scsi-device-removal-through-sysfs-triggers-a-deadlock.patch scsi-mpt3sas-fix-_transport_smp_handler-error-path.patch scsi-mpt3sas-fix-calltrace-observed-while-running-io-reset.patch scsi-sysfs-introduce-sysfs_-un-break_active_protection.patch tpm-return-the-actual-size-when-receiving-an-unsupported-command.patch tpm-separate-cmd_ready-go_idle-from-runtime_pm.patch watchdog-mark-watchdog-touch-functions-as-notrace.patch --- diff --git a/queue-4.18/cdrom-fix-info-leak-oob-read-in-cdrom_ioctl_drive_status.patch b/queue-4.18/cdrom-fix-info-leak-oob-read-in-cdrom_ioctl_drive_status.patch new file mode 100644 index 00000000000..16919a2f7ce --- /dev/null +++ b/queue-4.18/cdrom-fix-info-leak-oob-read-in-cdrom_ioctl_drive_status.patch @@ -0,0 +1,36 @@ +From 8f3fafc9c2f0ece10832c25f7ffcb07c97a32ad4 Mon Sep 17 00:00:00 2001 +From: Scott Bauer +Date: Thu, 26 Apr 2018 11:51:08 -0600 +Subject: cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status + +From: Scott Bauer + +commit 8f3fafc9c2f0ece10832c25f7ffcb07c97a32ad4 upstream. + +Like d88b6d04: "cdrom: information leak in cdrom_ioctl_media_changed()" + +There is another cast from unsigned long to int which causes +a bounds check to fail with specially crafted input. The value is +then used as an index in the slot array in cdrom_slot_status(). + +Signed-off-by: Scott Bauer +Signed-off-by: Scott Bauer +Cc: stable@vger.kernel.org +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cdrom/cdrom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/cdrom/cdrom.c ++++ b/drivers/cdrom/cdrom.c +@@ -2542,7 +2542,7 @@ static int cdrom_ioctl_drive_status(stru + if (!CDROM_CAN(CDC_SELECT_DISC) || + (arg == CDSL_CURRENT || arg == CDSL_NONE)) + return cdi->ops->drive_status(cdi, CDSL_CURRENT); +- if (((int)arg >= cdi->capacity)) ++ if (arg >= cdi->capacity) + return -EINVAL; + return cdrom_slot_status(cdi, arg); + } diff --git a/queue-4.18/clk-npcm7xx-fix-memory-allocation.patch b/queue-4.18/clk-npcm7xx-fix-memory-allocation.patch new file mode 100644 index 00000000000..be800fe66c1 --- /dev/null +++ b/queue-4.18/clk-npcm7xx-fix-memory-allocation.patch @@ -0,0 +1,58 @@ +From 450b6b9b169382205f88858541a8b79830262ce7 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Thu, 23 Aug 2018 18:06:54 -0500 +Subject: clk: npcm7xx: fix memory allocation + +From: Gustavo A. R. Silva + +commit 450b6b9b169382205f88858541a8b79830262ce7 upstream. + +One of the more common cases of allocation size calculations is finding +the size of a structure that has a zero-sized array at the end, along +with memory for some number of elements for that array. For example: + +struct foo { + int stuff; + void *entry[]; +}; + +instance = kzalloc(sizeof(struct foo) + sizeof(void *) * count, +GFP_KERNEL); + +Instead of leaving these open-coded and prone to type mistakes, we can +now use the new struct_size() helper: + +instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL); + +Notice that, currently, there is a bug during the allocation: + +sizeof(npcm7xx_clk_data) should be sizeof(*npcm7xx_clk_data) + +Fix this bug by using struct_size() in kzalloc() + +This issue was detected with the help of Coccinelle. + +Cc: stable@vger.kernel.org +Signed-off-by: Gustavo A. R. Silva +Reviewed-by: Kees Cook +Reviewed-by: Avi Fishman +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/clk-npcm7xx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/clk/clk-npcm7xx.c ++++ b/drivers/clk/clk-npcm7xx.c +@@ -558,8 +558,8 @@ static void __init npcm7xx_clk_init(stru + if (!clk_base) + goto npcm7xx_init_error; + +- npcm7xx_clk_data = kzalloc(sizeof(*npcm7xx_clk_data->hws) * +- NPCM7XX_NUM_CLOCKS + sizeof(npcm7xx_clk_data), GFP_KERNEL); ++ npcm7xx_clk_data = kzalloc(struct_size(npcm7xx_clk_data, hws, ++ NPCM7XX_NUM_CLOCKS), GFP_KERNEL); + if (!npcm7xx_clk_data) + goto npcm7xx_init_np_err; + diff --git a/queue-4.18/clk-rockchip-fix-clk_i2sout-parent-selection-bits-on-rk3399.patch b/queue-4.18/clk-rockchip-fix-clk_i2sout-parent-selection-bits-on-rk3399.patch new file mode 100644 index 00000000000..6520b45a6f0 --- /dev/null +++ b/queue-4.18/clk-rockchip-fix-clk_i2sout-parent-selection-bits-on-rk3399.patch @@ -0,0 +1,33 @@ +From a64ad008980c65d38e6cf6858429c78e6b740c41 Mon Sep 17 00:00:00 2001 +From: Alberto Panizzo +Date: Fri, 6 Jul 2018 15:18:51 +0200 +Subject: clk: rockchip: fix clk_i2sout parent selection bits on rk3399 + +From: Alberto Panizzo + +commit a64ad008980c65d38e6cf6858429c78e6b740c41 upstream. + +Register, shift and mask were wrong according to datasheet. + +Fixes: 115510053e5e ("clk: rockchip: add clock controller for the RK3399") +Cc: stable@vger.kernel.org +Signed-off-by: Alberto Panizzo +Signed-off-by: Anthony Brandon +Signed-off-by: Heiko Stuebner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/rockchip/clk-rk3399.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/clk/rockchip/clk-rk3399.c ++++ b/drivers/clk/rockchip/clk-rk3399.c +@@ -631,7 +631,7 @@ static struct rockchip_clk_branch rk3399 + MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT, + RK3399_CLKSEL_CON(31), 0, 2, MFLAGS), + COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "clk_i2sout", mux_i2sout_p, CLK_SET_RATE_PARENT, +- RK3399_CLKSEL_CON(30), 8, 2, MFLAGS, ++ RK3399_CLKSEL_CON(31), 2, 1, MFLAGS, + RK3399_CLKGATE_CON(8), 12, GFLAGS), + + /* uart */ diff --git a/queue-4.18/iscsi-target-fix-session-creation-failure-handling.patch b/queue-4.18/iscsi-target-fix-session-creation-failure-handling.patch new file mode 100644 index 00000000000..447e8c64a65 --- /dev/null +++ b/queue-4.18/iscsi-target-fix-session-creation-failure-handling.patch @@ -0,0 +1,98 @@ +From 26abc916a898d34c5ad159315a2f683def3c5555 Mon Sep 17 00:00:00 2001 +From: Mike Christie +Date: Thu, 26 Jul 2018 12:13:49 -0500 +Subject: iscsi target: fix session creation failure handling + +From: Mike Christie + +commit 26abc916a898d34c5ad159315a2f683def3c5555 upstream. + +The problem is that iscsi_login_zero_tsih_s1 sets conn->sess early in +iscsi_login_set_conn_values. If the function fails later like when we +alloc the idr it does kfree(sess) and leaves the conn->sess pointer set. +iscsi_login_zero_tsih_s1 then returns -Exyz and we then call +iscsi_target_login_sess_out and access the freed memory. + +This patch has iscsi_login_zero_tsih_s1 either completely setup the +session or completely tear it down, so later in +iscsi_target_login_sess_out we can just check for it being set to the +connection. + +Cc: stable@vger.kernel.org +Fixes: 0957627a9960 ("iscsi-target: Fix sess allocation leak in...") +Signed-off-by: Mike Christie +Acked-by: Martin K. Petersen +Signed-off-by: Matthew Wilcox +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target_login.c | 35 ++++++++++++++++++------------ + 1 file changed, 21 insertions(+), 14 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target_login.c ++++ b/drivers/target/iscsi/iscsi_target_login.c +@@ -348,8 +348,7 @@ static int iscsi_login_zero_tsih_s1( + pr_err("idr_alloc() for sess_idr failed\n"); + iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, + ISCSI_LOGIN_STATUS_NO_RESOURCES); +- kfree(sess); +- return -ENOMEM; ++ goto free_sess; + } + + sess->creation_time = get_jiffies_64(); +@@ -365,20 +364,28 @@ static int iscsi_login_zero_tsih_s1( + ISCSI_LOGIN_STATUS_NO_RESOURCES); + pr_err("Unable to allocate memory for" + " struct iscsi_sess_ops.\n"); +- kfree(sess); +- return -ENOMEM; ++ goto remove_idr; + } + + sess->se_sess = transport_init_session(TARGET_PROT_NORMAL); + if (IS_ERR(sess->se_sess)) { + iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, + ISCSI_LOGIN_STATUS_NO_RESOURCES); +- kfree(sess->sess_ops); +- kfree(sess); +- return -ENOMEM; ++ goto free_ops; + } + + return 0; ++ ++free_ops: ++ kfree(sess->sess_ops); ++remove_idr: ++ spin_lock_bh(&sess_idr_lock); ++ idr_remove(&sess_idr, sess->session_index); ++ spin_unlock_bh(&sess_idr_lock); ++free_sess: ++ kfree(sess); ++ conn->sess = NULL; ++ return -ENOMEM; + } + + static int iscsi_login_zero_tsih_s2( +@@ -1161,13 +1168,13 @@ void iscsi_target_login_sess_out(struct + ISCSI_LOGIN_STATUS_INIT_ERR); + if (!zero_tsih || !conn->sess) + goto old_sess_out; +- if (conn->sess->se_sess) +- transport_free_session(conn->sess->se_sess); +- if (conn->sess->session_index != 0) { +- spin_lock_bh(&sess_idr_lock); +- idr_remove(&sess_idr, conn->sess->session_index); +- spin_unlock_bh(&sess_idr_lock); +- } ++ ++ transport_free_session(conn->sess->se_sess); ++ ++ spin_lock_bh(&sess_idr_lock); ++ idr_remove(&sess_idr, conn->sess->session_index); ++ spin_unlock_bh(&sess_idr_lock); ++ + kfree(conn->sess->sess_ops); + kfree(conn->sess); + conn->sess = NULL; diff --git a/queue-4.18/kprobes-arm-fix-p-uses-in-error-messages.patch b/queue-4.18/kprobes-arm-fix-p-uses-in-error-messages.patch new file mode 100644 index 00000000000..d5f2264bcc4 --- /dev/null +++ b/queue-4.18/kprobes-arm-fix-p-uses-in-error-messages.patch @@ -0,0 +1,65 @@ +From 75b2f5f5911fe7a2fc82969b2b24dde34e8f820d Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Sat, 28 Apr 2018 21:37:33 +0900 +Subject: kprobes/arm: Fix %p uses in error messages + +From: Masami Hiramatsu + +commit 75b2f5f5911fe7a2fc82969b2b24dde34e8f820d upstream. + +Fix %p uses in error messages by removing it and +using general dumper. + +Signed-off-by: Masami Hiramatsu +Cc: Ananth N Mavinakayanahalli +Cc: Anil S Keshavamurthy +Cc: Arnd Bergmann +Cc: David Howells +Cc: David S . Miller +Cc: Heiko Carstens +Cc: Jon Medhurst +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Thomas Richter +Cc: Tobin C . Harding +Cc: Will Deacon +Cc: acme@kernel.org +Cc: akpm@linux-foundation.org +Cc: brueckner@linux.vnet.ibm.com +Cc: linux-arch@vger.kernel.org +Cc: rostedt@goodmis.org +Cc: schwidefsky@de.ibm.com +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/lkml/152491905361.9916.15300852365956231645.stgit@devbox +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/probes/kprobes/core.c | 4 ++-- + arch/arm/probes/kprobes/test-core.c | 1 - + 2 files changed, 2 insertions(+), 3 deletions(-) + +--- a/arch/arm/probes/kprobes/core.c ++++ b/arch/arm/probes/kprobes/core.c +@@ -289,8 +289,8 @@ void __kprobes kprobe_handler(struct pt_ + break; + case KPROBE_REENTER: + /* A nested probe was hit in FIQ, it is a BUG */ +- pr_warn("Unrecoverable kprobe detected at %p.\n", +- p->addr); ++ pr_warn("Unrecoverable kprobe detected.\n"); ++ dump_kprobe(p); + /* fall through */ + default: + /* impossible cases */ +--- a/arch/arm/probes/kprobes/test-core.c ++++ b/arch/arm/probes/kprobes/test-core.c +@@ -1461,7 +1461,6 @@ fail: + print_registers(&result_regs); + + if (mem) { +- pr_err("current_stack=%p\n", current_stack); + pr_err("expected_memory:\n"); + print_memory(expected_memory, mem_size); + pr_err("result_memory:\n"); diff --git a/queue-4.18/kprobes-make-list-and-blacklist-root-user-read-only.patch b/queue-4.18/kprobes-make-list-and-blacklist-root-user-read-only.patch new file mode 100644 index 00000000000..f09eabe4d8e --- /dev/null +++ b/queue-4.18/kprobes-make-list-and-blacklist-root-user-read-only.patch @@ -0,0 +1,63 @@ +From f2a3ab36077222437b4826fc76111caa14562b7c Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Sat, 28 Apr 2018 21:35:01 +0900 +Subject: kprobes: Make list and blacklist root user read only + +From: Masami Hiramatsu + +commit f2a3ab36077222437b4826fc76111caa14562b7c upstream. + +Since the blacklist and list files on debugfs indicates +a sensitive address information to reader, it should be +restricted to the root user. + +Suggested-by: Thomas Richter +Suggested-by: Ingo Molnar +Signed-off-by: Masami Hiramatsu +Cc: Ananth N Mavinakayanahalli +Cc: Anil S Keshavamurthy +Cc: Arnd Bergmann +Cc: David Howells +Cc: David S . Miller +Cc: Heiko Carstens +Cc: Jon Medhurst +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Tobin C . Harding +Cc: Will Deacon +Cc: acme@kernel.org +Cc: akpm@linux-foundation.org +Cc: brueckner@linux.vnet.ibm.com +Cc: linux-arch@vger.kernel.org +Cc: rostedt@goodmis.org +Cc: schwidefsky@de.ibm.com +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/lkml/152491890171.9916.5183693615601334087.stgit@devbox +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/kprobes.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -2617,7 +2617,7 @@ static int __init debugfs_kprobe_init(vo + if (!dir) + return -ENOMEM; + +- file = debugfs_create_file("list", 0444, dir, NULL, ++ file = debugfs_create_file("list", 0400, dir, NULL, + &debugfs_kprobes_operations); + if (!file) + goto error; +@@ -2627,7 +2627,7 @@ static int __init debugfs_kprobe_init(vo + if (!file) + goto error; + +- file = debugfs_create_file("blacklist", 0444, dir, NULL, ++ file = debugfs_create_file("blacklist", 0400, dir, NULL, + &debugfs_kprobe_blacklist_ops); + if (!file) + goto error; diff --git a/queue-4.18/kprobes-replace-p-with-other-pointer-types.patch b/queue-4.18/kprobes-replace-p-with-other-pointer-types.patch new file mode 100644 index 00000000000..fe7c3e94d3a --- /dev/null +++ b/queue-4.18/kprobes-replace-p-with-other-pointer-types.patch @@ -0,0 +1,103 @@ +From 4458515b2c52831ee622411d2fe3e774d1f5c49a Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Sat, 28 Apr 2018 21:36:33 +0900 +Subject: kprobes: Replace %p with other pointer types + +From: Masami Hiramatsu + +commit 4458515b2c52831ee622411d2fe3e774d1f5c49a upstream. + +Replace %p with %pS or just remove it if unneeded. +And use WARN_ONCE() if it is a single bug. + +Signed-off-by: Masami Hiramatsu +Cc: Ananth N Mavinakayanahalli +Cc: Anil S Keshavamurthy +Cc: Arnd Bergmann +Cc: David Howells +Cc: David S . Miller +Cc: Heiko Carstens +Cc: Jon Medhurst +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Thomas Richter +Cc: Tobin C . Harding +Cc: Will Deacon +Cc: acme@kernel.org +Cc: akpm@linux-foundation.org +Cc: brueckner@linux.vnet.ibm.com +Cc: linux-arch@vger.kernel.org +Cc: rostedt@goodmis.org +Cc: schwidefsky@de.ibm.com +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/lkml/152491899284.9916.5350534544808158621.stgit@devbox +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/kprobes.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -710,9 +710,7 @@ static void reuse_unused_kprobe(struct k + * there is still a relative jump) and disabled. + */ + op = container_of(ap, struct optimized_kprobe, kp); +- if (unlikely(list_empty(&op->list))) +- printk(KERN_WARNING "Warning: found a stray unused " +- "aggrprobe@%p\n", ap->addr); ++ WARN_ON_ONCE(list_empty(&op->list)); + /* Enable the probe again */ + ap->flags &= ~KPROBE_FLAG_DISABLED; + /* Optimize it again (remove from op->list) */ +@@ -985,7 +983,8 @@ static int arm_kprobe_ftrace(struct kpro + ret = ftrace_set_filter_ip(&kprobe_ftrace_ops, + (unsigned long)p->addr, 0, 0); + if (ret) { +- pr_debug("Failed to arm kprobe-ftrace at %p (%d)\n", p->addr, ret); ++ pr_debug("Failed to arm kprobe-ftrace at %pS (%d)\n", ++ p->addr, ret); + return ret; + } + +@@ -1025,7 +1024,8 @@ static int disarm_kprobe_ftrace(struct k + + ret = ftrace_set_filter_ip(&kprobe_ftrace_ops, + (unsigned long)p->addr, 1, 0); +- WARN(ret < 0, "Failed to disarm kprobe-ftrace at %p (%d)\n", p->addr, ret); ++ WARN_ONCE(ret < 0, "Failed to disarm kprobe-ftrace at %pS (%d)\n", ++ p->addr, ret); + return ret; + } + #else /* !CONFIG_KPROBES_ON_FTRACE */ +@@ -2169,11 +2169,12 @@ out: + } + EXPORT_SYMBOL_GPL(enable_kprobe); + ++/* Caller must NOT call this in usual path. This is only for critical case */ + void dump_kprobe(struct kprobe *kp) + { +- printk(KERN_WARNING "Dumping kprobe:\n"); +- printk(KERN_WARNING "Name: %s\nAddress: %p\nOffset: %x\n", +- kp->symbol_name, kp->addr, kp->offset); ++ pr_err("Dumping kprobe:\n"); ++ pr_err("Name: %s\nOffset: %x\nAddress: %pS\n", ++ kp->symbol_name, kp->offset, kp->addr); + } + NOKPROBE_SYMBOL(dump_kprobe); + +@@ -2196,11 +2197,8 @@ static int __init populate_kprobe_blackl + entry = arch_deref_entry_point((void *)*iter); + + if (!kernel_text_address(entry) || +- !kallsyms_lookup_size_offset(entry, &size, &offset)) { +- pr_err("Failed to find blacklist at %p\n", +- (void *)entry); ++ !kallsyms_lookup_size_offset(entry, &size, &offset)) + continue; +- } + + ent = kmalloc(sizeof(*ent), GFP_KERNEL); + if (!ent) diff --git a/queue-4.18/kprobes-show-blacklist-addresses-as-same-as-kallsyms-does.patch b/queue-4.18/kprobes-show-blacklist-addresses-as-same-as-kallsyms-does.patch new file mode 100644 index 00000000000..bd6ae3d900d --- /dev/null +++ b/queue-4.18/kprobes-show-blacklist-addresses-as-same-as-kallsyms-does.patch @@ -0,0 +1,67 @@ +From ffb9bd68ebdb3b8d00ef5a79bbe8167a3281cace Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Sat, 28 Apr 2018 21:35:32 +0900 +Subject: kprobes: Show blacklist addresses as same as kallsyms does + +From: Masami Hiramatsu + +commit ffb9bd68ebdb3b8d00ef5a79bbe8167a3281cace upstream. + +Show kprobes blacklist addresses under same condition of +showing kallsyms addresses. + +Since there are several name conflict for local symbols, +kprobe blacklist needs to show each addresses so that +user can identify where is on blacklist by comparing +with kallsyms. + +Signed-off-by: Masami Hiramatsu +Cc: Ananth N Mavinakayanahalli +Cc: Anil S Keshavamurthy +Cc: Arnd Bergmann +Cc: David Howells +Cc: David S . Miller +Cc: Heiko Carstens +Cc: Jon Medhurst +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Thomas Richter +Cc: Tobin C . Harding +Cc: Will Deacon +Cc: acme@kernel.org +Cc: akpm@linux-foundation.org +Cc: brueckner@linux.vnet.ibm.com +Cc: linux-arch@vger.kernel.org +Cc: rostedt@goodmis.org +Cc: schwidefsky@de.ibm.com +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/lkml/152491893217.9916.14760965896164273464.stgit@devbox +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/kprobes.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -2428,8 +2428,16 @@ static int kprobe_blacklist_seq_show(str + struct kprobe_blacklist_entry *ent = + list_entry(v, struct kprobe_blacklist_entry, list); + +- seq_printf(m, "0x%px-0x%px\t%ps\n", (void *)ent->start_addr, +- (void *)ent->end_addr, (void *)ent->start_addr); ++ /* ++ * If /proc/kallsyms is not showing kernel address, we won't ++ * show them here either. ++ */ ++ if (!kallsyms_show_value()) ++ seq_printf(m, "0x%px-0x%px\t%ps\n", NULL, NULL, ++ (void *)ent->start_addr); ++ else ++ seq_printf(m, "0x%px-0x%px\t%ps\n", (void *)ent->start_addr, ++ (void *)ent->end_addr, (void *)ent->start_addr); + return 0; + } + diff --git a/queue-4.18/mips-always-use-march-arch-not-arch-shortcuts.patch b/queue-4.18/mips-always-use-march-arch-not-arch-shortcuts.patch new file mode 100644 index 00000000000..6fcd670b80c --- /dev/null +++ b/queue-4.18/mips-always-use-march-arch-not-arch-shortcuts.patch @@ -0,0 +1,119 @@ +From 344ebf09949c31bcb8818d8458b65add29f1d67b Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Mon, 18 Jun 2018 17:37:59 -0700 +Subject: MIPS: Always use -march=, not - shortcuts + +From: Paul Burton + +commit 344ebf09949c31bcb8818d8458b65add29f1d67b upstream. + +The VDSO Makefile filters CFLAGS to select a subset which it uses whilst +building the VDSO ELF. One of the flags it allows through is the -march= +flag that selects the architecture/ISA to target. + +Unfortunately in cases where CONFIG_CPU_MIPS32_R{1,2}=y and the +toolchain defaults to building for MIPS64, the main MIPS Makefile ends +up using the short-form - flags in cflags-y. This is because the +calls to cc-option always fail to use the long-form -march= flag +due to the lack of an -mabi= flag in KBUILD_CFLAGS at the point +where the cc-option function is executed. The resulting GCC invocation +is something like: + + $ mips64-linux-gcc -Werror -march=mips32r2 -c -x c /dev/null -o tmp + cc1: error: '-march=mips32r2' is not compatible with the selected ABI + +These short-form - flags are dropped by the VDSO Makefile's +filtering, and so we attempt to build the VDSO without specifying any +architecture. This results in an attempt to build the VDSO using +whatever the compiler's default architecture is, regardless of whether +that is suitable for the kernel configuration. + +One encountered build failure resulting from this mismatch is a +rejection of the sync instruction if the kernel is configured for a +MIPS32 or MIPS64 r1 or r2 target but the toolchain defaults to an older +architecture revision such as MIPS1 which did not include the sync +instruction: + + CC arch/mips/vdso/gettimeofday.o + /tmp/ccGQKoOj.s: Assembler messages: + /tmp/ccGQKoOj.s:273: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:329: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:520: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:714: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:1009: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:1066: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:1114: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:1279: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:1334: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:1374: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:1459: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:1514: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:1814: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:2002: Error: opcode not supported on this processor: mips1 (mips1) `sync' + /tmp/ccGQKoOj.s:2066: Error: opcode not supported on this processor: mips1 (mips1) `sync' + make[2]: *** [scripts/Makefile.build:318: arch/mips/vdso/gettimeofday.o] Error 1 + make[1]: *** [scripts/Makefile.build:558: arch/mips/vdso] Error 2 + make[1]: *** Waiting for unfinished jobs.... + +This can be reproduced for example by attempting to build +pistachio_defconfig using Arnd's GCC 8.1.0 mips64 toolchain from +kernel.org: + + https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/8.1.0/x86_64-gcc-8.1.0-nolibc-mips64-linux.tar.xz + +Resolve this problem by using the long-form -march= in all cases, +which makes it through the arch/mips/vdso/Makefile's filtering & is thus +consistently used to build both the kernel proper & the VDSO. + +The use of cc-option to prefer the long-form & fall back to the +short-form flags makes no sense since the short-form is just an +abbreviation for the also-supported long-form in all GCC versions that +we support building with. This means there is no case in which we have +to use the short-form - flags, so we can simply remove them. + +The manual redefinition of _MIPS_ISA is removed naturally along with the +use of the short-form flags that it accompanied, and whilst here we +remove the separate assembler ISA selection. I suspect that both of +these were only required due to the mips32 vs mips2 mismatch that was +introduced by commit 59b3e8e9aac6 ("[MIPS] Makefile crapectomy.") and +fixed but not cleaned up by commit 9200c0b2a07c ("[MIPS] Fix Makefile +bugs for MIPS32/MIPS64 R1 and R2."). + +I've marked this for backport as far as v4.4 where the MIPS VDSO was +introduced. In earlier kernels there should be no ill effect to using +the short-form flags. + +Signed-off-by: Paul Burton +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: stable@vger.kernel.org # v4.4+ +Reviewed-by: James Hogan +Patchwork: https://patchwork.linux-mips.org/patch/19579/ +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/Makefile | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +--- a/arch/mips/Makefile ++++ b/arch/mips/Makefile +@@ -155,15 +155,11 @@ cflags-$(CONFIG_CPU_R4300) += -march=r43 + cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap + cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap + cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap +-cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ +- -Wa,-mips32 -Wa,--trap +-cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ +- -Wa,-mips32r2 -Wa,--trap ++cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap ++cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,--trap + cflags-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,--trap -modd-spreg +-cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips64 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \ +- -Wa,-mips64 -Wa,--trap +-cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \ +- -Wa,-mips64r2 -Wa,--trap ++cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap ++cflags-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,--trap + cflags-$(CONFIG_CPU_MIPS64_R6) += -march=mips64r6 -Wa,--trap + cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap + cflags-$(CONFIG_CPU_R5432) += $(call cc-option,-march=r5400,-march=r5000) \ diff --git a/queue-4.18/mips-change-definition-of-cpu_relax-for-loongson-3.patch b/queue-4.18/mips-change-definition-of-cpu_relax-for-loongson-3.patch new file mode 100644 index 00000000000..1037e60939e --- /dev/null +++ b/queue-4.18/mips-change-definition-of-cpu_relax-for-loongson-3.patch @@ -0,0 +1,85 @@ +From a30718868915fbb991a9ae9e45594b059f28e9ae Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Fri, 13 Jul 2018 15:37:57 +0800 +Subject: MIPS: Change definition of cpu_relax() for Loongson-3 + +From: Huacai Chen + +commit a30718868915fbb991a9ae9e45594b059f28e9ae upstream. + +Linux expects that if a CPU modifies a memory location, then that +modification will eventually become visible to other CPUs in the system. + +Loongson 3 CPUs include a Store Fill Buffer (SFB) which sits between a +core & its L1 data cache, queueing memory accesses & allowing for faster +forwarding of data from pending stores to younger loads from the core. +Unfortunately the SFB prioritizes loads such that a continuous stream of +loads may cause a pending write to be buffered indefinitely. This is +problematic if we end up with 2 CPUs which each perform a store that the +other polls for - one or both CPUs may end up with their stores buffered +in the SFB, never reaching cache due to the continuous reads from the +poll loop. Such a deadlock condition has been observed whilst running +qspinlock code. + +This patch changes the definition of cpu_relax() to smp_mb() for +Loongson-3, forcing a flush of the SFB on SMP systems which will cause +any pending writes to make it as far as the L1 caches where they will +become visible to other CPUs. If the kernel is not compiled for SMP +support, this will expand to a barrier() as before. + +This workaround matches that currently implemented for ARM when +CONFIG_ARM_ERRATA_754327=y, which was introduced by commit 534be1d5a2da +("ARM: 6194/1: change definition of cpu_relax() for ARM11MPCore"). + +Although the workaround is only required when the Loongson 3 SFB +functionality is enabled, and we only began explicitly enabling that +functionality in v4.7 with commit 1e820da3c9af ("MIPS: Loongson-3: +Introduce CONFIG_LOONGSON3_ENHANCEMENT"), existing or future firmware +may enable the SFB which means we may need the workaround backported to +earlier kernels too. + +[paul.burton@mips.com: + - Reword commit message & comment. + - Limit stable backport to v3.15+ where we support Loongson 3 CPUs.] + +Signed-off-by: Huacai Chen +Signed-off-by: Paul Burton +References: 534be1d5a2da ("ARM: 6194/1: change definition of cpu_relax() for ARM11MPCore") +References: 1e820da3c9af ("MIPS: Loongson-3: Introduce CONFIG_LOONGSON3_ENHANCEMENT") +Patchwork: https://patchwork.linux-mips.org/patch/19830/ +Cc: Ralf Baechle +Cc: James Hogan +Cc: linux-mips@linux-mips.org +Cc: Fuxin Zhang +Cc: Zhangjin Wu +Cc: Huacai Chen +Cc: stable@vger.kernel.org # v3.15+ +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/include/asm/processor.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/arch/mips/include/asm/processor.h ++++ b/arch/mips/include/asm/processor.h +@@ -386,7 +386,20 @@ unsigned long get_wchan(struct task_stru + #define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29]) + #define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status) + ++#ifdef CONFIG_CPU_LOONGSON3 ++/* ++ * Loongson-3's SFB (Store-Fill-Buffer) may buffer writes indefinitely when a ++ * tight read loop is executed, because reads take priority over writes & the ++ * hardware (incorrectly) doesn't ensure that writes will eventually occur. ++ * ++ * Since spin loops of any kind should have a cpu_relax() in them, force an SFB ++ * flush from cpu_relax() such that any pending writes will become visible as ++ * expected. ++ */ ++#define cpu_relax() smp_mb() ++#else + #define cpu_relax() barrier() ++#endif + + /* + * Return_address is a replacement for __builtin_return_address(count) diff --git a/queue-4.18/mips-correct-the-64-bit-dsp-accumulator-register-size.patch b/queue-4.18/mips-correct-the-64-bit-dsp-accumulator-register-size.patch new file mode 100644 index 00000000000..3e388685fec --- /dev/null +++ b/queue-4.18/mips-correct-the-64-bit-dsp-accumulator-register-size.patch @@ -0,0 +1,71 @@ +From f5958b4cf4fc38ed4583ab83fb7c4cd1ab05f47b Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Tue, 15 May 2018 23:33:26 +0100 +Subject: MIPS: Correct the 64-bit DSP accumulator register size + +From: Maciej W. Rozycki + +commit f5958b4cf4fc38ed4583ab83fb7c4cd1ab05f47b upstream. + +Use the `unsigned long' rather than `__u32' type for DSP accumulator +registers, like with the regular MIPS multiply/divide accumulator and +general-purpose registers, as all are 64-bit in 64-bit implementations +and using a 32-bit data type leads to contents truncation on context +saving. + +Update `arch_ptrace' and `compat_arch_ptrace' accordingly, removing +casts that are similarly not used with multiply/divide accumulator or +general-purpose register accesses. + +Signed-off-by: Maciej W. Rozycki +Signed-off-by: Paul Burton +Fixes: e50c0a8fa60d ("Support the MIPS32 / MIPS64 DSP ASE.") +Patchwork: https://patchwork.linux-mips.org/patch/19329/ +Cc: Alexander Viro +Cc: James Hogan +Cc: Ralf Baechle +Cc: linux-fsdevel@vger.kernel.org +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Cc: stable@vger.kernel.org # 2.6.15+ +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/include/asm/processor.h | 2 +- + arch/mips/kernel/ptrace.c | 2 +- + arch/mips/kernel/ptrace32.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/mips/include/asm/processor.h ++++ b/arch/mips/include/asm/processor.h +@@ -141,7 +141,7 @@ struct mips_fpu_struct { + + #define NUM_DSP_REGS 6 + +-typedef __u32 dspreg_t; ++typedef unsigned long dspreg_t; + + struct mips_dsp_state { + dspreg_t dspr[NUM_DSP_REGS]; +--- a/arch/mips/kernel/ptrace.c ++++ b/arch/mips/kernel/ptrace.c +@@ -856,7 +856,7 @@ long arch_ptrace(struct task_struct *chi + goto out; + } + dregs = __get_dsp_regs(child); +- tmp = (unsigned long) (dregs[addr - DSP_BASE]); ++ tmp = dregs[addr - DSP_BASE]; + break; + } + case DSP_CONTROL: +--- a/arch/mips/kernel/ptrace32.c ++++ b/arch/mips/kernel/ptrace32.c +@@ -142,7 +142,7 @@ long compat_arch_ptrace(struct task_stru + goto out; + } + dregs = __get_dsp_regs(child); +- tmp = (unsigned long) (dregs[addr - DSP_BASE]); ++ tmp = dregs[addr - DSP_BASE]; + break; + } + case DSP_CONTROL: diff --git a/queue-4.18/mips-lib-provide-mips64r6-__multi3-for-gcc-7.patch b/queue-4.18/mips-lib-provide-mips64r6-__multi3-for-gcc-7.patch new file mode 100644 index 00000000000..a514e54cfba --- /dev/null +++ b/queue-4.18/mips-lib-provide-mips64r6-__multi3-for-gcc-7.patch @@ -0,0 +1,62 @@ +From 690d9163bf4b8563a2682e619f938e6a0443947f Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Tue, 21 Aug 2018 12:12:59 -0700 +Subject: MIPS: lib: Provide MIPS64r6 __multi3() for GCC < 7 + +From: Paul Burton + +commit 690d9163bf4b8563a2682e619f938e6a0443947f upstream. + +Some versions of GCC suboptimally generate calls to the __multi3() +intrinsic for MIPS64r6 builds, resulting in link failures due to the +missing function: + + LD vmlinux.o + MODPOST vmlinux.o + kernel/bpf/verifier.o: In function `kmalloc_array': + include/linux/slab.h:631: undefined reference to `__multi3' + fs/select.o: In function `kmalloc_array': + include/linux/slab.h:631: undefined reference to `__multi3' + ... + +We already have a workaround for this in which we provide the +instrinsic, but we do so selectively for GCC 7 only. Unfortunately the +issue occurs with older GCC versions too - it has been observed with +both GCC 5.4.0 & GCC 6.4.0. + +MIPSr6 support was introduced in GCC 5, so all major GCC versions prior +to GCC 8 are affected and we extend our workaround accordingly to all +MIPS64r6 builds using GCC versions older than GCC 8. + +Signed-off-by: Paul Burton +Reported-by: Vladimir Kondratiev +Fixes: ebabcf17bcd7 ("MIPS: Implement __multi3 for GCC7 MIPS64r6 builds") +Patchwork: https://patchwork.linux-mips.org/patch/20297/ +Cc: James Hogan +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: stable@vger.kernel.org # 4.15+ +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/lib/multi3.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/mips/lib/multi3.c ++++ b/arch/mips/lib/multi3.c +@@ -4,12 +4,12 @@ + #include "libgcc.h" + + /* +- * GCC 7 suboptimally generates __multi3 calls for mips64r6, so for that +- * specific case only we'll implement it here. ++ * GCC 7 & older can suboptimally generate __multi3 calls for mips64r6, so for ++ * that specific case only we implement that intrinsic here. + * + * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981 + */ +-#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ == 7) ++#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ < 8) + + /* multiply 64-bit values, low 64-bits returned */ + static inline long long notrace dmulu(long long a, long long b) diff --git a/queue-4.18/mips-memset.s-fix-byte_fixup-for-mipsr6.patch b/queue-4.18/mips-memset.s-fix-byte_fixup-for-mipsr6.patch new file mode 100644 index 00000000000..2474a43ff55 --- /dev/null +++ b/queue-4.18/mips-memset.s-fix-byte_fixup-for-mipsr6.patch @@ -0,0 +1,125 @@ +From b1c03f1ef48d36ff28afb06e8f0c1233ef072f1d Mon Sep 17 00:00:00 2001 +From: Matt Redfearn +Date: Wed, 23 May 2018 14:39:58 +0100 +Subject: MIPS: memset.S: Fix byte_fixup for MIPSr6 + +From: Matt Redfearn + +commit b1c03f1ef48d36ff28afb06e8f0c1233ef072f1d upstream. + +The __clear_user function is defined to return the number of bytes that +could not be cleared. From the underlying memset / bzero implementation +this means setting register a2 to that number on return. Currently if a +page fault is triggered within the MIPSr6 version of setting of initial +unaligned bytes, the value loaded into a2 on return is meaningless. + +During the MIPSr6 version of the initial unaligned bytes block, register +a2 contains the number of bytes to be set beyond the initial unaligned +bytes. The t0 register is initally set to the number of unaligned bytes +- STORSIZE, effectively a negative version of the number of unaligned +bytes. This is then incremented before each byte is saved. + +The label .Lbyte_fixup\@ is jumped to on page fault. Currently the value +in a2 is incorrectly replaced by 0 - t0 + 1, effectively the number of +unaligned bytes remaining. This leads to the failures being reported by +the following test code: + +static int __init test_clear_user(void) +{ + int j, k; + + pr_info("\n\n\nTesting clear_user\n"); + for (j = 0; j < 512; j++) { + if ((k = clear_user(NULL+3, j)) != j) { + pr_err("clear_user (NULL %d) returned %d\n", j, k); + } + } + return 0; +} +late_initcall(test_clear_user); + +Which reports: +[ 3.965439] Testing clear_user +[ 3.973169] clear_user (NULL 8) returned 6 +[ 3.976782] clear_user (NULL 9) returned 6 +[ 3.980390] clear_user (NULL 10) returned 6 +[ 3.984052] clear_user (NULL 11) returned 6 +[ 3.987524] clear_user (NULL 12) returned 6 + +Fix this by subtracting t0 from a2 (rather than $0), effectivey giving: +unset_bytes = (#bytes - (#unaligned bytes)) - (-#unaligned bytes remaining + 1) + 1 + a2 = a2 - t0 + 1 + +This fixes the value returned from __clear user when the number of bytes +to set is > LONGSIZE and the address is invalid and unaligned. + +Unfortunately, this breaks the fixup handling for unaligned bytes after +the final long, where register a2 still contains the number of bytes +remaining to be set and the t0 register is to 0 - the number of +unaligned bytes remaining. + +Because t0 is now is now subtracted from a2 rather than 0, the number of +bytes unset is reported incorrectly: + +static int __init test_clear_user(void) +{ + char *test; + int j, k; + + pr_info("\n\n\nTesting clear_user\n"); + test = vmalloc(PAGE_SIZE); + + for (j = 256; j < 512; j++) { + if ((k = clear_user(test + PAGE_SIZE - 254, j)) != j - 254) { + pr_err("clear_user (%px %d) returned %d\n", + test + PAGE_SIZE - 254, j, k); + } + } + return 0; +} +late_initcall(test_clear_user); + +[ 3.976775] clear_user (c00000000000df02 256) returned 4 +[ 3.981957] clear_user (c00000000000df02 257) returned 6 +[ 3.986425] clear_user (c00000000000df02 258) returned 8 +[ 3.990850] clear_user (c00000000000df02 259) returned 10 +[ 3.995332] clear_user (c00000000000df02 260) returned 12 +[ 3.999815] clear_user (c00000000000df02 261) returned 14 + +Fix this by ensuring that a2 is set to 0 during the set of final +unaligned bytes. + +Signed-off-by: Matt Redfearn +Signed-off-by: Paul Burton +Fixes: 8c56208aff77 ("MIPS: lib: memset: Add MIPS R6 support") +Patchwork: https://patchwork.linux-mips.org/patch/19338/ +Cc: James Hogan +Cc: Ralf Baechle +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Cc: stable@vger.kernel.org # v4.0+ +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/lib/memset.S | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/mips/lib/memset.S ++++ b/arch/mips/lib/memset.S +@@ -195,6 +195,7 @@ + #endif + #else + PTR_SUBU t0, $0, a2 ++ move a2, zero /* No remaining longs */ + PTR_ADDIU t0, 1 + STORE_BYTE(0) + STORE_BYTE(1) +@@ -231,7 +232,7 @@ + + #ifdef CONFIG_CPU_MIPSR6 + .Lbyte_fixup\@: +- PTR_SUBU a2, $0, t0 ++ PTR_SUBU a2, t0 + jr ra + PTR_ADDIU a2, 1 + #endif /* CONFIG_CPU_MIPSR6 */ diff --git a/queue-4.18/mtd-rawnand-fsmc-stop-using-chip-read_buf.patch b/queue-4.18/mtd-rawnand-fsmc-stop-using-chip-read_buf.patch new file mode 100644 index 00000000000..f0b8150c3b4 --- /dev/null +++ b/queue-4.18/mtd-rawnand-fsmc-stop-using-chip-read_buf.patch @@ -0,0 +1,35 @@ +From 79e1ca37cc0c056f224cc1dd4a301b9dc2f94167 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Wed, 18 Jul 2018 10:28:14 +0200 +Subject: mtd: rawnand: fsmc: Stop using chip->read_buf() + +From: Boris Brezillon + +commit 79e1ca37cc0c056f224cc1dd4a301b9dc2f94167 upstream. + +chip->read_buf is left unassigned since commit 4da712e70294 ("mtd: nand: +fsmc: use ->exec_op()"), leading to a NULL pointer dereference when it's +called from fsmc_read_page_hwecc(). Fix that by using the appropriate +helper to read data out of the NAND. + +Fixes: 4da712e70294 ("mtd: nand: fsmc: use ->exec_op()") +Cc: +Signed-off-by: Boris Brezillon +Signed-off-by: Miquel Raynal +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/nand/raw/fsmc_nand.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mtd/nand/raw/fsmc_nand.c ++++ b/drivers/mtd/nand/raw/fsmc_nand.c +@@ -740,7 +740,7 @@ static int fsmc_read_page_hwecc(struct m + for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) { + nand_read_page_op(chip, page, s * eccsize, NULL, 0); + chip->ecc.hwctl(mtd, NAND_ECC_READ); +- chip->read_buf(mtd, p, eccsize); ++ nand_read_data_op(chip, p, eccsize, false); + + for (j = 0; j < eccbytes;) { + struct mtd_oob_region oobregion; diff --git a/queue-4.18/mtd-rawnand-hynix-use-exec_op-in-hynix_nand_reg_write_op.patch b/queue-4.18/mtd-rawnand-hynix-use-exec_op-in-hynix_nand_reg_write_op.patch new file mode 100644 index 00000000000..d9fc66a2417 --- /dev/null +++ b/queue-4.18/mtd-rawnand-hynix-use-exec_op-in-hynix_nand_reg_write_op.patch @@ -0,0 +1,42 @@ +From 20366e19e28f9954b25580c020d7a4e0db6055c4 Mon Sep 17 00:00:00 2001 +From: Boris Brezillon +Date: Wed, 4 Jul 2018 16:08:58 +0200 +Subject: mtd: rawnand: hynix: Use ->exec_op() in hynix_nand_reg_write_op() + +From: Boris Brezillon + +commit 20366e19e28f9954b25580c020d7a4e0db6055c4 upstream. + +Modern NAND controller drivers implement ->exec_op() instead of +->cmdfunc(), make sure we don't end up with a NULL pointer dereference +when hynix_nand_reg_write_op() is called. + +Fixes: 8878b126df76 ("mtd: nand: add ->exec_op() implementation") +Cc: +Signed-off-by: Boris Brezillon +Signed-off-by: Miquel Raynal +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/nand/raw/nand_hynix.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/mtd/nand/raw/nand_hynix.c ++++ b/drivers/mtd/nand/raw/nand_hynix.c +@@ -100,6 +100,16 @@ static int hynix_nand_reg_write_op(struc + struct mtd_info *mtd = nand_to_mtd(chip); + u16 column = ((u16)addr << 8) | addr; + ++ if (chip->exec_op) { ++ struct nand_op_instr instrs[] = { ++ NAND_OP_ADDR(1, &addr, 0), ++ NAND_OP_8BIT_DATA_OUT(1, &val, 0), ++ }; ++ struct nand_operation op = NAND_OPERATION(instrs); ++ ++ return nand_exec_op(chip, &op); ++ } ++ + chip->cmdfunc(mtd, NAND_CMD_NONE, column, -1); + chip->write_byte(mtd, val); + diff --git a/queue-4.18/mtd-rawnand-marvell-add-suspend-and-resume-hooks.patch b/queue-4.18/mtd-rawnand-marvell-add-suspend-and-resume-hooks.patch new file mode 100644 index 00000000000..63e177ed495 --- /dev/null +++ b/queue-4.18/mtd-rawnand-marvell-add-suspend-and-resume-hooks.patch @@ -0,0 +1,146 @@ +From bd9c3f9b3c00da322b5e784e820533f1598f690a Mon Sep 17 00:00:00 2001 +From: Daniel Mack +Date: Sun, 8 Jul 2018 02:10:06 +0200 +Subject: mtd: rawnand: marvell: add suspend and resume hooks + +From: Daniel Mack + +commit bd9c3f9b3c00da322b5e784e820533f1598f690a upstream. + +This patch restores the suspend and resume hooks that the old driver used +to have. Apart from stopping and starting the clocks, the resume callback +also nullifies the selected_chip pointer, so the next command that is issued +will re-select the chip and thereby restore the timing registers. + +Factor out some code from marvell_nfc_init() into a new function +marvell_nfc_reset() and also call it at resume time to reset some registers +that don't retain their contents during low-power mode. + +Without this patch, a PXA3xx based system would cough up an error similar to +the one below after resume. + +[ 44.660162] marvell-nfc 43100000.nand-controller: Timeout waiting for RB signal +[ 44.671492] ubi0 error: ubi_io_write: error -110 while writing 2048 bytes to PEB 102:38912, written 0 bytes +[ 44.682887] CPU: 0 PID: 1417 Comm: remote-control Not tainted 4.18.0-rc2+ #344 +[ 44.691197] Hardware name: Marvell PXA3xx (Device Tree Support) +[ 44.697111] Backtrace: +[ 44.699593] [] (dump_backtrace) from [] (show_stack+0x18/0x1c) +[ 44.708931] r7:00000800 r6:00009800 r5:00000066 r4:c6139000 +[ 44.715833] [] (show_stack) from [] (dump_stack+0x20/0x28) +[ 44.724206] [] (dump_stack) from [] (ubi_io_write+0x3d4/0x630) +[ 44.732925] [] (ubi_io_write) from [] (ubi_eba_write_leb+0x690/0x6fc) +... + +Fixes: 02f26ecf8c77 ("mtd: nand: add reworked Marvell NAND controller driver") +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Mack +Signed-off-by: Miquel Raynal +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/nand/raw/marvell_nand.c | 73 ++++++++++++++++++++++++++++++------ + 1 file changed, 62 insertions(+), 11 deletions(-) + +--- a/drivers/mtd/nand/raw/marvell_nand.c ++++ b/drivers/mtd/nand/raw/marvell_nand.c +@@ -2677,6 +2677,21 @@ static int marvell_nfc_init_dma(struct m + return 0; + } + ++static void marvell_nfc_reset(struct marvell_nfc *nfc) ++{ ++ /* ++ * ECC operations and interruptions are only enabled when specifically ++ * needed. ECC shall not be activated in the early stages (fails probe). ++ * Arbiter flag, even if marked as "reserved", must be set (empirical). ++ * SPARE_EN bit must always be set or ECC bytes will not be at the same ++ * offset in the read page and this will fail the protection. ++ */ ++ writel_relaxed(NDCR_ALL_INT | NDCR_ND_ARB_EN | NDCR_SPARE_EN | ++ NDCR_RD_ID_CNT(NFCV1_READID_LEN), nfc->regs + NDCR); ++ writel_relaxed(0xFFFFFFFF, nfc->regs + NDSR); ++ writel_relaxed(0, nfc->regs + NDECCCTRL); ++} ++ + static int marvell_nfc_init(struct marvell_nfc *nfc) + { + struct device_node *np = nfc->dev->of_node; +@@ -2715,17 +2730,7 @@ static int marvell_nfc_init(struct marve + if (!nfc->caps->is_nfcv2) + marvell_nfc_init_dma(nfc); + +- /* +- * ECC operations and interruptions are only enabled when specifically +- * needed. ECC shall not be activated in the early stages (fails probe). +- * Arbiter flag, even if marked as "reserved", must be set (empirical). +- * SPARE_EN bit must always be set or ECC bytes will not be at the same +- * offset in the read page and this will fail the protection. +- */ +- writel_relaxed(NDCR_ALL_INT | NDCR_ND_ARB_EN | NDCR_SPARE_EN | +- NDCR_RD_ID_CNT(NFCV1_READID_LEN), nfc->regs + NDCR); +- writel_relaxed(0xFFFFFFFF, nfc->regs + NDSR); +- writel_relaxed(0, nfc->regs + NDECCCTRL); ++ marvell_nfc_reset(nfc); + + return 0; + } +@@ -2840,6 +2845,51 @@ static int marvell_nfc_remove(struct pla + return 0; + } + ++static int __maybe_unused marvell_nfc_suspend(struct device *dev) ++{ ++ struct marvell_nfc *nfc = dev_get_drvdata(dev); ++ struct marvell_nand_chip *chip; ++ ++ list_for_each_entry(chip, &nfc->chips, node) ++ marvell_nfc_wait_ndrun(&chip->chip); ++ ++ clk_disable_unprepare(nfc->reg_clk); ++ clk_disable_unprepare(nfc->core_clk); ++ ++ return 0; ++} ++ ++static int __maybe_unused marvell_nfc_resume(struct device *dev) ++{ ++ struct marvell_nfc *nfc = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = clk_prepare_enable(nfc->core_clk); ++ if (ret < 0) ++ return ret; ++ ++ if (!IS_ERR(nfc->reg_clk)) { ++ ret = clk_prepare_enable(nfc->reg_clk); ++ if (ret < 0) ++ return ret; ++ } ++ ++ /* ++ * Reset nfc->selected_chip so the next command will cause the timing ++ * registers to be restored in marvell_nfc_select_chip(). ++ */ ++ nfc->selected_chip = NULL; ++ ++ /* Reset registers that have lost their contents */ ++ marvell_nfc_reset(nfc); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops marvell_nfc_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(marvell_nfc_suspend, marvell_nfc_resume) ++}; ++ + static const struct marvell_nfc_caps marvell_armada_8k_nfc_caps = { + .max_cs_nb = 4, + .max_rb_nb = 2, +@@ -2924,6 +2974,7 @@ static struct platform_driver marvell_nf + .driver = { + .name = "marvell-nfc", + .of_match_table = marvell_nfc_of_ids, ++ .pm = &marvell_nfc_pm_ops, + }, + .id_table = marvell_nfc_platform_ids, + .probe = marvell_nfc_probe, diff --git a/queue-4.18/mtd-rawnand-qcom-wait-for-desc-completion-in-all-bam-channels.patch b/queue-4.18/mtd-rawnand-qcom-wait-for-desc-completion-in-all-bam-channels.patch new file mode 100644 index 00000000000..8c5e71a7e90 --- /dev/null +++ b/queue-4.18/mtd-rawnand-qcom-wait-for-desc-completion-in-all-bam-channels.patch @@ -0,0 +1,146 @@ +From 6f20070d51a20e489ef117603210264c6bcde8a5 Mon Sep 17 00:00:00 2001 +From: Abhishek Sahu +Date: Wed, 20 Jun 2018 12:57:33 +0530 +Subject: mtd: rawnand: qcom: wait for desc completion in all BAM channels + +From: Abhishek Sahu + +commit 6f20070d51a20e489ef117603210264c6bcde8a5 upstream. + +The BAM has 3 channels - tx, rx and command. command channel +is used for register read/writes, tx channel for data writes +and rx channel for data reads. Currently, the driver assumes the +transfer completion once it gets all the command descriptors +completed. Sometimes, there is race condition between data channel +(tx/rx) and command channel completion. In these cases, +the data present in buffer is not valid during small window +between command descriptor completion and data descriptor +completion. + +This patch generates NAND transfer completion when both +(Data and Command) DMA channels have completed all its DMA +descriptors. It assigns completion callback in last +DMA descriptors of that channel and wait for completion. + +Fixes: 8d6b6d7e135e ("mtd: nand: qcom: support for command descriptor formation") +Cc: stable@vger.kernel.org +Signed-off-by: Abhishek Sahu +Signed-off-by: Miquel Raynal +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/nand/raw/qcom_nandc.c | 53 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 52 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/nand/raw/qcom_nandc.c ++++ b/drivers/mtd/nand/raw/qcom_nandc.c +@@ -213,6 +213,8 @@ nandc_set_reg(nandc, NAND_READ_LOCATION_ + #define QPIC_PER_CW_CMD_SGL 32 + #define QPIC_PER_CW_DATA_SGL 8 + ++#define QPIC_NAND_COMPLETION_TIMEOUT msecs_to_jiffies(2000) ++ + /* + * Flags used in DMA descriptor preparation helper functions + * (i.e. read_reg_dma/write_reg_dma/read_data_dma/write_data_dma) +@@ -245,6 +247,11 @@ nandc_set_reg(nandc, NAND_READ_LOCATION_ + * @tx_sgl_start - start index in data sgl for tx. + * @rx_sgl_pos - current index in data sgl for rx. + * @rx_sgl_start - start index in data sgl for rx. ++ * @wait_second_completion - wait for second DMA desc completion before making ++ * the NAND transfer completion. ++ * @txn_done - completion for NAND transfer. ++ * @last_data_desc - last DMA desc in data channel (tx/rx). ++ * @last_cmd_desc - last DMA desc in command channel. + */ + struct bam_transaction { + struct bam_cmd_element *bam_ce; +@@ -258,6 +265,10 @@ struct bam_transaction { + u32 tx_sgl_start; + u32 rx_sgl_pos; + u32 rx_sgl_start; ++ bool wait_second_completion; ++ struct completion txn_done; ++ struct dma_async_tx_descriptor *last_data_desc; ++ struct dma_async_tx_descriptor *last_cmd_desc; + }; + + /* +@@ -504,6 +515,8 @@ alloc_bam_transaction(struct qcom_nand_c + + bam_txn->data_sgl = bam_txn_buf; + ++ init_completion(&bam_txn->txn_done); ++ + return bam_txn; + } + +@@ -523,11 +536,33 @@ static void clear_bam_transaction(struct + bam_txn->tx_sgl_start = 0; + bam_txn->rx_sgl_pos = 0; + bam_txn->rx_sgl_start = 0; ++ bam_txn->last_data_desc = NULL; ++ bam_txn->wait_second_completion = false; + + sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage * + QPIC_PER_CW_CMD_SGL); + sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage * + QPIC_PER_CW_DATA_SGL); ++ ++ reinit_completion(&bam_txn->txn_done); ++} ++ ++/* Callback for DMA descriptor completion */ ++static void qpic_bam_dma_done(void *data) ++{ ++ struct bam_transaction *bam_txn = data; ++ ++ /* ++ * In case of data transfer with NAND, 2 callbacks will be generated. ++ * One for command channel and another one for data channel. ++ * If current transaction has data descriptors ++ * (i.e. wait_second_completion is true), then set this to false ++ * and wait for second DMA descriptor completion. ++ */ ++ if (bam_txn->wait_second_completion) ++ bam_txn->wait_second_completion = false; ++ else ++ complete(&bam_txn->txn_done); + } + + static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip) +@@ -756,6 +791,12 @@ static int prepare_bam_async_desc(struct + + desc->dma_desc = dma_desc; + ++ /* update last data/command descriptor */ ++ if (chan == nandc->cmd_chan) ++ bam_txn->last_cmd_desc = dma_desc; ++ else ++ bam_txn->last_data_desc = dma_desc; ++ + list_add_tail(&desc->node, &nandc->desc_list); + + return 0; +@@ -1273,10 +1314,20 @@ static int submit_descs(struct qcom_nand + cookie = dmaengine_submit(desc->dma_desc); + + if (nandc->props->is_bam) { ++ bam_txn->last_cmd_desc->callback = qpic_bam_dma_done; ++ bam_txn->last_cmd_desc->callback_param = bam_txn; ++ if (bam_txn->last_data_desc) { ++ bam_txn->last_data_desc->callback = qpic_bam_dma_done; ++ bam_txn->last_data_desc->callback_param = bam_txn; ++ bam_txn->wait_second_completion = true; ++ } ++ + dma_async_issue_pending(nandc->tx_chan); + dma_async_issue_pending(nandc->rx_chan); ++ dma_async_issue_pending(nandc->cmd_chan); + +- if (dma_sync_wait(nandc->cmd_chan, cookie) != DMA_COMPLETE) ++ if (!wait_for_completion_timeout(&bam_txn->txn_done, ++ QPIC_NAND_COMPLETION_TIMEOUT)) + return -ETIMEDOUT; + } else { + if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE) diff --git a/queue-4.18/pm-clk-signedness-bug-in-of_pm_clk_add_clks.patch b/queue-4.18/pm-clk-signedness-bug-in-of_pm_clk_add_clks.patch new file mode 100644 index 00000000000..2d6c810cfc1 --- /dev/null +++ b/queue-4.18/pm-clk-signedness-bug-in-of_pm_clk_add_clks.patch @@ -0,0 +1,33 @@ +From 5e2e2f9f76e157063a656351728703cb02b068f1 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 23 Aug 2018 16:59:25 +0300 +Subject: PM / clk: signedness bug in of_pm_clk_add_clks() + +From: Dan Carpenter + +commit 5e2e2f9f76e157063a656351728703cb02b068f1 upstream. + +"count" needs to be signed for the error handling to work. I made "i" +signed as well so they match. + +Fixes: 02113ba93ea4 (PM / clk: Add support for obtaining clocks from device-tree) +Cc: 4.6+ # 4.6+ +Signed-off-by: Dan Carpenter +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/power/clock_ops.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/base/power/clock_ops.c ++++ b/drivers/base/power/clock_ops.c +@@ -185,7 +185,7 @@ EXPORT_SYMBOL_GPL(of_pm_clk_add_clk); + int of_pm_clk_add_clks(struct device *dev) + { + struct clk **clks; +- unsigned int i, count; ++ int i, count; + int ret; + + if (!dev || !dev->of_node) diff --git a/queue-4.18/power-generic-adc-battery-check-for-duplicate-properties-copied-from-iio-channels.patch b/queue-4.18/power-generic-adc-battery-check-for-duplicate-properties-copied-from-iio-channels.patch new file mode 100644 index 00000000000..a2203bd0e4f --- /dev/null +++ b/queue-4.18/power-generic-adc-battery-check-for-duplicate-properties-copied-from-iio-channels.patch @@ -0,0 +1,60 @@ +From a427503edaaed9b75ed9746a654cece7e93e60a8 Mon Sep 17 00:00:00 2001 +From: "H. Nikolaus Schaller" +Date: Tue, 26 Jun 2018 15:28:30 +0200 +Subject: power: generic-adc-battery: check for duplicate properties copied from iio channels + +From: H. Nikolaus Schaller + +commit a427503edaaed9b75ed9746a654cece7e93e60a8 upstream. + +If an iio channel defines a basic property, there are duplicate entries +in /sys/class/power/*/uevent. + +So add a check to avoid duplicates. Since all channels may be duplicates, +we have to modify the related error check. + +Signed-off-by: H. Nikolaus Schaller +Cc: stable@vger.kernel.org +Fixes: e60fea794e6e ("power: battery: Generic battery driver using IIO") +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/supply/generic-adc-battery.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/power/supply/generic-adc-battery.c ++++ b/drivers/power/supply/generic-adc-battery.c +@@ -244,6 +244,7 @@ static int gab_probe(struct platform_dev + int ret = 0; + int chan; + int index = ARRAY_SIZE(gab_props); ++ bool any = false; + + adc_bat = devm_kzalloc(&pdev->dev, sizeof(*adc_bat), GFP_KERNEL); + if (!adc_bat) { +@@ -290,12 +291,22 @@ static int gab_probe(struct platform_dev + adc_bat->channel[chan] = NULL; + } else { + /* copying properties for supported channels only */ +- psy_desc->properties[index++] = gab_dyn_props[chan]; ++ int index2; ++ ++ for (index2 = 0; index2 < index; index2++) { ++ if (psy_desc->properties[index2] == ++ gab_dyn_props[chan]) ++ break; /* already known */ ++ } ++ if (index2 == index) /* really new */ ++ psy_desc->properties[index++] = ++ gab_dyn_props[chan]; ++ any = true; + } + } + + /* none of the channels are supported so let's bail out */ +- if (index == ARRAY_SIZE(gab_props)) { ++ if (!any) { + ret = -ENODEV; + goto second_mem_fail; + } diff --git a/queue-4.18/power-generic-adc-battery-fix-out-of-bounds-write-when-copying-channel-properties.patch b/queue-4.18/power-generic-adc-battery-fix-out-of-bounds-write-when-copying-channel-properties.patch new file mode 100644 index 00000000000..886d20623ed --- /dev/null +++ b/queue-4.18/power-generic-adc-battery-fix-out-of-bounds-write-when-copying-channel-properties.patch @@ -0,0 +1,99 @@ +From 932d47448c3caa0fa99e84d7f5bc302aa286efd8 Mon Sep 17 00:00:00 2001 +From: "H. Nikolaus Schaller" +Date: Tue, 26 Jun 2018 15:28:29 +0200 +Subject: power: generic-adc-battery: fix out-of-bounds write when copying channel properties + +From: H. Nikolaus Schaller + +commit 932d47448c3caa0fa99e84d7f5bc302aa286efd8 upstream. + +We did have sporadic problems in the pinctrl framework during boot +where a pin group name unexpectedly became NULL leading to a NULL +dereference in strcmp. + +Detailled analysis of the failing cases did reveal that there were +two devm allocated objects close to each other. The second one was +the affected group_desc in pinmux and the first one was the +psy_desc->properties buffer of the gab driver. + +Review of the gab code showed that the address calculation for +one memcpy() is wrong. It does + + properties + sizeof(type) * index + +but C is defined to do the index multiplication already for +pointer + integer additions. Hence the factor was applied twice +and the memcpy() does write outside of the properties buffer. +Sometimes it happened to be the pinctrl and triggered the strcmp(NULL). + +Anyways, it is overkill to use a memcpy() here instead of a simple +assignment, which is easier to read and has less risk for wrong +address calculations. So we change code to a simple assignment. + +If we initialize the index to the first free location, we can even +remove the local variable 'properties'. + +This bug seems to exist right from the beginning in 3.7-rc1 in + +commit e60fea794e6e ("power: battery: Generic battery driver using IIO") + +Signed-off-by: H. Nikolaus Schaller +Cc: stable@vger.kernel.org +Fixes: e60fea794e6e ("power: battery: Generic battery driver using IIO") +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/power/supply/generic-adc-battery.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +--- a/drivers/power/supply/generic-adc-battery.c ++++ b/drivers/power/supply/generic-adc-battery.c +@@ -241,10 +241,9 @@ static int gab_probe(struct platform_dev + struct power_supply_desc *psy_desc; + struct power_supply_config psy_cfg = {}; + struct gab_platform_data *pdata = pdev->dev.platform_data; +- enum power_supply_property *properties; + int ret = 0; + int chan; +- int index = 0; ++ int index = ARRAY_SIZE(gab_props); + + adc_bat = devm_kzalloc(&pdev->dev, sizeof(*adc_bat), GFP_KERNEL); + if (!adc_bat) { +@@ -278,8 +277,6 @@ static int gab_probe(struct platform_dev + } + + memcpy(psy_desc->properties, gab_props, sizeof(gab_props)); +- properties = (enum power_supply_property *) +- ((char *)psy_desc->properties + sizeof(gab_props)); + + /* + * getting channel from iio and copying the battery properties +@@ -293,15 +290,12 @@ static int gab_probe(struct platform_dev + adc_bat->channel[chan] = NULL; + } else { + /* copying properties for supported channels only */ +- memcpy(properties + sizeof(*(psy_desc->properties)) * index, +- &gab_dyn_props[chan], +- sizeof(gab_dyn_props[chan])); +- index++; ++ psy_desc->properties[index++] = gab_dyn_props[chan]; + } + } + + /* none of the channels are supported so let's bail out */ +- if (index == 0) { ++ if (index == ARRAY_SIZE(gab_props)) { + ret = -ENODEV; + goto second_mem_fail; + } +@@ -312,7 +306,7 @@ static int gab_probe(struct platform_dev + * as come channels may be not be supported by the device.So + * we need to take care of that. + */ +- psy_desc->num_properties = ARRAY_SIZE(gab_props) + index; ++ psy_desc->num_properties = index; + + adc_bat->psy = power_supply_register(&pdev->dev, psy_desc, &psy_cfg); + if (IS_ERR(adc_bat->psy)) { diff --git a/queue-4.18/s390-fix-br_r1_trampoline-for-machines-without-exrl.patch b/queue-4.18/s390-fix-br_r1_trampoline-for-machines-without-exrl.patch new file mode 100644 index 00000000000..3716cb4a517 --- /dev/null +++ b/queue-4.18/s390-fix-br_r1_trampoline-for-machines-without-exrl.patch @@ -0,0 +1,35 @@ +From 26f843848bae973817b3587780ce6b7b0200d3e4 Mon Sep 17 00:00:00 2001 +From: Martin Schwidefsky +Date: Mon, 6 Aug 2018 14:26:39 +0200 +Subject: s390: fix br_r1_trampoline for machines without exrl + +From: Martin Schwidefsky + +commit 26f843848bae973817b3587780ce6b7b0200d3e4 upstream. + +For machines without the exrl instruction the BFP jit generates +code that uses an "br %r1" instruction located in the lowcore page. +Unfortunately there is a cut & paste error that puts an additional +"larl %r1,.+14" instruction in the code that clobbers the branch +target address in %r1. Remove the larl instruction. + +Cc: # v4.17+ +Fixes: de5cb6eb51 ("s390: use expoline thunks in the BPF JIT") +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/net/bpf_jit_comp.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/arch/s390/net/bpf_jit_comp.c ++++ b/arch/s390/net/bpf_jit_comp.c +@@ -485,8 +485,6 @@ static void bpf_jit_epilogue(struct bpf_ + /* br %r1 */ + _EMIT2(0x07f1); + } else { +- /* larl %r1,.+14 */ +- EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14); + /* ex 0,S390_lowcore.br_r1_tampoline */ + EMIT4_DISP(0x44000000, REG_0, REG_0, + offsetof(struct lowcore, br_r1_trampoline)); diff --git a/queue-4.18/s390-lib-use-expoline-for-all-bcr-instructions.patch b/queue-4.18/s390-lib-use-expoline-for-all-bcr-instructions.patch new file mode 100644 index 00000000000..e981a3c974c --- /dev/null +++ b/queue-4.18/s390-lib-use-expoline-for-all-bcr-instructions.patch @@ -0,0 +1,99 @@ +From 5eda25b10297684c1f46a14199ec00210f3c346e Mon Sep 17 00:00:00 2001 +From: Martin Schwidefsky +Date: Mon, 6 Aug 2018 13:49:47 +0200 +Subject: s390/lib: use expoline for all bcr instructions + +From: Martin Schwidefsky + +commit 5eda25b10297684c1f46a14199ec00210f3c346e upstream. + +The memove, memset, memcpy, __memset16, __memset32 and __memset64 +function have an additional indirect return branch in form of a +"bzr" instruction. These need to use expolines as well. + +Cc: # v4.17+ +Fixes: 97489e0663 ("s390/lib: use expoline for indirect branches") +Reviewed-by: Heiko Carstens +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/lib/mem.S | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +--- a/arch/s390/lib/mem.S ++++ b/arch/s390/lib/mem.S +@@ -17,7 +17,7 @@ + ENTRY(memmove) + ltgr %r4,%r4 + lgr %r1,%r2 +- bzr %r14 ++ jz .Lmemmove_exit + aghi %r4,-1 + clgr %r2,%r3 + jnh .Lmemmove_forward +@@ -36,6 +36,7 @@ ENTRY(memmove) + .Lmemmove_forward_remainder: + larl %r5,.Lmemmove_mvc + ex %r4,0(%r5) ++.Lmemmove_exit: + BR_EX %r14 + .Lmemmove_reverse: + ic %r0,0(%r4,%r3) +@@ -65,7 +66,7 @@ EXPORT_SYMBOL(memmove) + */ + ENTRY(memset) + ltgr %r4,%r4 +- bzr %r14 ++ jz .Lmemset_exit + ltgr %r3,%r3 + jnz .Lmemset_fill + aghi %r4,-1 +@@ -80,6 +81,7 @@ ENTRY(memset) + .Lmemset_clear_remainder: + larl %r3,.Lmemset_xc + ex %r4,0(%r3) ++.Lmemset_exit: + BR_EX %r14 + .Lmemset_fill: + cghi %r4,1 +@@ -115,7 +117,7 @@ EXPORT_SYMBOL(memset) + */ + ENTRY(memcpy) + ltgr %r4,%r4 +- bzr %r14 ++ jz .Lmemcpy_exit + aghi %r4,-1 + srlg %r5,%r4,8 + ltgr %r5,%r5 +@@ -124,6 +126,7 @@ ENTRY(memcpy) + .Lmemcpy_remainder: + larl %r5,.Lmemcpy_mvc + ex %r4,0(%r5) ++.Lmemcpy_exit: + BR_EX %r14 + .Lmemcpy_loop: + mvc 0(256,%r1),0(%r3) +@@ -145,9 +148,9 @@ EXPORT_SYMBOL(memcpy) + .macro __MEMSET bits,bytes,insn + ENTRY(__memset\bits) + ltgr %r4,%r4 +- bzr %r14 ++ jz .L__memset_exit\bits + cghi %r4,\bytes +- je .L__memset_exit\bits ++ je .L__memset_store\bits + aghi %r4,-(\bytes+1) + srlg %r5,%r4,8 + ltgr %r5,%r5 +@@ -163,8 +166,9 @@ ENTRY(__memset\bits) + larl %r5,.L__memset_mvc\bits + ex %r4,0(%r5) + BR_EX %r14 +-.L__memset_exit\bits: ++.L__memset_store\bits: + \insn %r3,0(%r2) ++.L__memset_exit\bits: + BR_EX %r14 + .L__memset_mvc\bits: + mvc \bytes(1,%r1),0(%r1) diff --git a/queue-4.18/s390-mm-fix-addressing-exception-after-suspend-resume.patch b/queue-4.18/s390-mm-fix-addressing-exception-after-suspend-resume.patch new file mode 100644 index 00000000000..ac819d11ccf --- /dev/null +++ b/queue-4.18/s390-mm-fix-addressing-exception-after-suspend-resume.patch @@ -0,0 +1,40 @@ +From 37a366face294facb9c9d9fdd9f5b64a27456cbd Mon Sep 17 00:00:00 2001 +From: Gerald Schaefer +Date: Tue, 7 Aug 2018 18:57:11 +0200 +Subject: s390/mm: fix addressing exception after suspend/resume + +From: Gerald Schaefer + +commit 37a366face294facb9c9d9fdd9f5b64a27456cbd upstream. + +Commit c9b5ad546e7d "s390/mm: tag normal pages vs pages used in page tables" +accidentally changed the logic in arch_set_page_states(), which is used by +the suspend/resume code. set_page_stable(page, order) was changed to +set_page_stable_dat(page, 0). After this, only the first page of higher order +pages will be set to stable, and a write to one of the unstable pages will +result in an addressing exception. + +Fix this by using "order" again, instead of "0". + +Fixes: c9b5ad546e7d ("s390/mm: tag normal pages vs pages used in page tables") +Cc: stable@vger.kernel.org # 4.14+ +Reviewed-by: Heiko Carstens +Signed-off-by: Gerald Schaefer +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/mm/page-states.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/s390/mm/page-states.c ++++ b/arch/s390/mm/page-states.c +@@ -271,7 +271,7 @@ void arch_set_page_states(int make_stabl + list_for_each(l, &zone->free_area[order].free_list[t]) { + page = list_entry(l, struct page, lru); + if (make_stable) +- set_page_stable_dat(page, 0); ++ set_page_stable_dat(page, order); + else + set_page_unused(page, order); + } diff --git a/queue-4.18/s390-numa-move-initial-setup-of-node_to_cpumask_map.patch b/queue-4.18/s390-numa-move-initial-setup-of-node_to_cpumask_map.patch new file mode 100644 index 00000000000..2b667a3097a --- /dev/null +++ b/queue-4.18/s390-numa-move-initial-setup-of-node_to_cpumask_map.patch @@ -0,0 +1,60 @@ +From fb7d7518b0d65955f91c7b875c36eae7694c69bd Mon Sep 17 00:00:00 2001 +From: Martin Schwidefsky +Date: Tue, 31 Jul 2018 16:14:18 +0200 +Subject: s390/numa: move initial setup of node_to_cpumask_map + +From: Martin Schwidefsky + +commit fb7d7518b0d65955f91c7b875c36eae7694c69bd upstream. + +The numa_init_early initcall sets the node_to_cpumask_map[0] to the +full cpu_possible_mask. Unfortunately this early_initcall is too late, +the NUMA setup for numa=emu is done even earlier. The order of calls +is numa_setup() -> emu_update_cpu_topology(), then the early_initcalls(), +followed by sched_init_domains(). + +Starting with git commit 051f3ca02e46432c0965e8948f00c07d8a2f09c0 +"sched/topology: Introduce NUMA identity node sched domain" +the incorrect node_to_cpumask_map[0] really screws up the domain +setup and the kernel panics with the follow oops: + +Cc: # v4.15+ +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/numa/numa.c | 16 ++-------------- + 1 file changed, 2 insertions(+), 14 deletions(-) + +--- a/arch/s390/numa/numa.c ++++ b/arch/s390/numa/numa.c +@@ -134,6 +134,8 @@ void __init numa_setup(void) + { + pr_info("NUMA mode: %s\n", mode->name); + nodes_clear(node_possible_map); ++ /* Initially attach all possible CPUs to node 0. */ ++ cpumask_copy(&node_to_cpumask_map[0], cpu_possible_mask); + if (mode->setup) + mode->setup(); + numa_setup_memory(); +@@ -141,20 +143,6 @@ void __init numa_setup(void) + } + + /* +- * numa_init_early() - Initialization initcall +- * +- * This runs when only one CPU is online and before the first +- * topology update is called for by the scheduler. +- */ +-static int __init numa_init_early(void) +-{ +- /* Attach all possible CPUs to node 0 for now. */ +- cpumask_copy(&node_to_cpumask_map[0], cpu_possible_mask); +- return 0; +-} +-early_initcall(numa_init_early); +- +-/* + * numa_init_late() - Initialization initcall + * + * Register NUMA nodes. diff --git a/queue-4.18/s390-pci-fix-out-of-bounds-access-during-irq-setup.patch b/queue-4.18/s390-pci-fix-out-of-bounds-access-during-irq-setup.patch new file mode 100644 index 00000000000..702b45a86f7 --- /dev/null +++ b/queue-4.18/s390-pci-fix-out-of-bounds-access-during-irq-setup.patch @@ -0,0 +1,36 @@ +From 866f3576a72b2233a76dffb80290f8086dc49e17 Mon Sep 17 00:00:00 2001 +From: Sebastian Ott +Date: Mon, 13 Aug 2018 11:26:46 +0200 +Subject: s390/pci: fix out of bounds access during irq setup + +From: Sebastian Ott + +commit 866f3576a72b2233a76dffb80290f8086dc49e17 upstream. + +During interrupt setup we allocate interrupt vectors, walk the list of msi +descriptors, and fill in the message data. Requesting more interrupts than +supported on s390 can lead to an out of bounds access. + +When we restrict the number of interrupts we should also stop walking the +msi list after all supported interrupts are handled. + +Cc: stable@vger.kernel.org +Signed-off-by: Sebastian Ott +Signed-off-by: Heiko Carstens +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/pci/pci.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/s390/pci/pci.c ++++ b/arch/s390/pci/pci.c +@@ -421,6 +421,8 @@ int arch_setup_msi_irqs(struct pci_dev * + hwirq = 0; + for_each_pci_msi_entry(msi, pdev) { + rc = -EIO; ++ if (hwirq >= msi_vecs) ++ break; + irq = irq_alloc_desc(0); /* Alloc irq on node 0 */ + if (irq < 0) + return -ENOMEM; diff --git a/queue-4.18/s390-purgatory-add-missing-force-to-makefile-targets.patch b/queue-4.18/s390-purgatory-add-missing-force-to-makefile-targets.patch new file mode 100644 index 00000000000..12dc1cb2c36 --- /dev/null +++ b/queue-4.18/s390-purgatory-add-missing-force-to-makefile-targets.patch @@ -0,0 +1,43 @@ +From c315e69308c739a43c4ebc539bedbc1ac8d79854 Mon Sep 17 00:00:00 2001 +From: Philipp Rudo +Date: Tue, 26 Jun 2018 18:24:52 +0200 +Subject: s390/purgatory: Add missing FORCE to Makefile targets + +From: Philipp Rudo + +commit c315e69308c739a43c4ebc539bedbc1ac8d79854 upstream. + +Without FORCE make does not detect changes only made to the command line +options. So object files might not be re-built even when they should be. +Fix this by adding FORCE where it is missing. + +Fixes: 840798a1f5299 ("s390/kexec_file: Add purgatory") +Cc: # 4.17 +Signed-off-by: Philipp Rudo +Acked-by: Heiko Carstens +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/purgatory/Makefile | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/s390/purgatory/Makefile ++++ b/arch/s390/purgatory/Makefile +@@ -7,13 +7,13 @@ purgatory-y := head.o purgatory.o string + targets += $(purgatory-y) purgatory.ro kexec-purgatory.c + PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y)) + +-$(obj)/sha256.o: $(srctree)/lib/sha256.c ++$(obj)/sha256.o: $(srctree)/lib/sha256.c FORCE + $(call if_changed_rule,cc_o_c) + +-$(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S ++$(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S FORCE + $(call if_changed_rule,as_o_S) + +-$(obj)/string.o: $(srctree)/arch/s390/lib/string.c ++$(obj)/string.o: $(srctree)/arch/s390/lib/string.c FORCE + $(call if_changed_rule,cc_o_c) + + LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib diff --git a/queue-4.18/s390-purgatory-fix-crash-with-expoline-enabled.patch b/queue-4.18/s390-purgatory-fix-crash-with-expoline-enabled.patch new file mode 100644 index 00000000000..f81a4660403 --- /dev/null +++ b/queue-4.18/s390-purgatory-fix-crash-with-expoline-enabled.patch @@ -0,0 +1,45 @@ +From ad03b821fbc30395b72af438f5bb41676a5f891d Mon Sep 17 00:00:00 2001 +From: Philipp Rudo +Date: Tue, 26 Jun 2018 12:24:30 +0200 +Subject: s390/purgatory: Fix crash with expoline enabled + +From: Philipp Rudo + +commit ad03b821fbc30395b72af438f5bb41676a5f891d upstream. + +When the kernel is built with CONFIG_EXPOLINE=y and a compiler with +indirect branch mitigation enabled the purgatory crashes. The reason for +that is that the macros defined for expoline are used in mem.S. These +macros define new sections (.text.__s390x_indirect_*) which are marked +executable. Due to the missing linker script those sections are linked to +address 0, just as the .text section. In combination with the entry point +also being at address 0 this causes the purgatory load code +(kernel/kexec_file.c: kexec_purgatory_setup_sechdrs) to update the entry +point twice. Thus the old kernel jumps to some 'random' address causing the +crash. + +To fix this turn off expolines for the purgatory. There is no problem with +this in this case due to the fact that the purgatory only runs once and the +tlb is purged (diag 308) in the end. + +Fixes: 840798a1f5299 ("s390/kexec_file: Add purgatory") +Cc: # 4.17 +Signed-off-by: Philipp Rudo +Reviewed-by: Heiko Carstens +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/purgatory/Makefile | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/s390/purgatory/Makefile ++++ b/arch/s390/purgatory/Makefile +@@ -23,6 +23,7 @@ KBUILD_CFLAGS += -Wno-pointer-sign -Wno- + KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding + KBUILD_CFLAGS += -c -MD -Os -m64 -msoft-float + KBUILD_CFLAGS += $(call cc-option,-fno-PIE) ++KBUILD_AFLAGS := $(filter-out -DCC_USING_EXPOLINE,$(KBUILD_AFLAGS)) + + $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE + $(call if_changed,ld) diff --git a/queue-4.18/s390-qdio-reset-old-sbal_state-flags.patch b/queue-4.18/s390-qdio-reset-old-sbal_state-flags.patch new file mode 100644 index 00000000000..16eccd76a36 --- /dev/null +++ b/queue-4.18/s390-qdio-reset-old-sbal_state-flags.patch @@ -0,0 +1,66 @@ +From 64e03ff72623b8c2ea89ca3cb660094e019ed4ae Mon Sep 17 00:00:00 2001 +From: Julian Wiedmann +Date: Wed, 16 May 2018 09:37:25 +0200 +Subject: s390/qdio: reset old sbal_state flags + +From: Julian Wiedmann + +commit 64e03ff72623b8c2ea89ca3cb660094e019ed4ae upstream. + +When allocating a new AOB fails, handle_outbound() is still capable of +transmitting the selected buffer (just without async completion). + +But if a previous transfer on this queue slot used async completion, its +sbal_state flags field is still set to QDIO_OUTBUF_STATE_FLAG_PENDING. +So when the upper layer driver sees this stale flag, it expects an async +completion that never happens. + +Fix this by unconditionally clearing the flags field. + +Fixes: 104ea556ee7f ("qdio: support asynchronous delivery of storage blocks") +Cc: #v3.2+ +Signed-off-by: Julian Wiedmann +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/include/asm/qdio.h | 1 - + drivers/s390/cio/qdio_main.c | 5 ++--- + 2 files changed, 2 insertions(+), 4 deletions(-) + +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -262,7 +262,6 @@ struct qdio_outbuf_state { + void *user; + }; + +-#define QDIO_OUTBUF_STATE_FLAG_NONE 0x00 + #define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01 + + #define CHSC_AC1_INITIATE_INPUTQ 0x80 +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -631,21 +631,20 @@ static inline unsigned long qdio_aob_for + unsigned long phys_aob = 0; + + if (!q->use_cq) +- goto out; ++ return 0; + + if (!q->aobs[bufnr]) { + struct qaob *aob = qdio_allocate_aob(); + q->aobs[bufnr] = aob; + } + if (q->aobs[bufnr]) { +- q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE; + q->sbal_state[bufnr].aob = q->aobs[bufnr]; + q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user; + phys_aob = virt_to_phys(q->aobs[bufnr]); + WARN_ON_ONCE(phys_aob & 0xFF); + } + +-out: ++ q->sbal_state[bufnr].flags = 0; + return phys_aob; + } + diff --git a/queue-4.18/scsi-core-avoid-that-scsi-device-removal-through-sysfs-triggers-a-deadlock.patch b/queue-4.18/scsi-core-avoid-that-scsi-device-removal-through-sysfs-triggers-a-deadlock.patch new file mode 100644 index 00000000000..e9f5f21babb --- /dev/null +++ b/queue-4.18/scsi-core-avoid-that-scsi-device-removal-through-sysfs-triggers-a-deadlock.patch @@ -0,0 +1,164 @@ +From 0ee223b2e1f67cb2de9c0e3247c510d846e74d63 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Thu, 2 Aug 2018 10:51:41 -0700 +Subject: scsi: core: Avoid that SCSI device removal through sysfs triggers a deadlock + +From: Bart Van Assche + +commit 0ee223b2e1f67cb2de9c0e3247c510d846e74d63 upstream. + +A long time ago the unfortunate decision was taken to add a self-deletion +attribute to the sysfs SCSI device directory. That decision was unfortunate +because self-deletion is really tricky. We can't drop that attribute +because widely used user space software depends on it, namely the +rescan-scsi-bus.sh script. Hence this patch that avoids that writing into +that attribute triggers a deadlock. See also commit 7973cbd9fbd9 ("[PATCH] +add sysfs attributes to scan and delete scsi_devices"). + +This patch avoids that self-removal triggers the following deadlock: + +====================================================== +WARNING: possible circular locking dependency detected +4.18.0-rc2-dbg+ #5 Not tainted +------------------------------------------------------ +modprobe/6539 is trying to acquire lock: +000000008323c4cd (kn->count#202){++++}, at: kernfs_remove_by_name_ns+0x45/0x90 + +but task is already holding lock: +00000000a6ec2c69 (&shost->scan_mutex){+.+.}, at: scsi_remove_host+0x21/0x150 [scsi_mod] + +which lock already depends on the new lock. + +the existing dependency chain (in reverse order) is: + +-> #1 (&shost->scan_mutex){+.+.}: + __mutex_lock+0xfe/0xc70 + mutex_lock_nested+0x1b/0x20 + scsi_remove_device+0x26/0x40 [scsi_mod] + sdev_store_delete+0x27/0x30 [scsi_mod] + dev_attr_store+0x3e/0x50 + sysfs_kf_write+0x87/0xa0 + kernfs_fop_write+0x190/0x230 + __vfs_write+0xd2/0x3b0 + vfs_write+0x101/0x270 + ksys_write+0xab/0x120 + __x64_sys_write+0x43/0x50 + do_syscall_64+0x77/0x230 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +-> #0 (kn->count#202){++++}: + lock_acquire+0xd2/0x260 + __kernfs_remove+0x424/0x4a0 + kernfs_remove_by_name_ns+0x45/0x90 + remove_files.isra.1+0x3a/0x90 + sysfs_remove_group+0x5c/0xc0 + sysfs_remove_groups+0x39/0x60 + device_remove_attrs+0x82/0xb0 + device_del+0x251/0x580 + __scsi_remove_device+0x19f/0x1d0 [scsi_mod] + scsi_forget_host+0x37/0xb0 [scsi_mod] + scsi_remove_host+0x9b/0x150 [scsi_mod] + sdebug_driver_remove+0x4b/0x150 [scsi_debug] + device_release_driver_internal+0x241/0x360 + device_release_driver+0x12/0x20 + bus_remove_device+0x1bc/0x290 + device_del+0x259/0x580 + device_unregister+0x1a/0x70 + sdebug_remove_adapter+0x8b/0xf0 [scsi_debug] + scsi_debug_exit+0x76/0xe8 [scsi_debug] + __x64_sys_delete_module+0x1c1/0x280 + do_syscall_64+0x77/0x230 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +other info that might help us debug this: + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(&shost->scan_mutex); + lock(kn->count#202); + lock(&shost->scan_mutex); + lock(kn->count#202); + + *** DEADLOCK *** + +2 locks held by modprobe/6539: + #0: 00000000efaf9298 (&dev->mutex){....}, at: device_release_driver_internal+0x68/0x360 + #1: 00000000a6ec2c69 (&shost->scan_mutex){+.+.}, at: scsi_remove_host+0x21/0x150 [scsi_mod] + +stack backtrace: +CPU: 10 PID: 6539 Comm: modprobe Not tainted 4.18.0-rc2-dbg+ #5 +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014 +Call Trace: + dump_stack+0xa4/0xf5 + print_circular_bug.isra.34+0x213/0x221 + __lock_acquire+0x1a7e/0x1b50 + lock_acquire+0xd2/0x260 + __kernfs_remove+0x424/0x4a0 + kernfs_remove_by_name_ns+0x45/0x90 + remove_files.isra.1+0x3a/0x90 + sysfs_remove_group+0x5c/0xc0 + sysfs_remove_groups+0x39/0x60 + device_remove_attrs+0x82/0xb0 + device_del+0x251/0x580 + __scsi_remove_device+0x19f/0x1d0 [scsi_mod] + scsi_forget_host+0x37/0xb0 [scsi_mod] + scsi_remove_host+0x9b/0x150 [scsi_mod] + sdebug_driver_remove+0x4b/0x150 [scsi_debug] + device_release_driver_internal+0x241/0x360 + device_release_driver+0x12/0x20 + bus_remove_device+0x1bc/0x290 + device_del+0x259/0x580 + device_unregister+0x1a/0x70 + sdebug_remove_adapter+0x8b/0xf0 [scsi_debug] + scsi_debug_exit+0x76/0xe8 [scsi_debug] + __x64_sys_delete_module+0x1c1/0x280 + do_syscall_64+0x77/0x230 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +See also https://www.mail-archive.com/linux-scsi@vger.kernel.org/msg54525.html. + +Fixes: ac0ece9174ac ("scsi: use device_remove_file_self() instead of device_schedule_callback()") +Signed-off-by: Bart Van Assche +Cc: Greg Kroah-Hartman +Acked-by: Tejun Heo +Cc: Johannes Thumshirn +Cc: +Signed-off-by: Greg Kroah-Hartman + +Signed-off-by: Martin K. Petersen + +--- + drivers/scsi/scsi_sysfs.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -722,8 +722,24 @@ static ssize_t + sdev_store_delete(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) + { +- if (device_remove_file_self(dev, attr)) +- scsi_remove_device(to_scsi_device(dev)); ++ struct kernfs_node *kn; ++ ++ kn = sysfs_break_active_protection(&dev->kobj, &attr->attr); ++ WARN_ON_ONCE(!kn); ++ /* ++ * Concurrent writes into the "delete" sysfs attribute may trigger ++ * concurrent calls to device_remove_file() and scsi_remove_device(). ++ * device_remove_file() handles concurrent removal calls by ++ * serializing these and by ignoring the second and later removal ++ * attempts. Concurrent calls of scsi_remove_device() are ++ * serialized. The second and later calls of scsi_remove_device() are ++ * ignored because the first call of that function changes the device ++ * state into SDEV_DEL. ++ */ ++ device_remove_file(dev, attr); ++ scsi_remove_device(to_scsi_device(dev)); ++ if (kn) ++ sysfs_unbreak_active_protection(kn); + return count; + }; + static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete); diff --git a/queue-4.18/scsi-mpt3sas-fix-_transport_smp_handler-error-path.patch b/queue-4.18/scsi-mpt3sas-fix-_transport_smp_handler-error-path.patch new file mode 100644 index 00000000000..dd084b27ba9 --- /dev/null +++ b/queue-4.18/scsi-mpt3sas-fix-_transport_smp_handler-error-path.patch @@ -0,0 +1,52 @@ +From 91b7bdb2c0089cbbb817df6888ab1458c645184e Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Fri, 15 Jun 2018 14:41:58 -0700 +Subject: scsi: mpt3sas: Fix _transport_smp_handler() error path + +From: Bart Van Assche + +commit 91b7bdb2c0089cbbb817df6888ab1458c645184e upstream. + +This patch avoids that smatch complains about a double unlock on +ioc->transport_cmds.mutex. + +Fixes: 651a01364994 ("scsi: scsi_transport_sas: switch to bsg-lib for SMP passthrough") +Signed-off-by: Bart Van Assche +Cc: Christoph Hellwig +Cc: Sathya Prakash +Cc: Chaitra P B +Cc: Suganath Prabu Subramani +Cc: stable@vger.kernel.org +Reviewed-by: Christoph Hellwig +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/mpt3sas/mpt3sas_transport.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c +@@ -1936,12 +1936,12 @@ _transport_smp_handler(struct bsg_job *j + pr_info(MPT3SAS_FMT "%s: host reset in progress!\n", + __func__, ioc->name); + rc = -EFAULT; +- goto out; ++ goto job_done; + } + + rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex); + if (rc) +- goto out; ++ goto job_done; + + if (ioc->transport_cmds.status != MPT3_CMD_NOT_USED) { + pr_err(MPT3SAS_FMT "%s: transport_cmds in use\n", ioc->name, +@@ -2066,6 +2066,7 @@ _transport_smp_handler(struct bsg_job *j + out: + ioc->transport_cmds.status = MPT3_CMD_NOT_USED; + mutex_unlock(&ioc->transport_cmds.mutex); ++job_done: + bsg_job_done(job, rc, reslen); + } + diff --git a/queue-4.18/scsi-mpt3sas-fix-calltrace-observed-while-running-io-reset.patch b/queue-4.18/scsi-mpt3sas-fix-calltrace-observed-while-running-io-reset.patch new file mode 100644 index 00000000000..47f5022b73d --- /dev/null +++ b/queue-4.18/scsi-mpt3sas-fix-calltrace-observed-while-running-io-reset.patch @@ -0,0 +1,160 @@ +From e70183143cc472960bc60dfee1b7bbe1949feffb Mon Sep 17 00:00:00 2001 +From: Sreekanth Reddy +Date: Thu, 12 Jul 2018 12:53:29 -0400 +Subject: scsi: mpt3sas: Fix calltrace observed while running IO & reset + +From: Sreekanth Reddy + +commit e70183143cc472960bc60dfee1b7bbe1949feffb upstream. + +Below kernel BUG was observed while running IOs with host reset (issued +from application), + +mpt3sas_cm0: diag reset: SUCCESS +------------[ cut here ]------------ +WARNING: CPU: 12 PID: 4336 at drivers/scsi/mpt3sas/mpt3sas_base.c:3282 mpt3sas_base_clear_st+0x3d/0x40 [mpt3sas] +Modules linked in: macsec tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag binfmt_misc fuse xt_CHECKSUM ipt_MASQUERADE nf_nat_masquerade_ipv4 tun devlink ip6t_rpfilter ipt_REJECT nf_reject_ipv4 ip6t_REJECT nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter sunrpc vfat fat sb_edac intel_powerclamp coretemp intel_rapl iosf_mbi kvm_intel kvm irqbypass crc32_pclmul ghash_clmulni_intel aesni_intel lrw gf128mul glue_helper ablk_helper cryptd iTCO_wdt iTCO_vendor_support + dcdbas pcspkr joydev ipmi_ssif ses enclosure sg ipmi_devintf acpi_pad ipmi_msghandler acpi_power_meter mei_me lpc_ich wmi mei shpchp ip_tables xfs libcrc32c sd_mod crc_t10dif crct10dif_generic ata_generic pata_acpi uas usb_storage mgag200 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm ata_piix mpt3sas libata crct10dif_pclmul crct10dif_common tg3 crc32c_intel i2c_core raid_class ptp scsi_transport_sas pps_core dm_mirror dm_region_hash dm_log dm_mod +CPU: 12 PID: 4336 Comm: python Kdump: loaded Tainted: G W ------------ 3.10.0-875.el7.brdc.x86_64 #1 +Hardware name: Dell Inc. PowerEdge R820/0YWR73, BIOS 1.5.0 03/08/2013 +Call Trace: + [] dump_stack+0x19/0x1b + [] __warn+0xd8/0x100 + [] warn_slowpath_null+0x1d/0x20 + [] mpt3sas_base_clear_st+0x3d/0x40 [mpt3sas] + [] _scsih_flush_running_cmds+0x92/0xe0 [mpt3sas] + [] mpt3sas_scsih_reset_handler+0x43b/0xaf0 [mpt3sas] + [] ? vprintk_default+0x29/0x40 + [] ? printk+0x60/0x77 + [] ? _base_diag_reset+0x238/0x340 [mpt3sas] + [] mpt3sas_base_hard_reset_handler+0x1ad/0x420 [mpt3sas] + [] _ctl_ioctl_main.isra.12+0x11b9/0x1200 [mpt3sas] + [] ? xfs_file_aio_write+0x155/0x1b0 [xfs] + [] ? do_sync_write+0x93/0xe0 + [] _ctl_ioctl+0x1a/0x20 [mpt3sas] + [] do_vfs_ioctl+0x350/0x560 + [] ? __sb_end_write+0x31/0x60 + [] SyS_ioctl+0xa1/0xc0 + [] ? system_call_after_swapgs+0xa2/0x146 + [] system_call_fastpath+0x1c/0x21 + [] ? system_call_after_swapgs+0xae/0x146 +---[ end trace 5dac5b98d89aaa3c ]--- +------------[ cut here ]------------ +kernel BUG at block/blk-core.c:1476! +invalid opcode: 0000 [#1] SMP +Modules linked in: macsec tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag binfmt_misc fuse xt_CHECKSUM ipt_MASQUERADE nf_nat_masquerade_ipv4 tun devlink ip6t_rpfilter ipt_REJECT nf_reject_ipv4 ip6t_REJECT nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter sunrpc vfat fat sb_edac intel_powerclamp coretemp intel_rapl iosf_mbi kvm_intel kvm irqbypass crc32_pclmul ghash_clmulni_intel aesni_intel lrw gf128mul glue_helper ablk_helper cryptd iTCO_wdt iTCO_vendor_support + dcdbas pcspkr joydev ipmi_ssif ses enclosure sg ipmi_devintf acpi_pad ipmi_msghandler acpi_power_meter mei_me lpc_ich wmi mei shpchp ip_tables xfs libcrc32c sd_mod crc_t10dif crct10dif_generic ata_generic pata_acpi uas usb_storage mgag200 i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm ata_piix mpt3sas libata crct10dif_pclmul crct10dif_common tg3 crc32c_intel i2c_core raid_class ptp scsi_transport_sas pps_core dm_mirror dm_region_hash dm_log dm_mod +CPU: 12 PID: 4336 Comm: python Kdump: loaded Tainted: G W ------------ 3.10.0-875.el7.brdc.x86_64 #1 +Hardware name: Dell Inc. PowerEdge R820/0YWR73, BIOS 1.5.0 03/08/2013 +task: ffff903fc96e0fd0 ti: ffff903fb1eec000 task.ti: ffff903fb1eec000 +RIP: 0010:[] [] blk_requeue_request+0x90/0xa0 +RSP: 0018:ffff903c6b783dc0 EFLAGS: 00010087 +RAX: ffff903bb67026d0 RBX: ffff903b7d6a6140 RCX: dead000000000200 +RDX: ffff903bb67026d0 RSI: ffff903bb6702580 RDI: ffff903bb67026d0 +RBP: ffff903c6b783dd8 R08: ffff903bb67026d0 R09: ffffd97e80000000 +R10: ffff903c658bac00 R11: 0000000000000000 R12: ffff903bb6702580 +R13: ffff903fa9a292f0 R14: 0000000000000246 R15: 0000000000001057 +FS: 00007f7026f5b740(0000) GS:ffff903c6b780000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f298877c004 CR3: 00000000caf36000 CR4: 00000000000607e0 +Call Trace: + + [] __scsi_queue_insert+0xbf/0x110 + [] scsi_io_completion+0x5da/0x6a0 + [] scsi_finish_command+0xdc/0x140 + [] scsi_softirq_done+0x132/0x160 + [] blk_done_softirq+0x96/0xc0 + [] __do_softirq+0xf5/0x280 + [] call_softirq+0x1c/0x30 + [] do_softirq+0x65/0xa0 + [] irq_exit+0x105/0x110 + [] smp_apic_timer_interrupt+0x48/0x60 + [] apic_timer_interrupt+0x162/0x170 + + [] ? scsi_done+0x21/0x60 + [] ? delay_tsc+0x38/0x60 + [] __const_udelay+0x2d/0x30 + [] _base_handshake_req_reply_wait+0x8e/0x4a0 [mpt3sas] + [] _base_get_ioc_facts+0x123/0x590 [mpt3sas] + [] ? _base_diag_reset+0x238/0x340 [mpt3sas] + [] mpt3sas_base_hard_reset_handler+0x1f3/0x420 [mpt3sas] + [] _ctl_ioctl_main.isra.12+0x11b9/0x1200 [mpt3sas] + [] ? xfs_file_aio_write+0x155/0x1b0 [xfs] + [] ? do_sync_write+0x93/0xe0 + [] _ctl_ioctl+0x1a/0x20 [mpt3sas] + [] do_vfs_ioctl+0x350/0x560 + [] ? __sb_end_write+0x31/0x60 + [] SyS_ioctl+0xa1/0xc0 + [] ? system_call_after_swapgs+0xa2/0x146 + [] system_call_fastpath+0x1c/0x21 + [] ? system_call_after_swapgs+0xae/0x146 +Code: 83 c3 10 4c 89 e2 4c 89 ee e8 8d 21 04 00 48 8b 03 48 85 c0 75 e5 41 f6 44 24 4a 10 74 ad 4c 89 e6 4c 89 ef e8 b2 42 00 00 eb a0 <0f> 0b 0f 1f 40 00 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 +RIP [] blk_requeue_request+0x90/0xa0 + RSP + +As a part of host reset operation, driver will flushout all IOs outstanding +at driver level with "DID_RESET" result. To find which are all commands +outstanding at the driver level, driver loops with smid starting from one +to HBA queue depth and calls mpt3sas_scsih_scsi_lookup_get() to get scmd as +shown below + + for (smid = 1; smid <= ioc->scsiio_depth; smid++) { + scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid); + if (!scmd) + continue; + +But in mpt3sas_scsih_scsi_lookup_get() function, driver returns some scsi +cmnds which are not outstanding at the driver level (possibly request is +constructed at block layer since QUEUE_FLAG_QUIESCED is not set. Even if +driver uses scsi_block_requests and scsi_unblock_requests, issue still +persists as they will be just blocking further IO from scsi layer and not +from block layer) and these commands are flushed with DID_RESET host bytes +thus resulting into above kernel BUG. + +This issue got introduced by commit dbec4c9040ed ("scsi: mpt3sas: lockless +command submission"). + +To fix this issue, we have modified the mpt3sas_scsih_scsi_lookup_get() to +check for smid equals to zero (note: whenever any scsi cmnd is processing +at the driver level then smid for that scsi cmnd will be non-zero, always +it starts from one) before it returns the scmd pointer to the caller. If +smid is zero then this function returns scmd pointer as NULL and driver +won't flushout those scsi cmnds at driver level with DID_RESET host byte +thus this issue will not be observed. + +[mkp: amended with updated fix from Sreekanth] + +Signed-off-by: Sreekanth Reddy +Fixes: dbec4c9040ed ("scsi: mpt3sas: lockless command submission") +Cc: stable@vger.kernel.org # v4.16+ +Reviewed-by: Tomas Henzl +Reviewed-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 1 + + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -3284,6 +3284,7 @@ void mpt3sas_base_clear_st(struct MPT3SA + st->cb_idx = 0xFF; + st->direct_io = 0; + atomic_set(&ioc->chain_lookup[st->smid - 1].chain_offset, 0); ++ st->smid = 0; + } + + /** +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -1489,7 +1489,7 @@ mpt3sas_scsih_scsi_lookup_get(struct MPT + scmd = scsi_host_find_tag(ioc->shost, unique_tag); + if (scmd) { + st = scsi_cmd_priv(scmd); +- if (st->cb_idx == 0xFF) ++ if (st->cb_idx == 0xFF || st->smid == 0) + scmd = NULL; + } + } diff --git a/queue-4.18/scsi-sysfs-introduce-sysfs_-un-break_active_protection.patch b/queue-4.18/scsi-sysfs-introduce-sysfs_-un-break_active_protection.patch new file mode 100644 index 00000000000..fc594b347de --- /dev/null +++ b/queue-4.18/scsi-sysfs-introduce-sysfs_-un-break_active_protection.patch @@ -0,0 +1,107 @@ +From 2afc9166f79b8f6da5f347f48515215ceee4ae37 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Thu, 2 Aug 2018 10:51:40 -0700 +Subject: scsi: sysfs: Introduce sysfs_{un,}break_active_protection() + +From: Bart Van Assche + +commit 2afc9166f79b8f6da5f347f48515215ceee4ae37 upstream. + +Introduce these two functions and export them such that the next patch +can add calls to these functions from the SCSI core. + +Signed-off-by: Bart Van Assche +Acked-by: Tejun Heo +Acked-by: Greg Kroah-Hartman +Cc: +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + fs/sysfs/file.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + include/linux/sysfs.h | 14 ++++++++++++++ + 2 files changed, 58 insertions(+) + +--- a/fs/sysfs/file.c ++++ b/fs/sysfs/file.c +@@ -406,6 +406,50 @@ int sysfs_chmod_file(struct kobject *kob + EXPORT_SYMBOL_GPL(sysfs_chmod_file); + + /** ++ * sysfs_break_active_protection - break "active" protection ++ * @kobj: The kernel object @attr is associated with. ++ * @attr: The attribute to break the "active" protection for. ++ * ++ * With sysfs, just like kernfs, deletion of an attribute is postponed until ++ * all active .show() and .store() callbacks have finished unless this function ++ * is called. Hence this function is useful in methods that implement self ++ * deletion. ++ */ ++struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj, ++ const struct attribute *attr) ++{ ++ struct kernfs_node *kn; ++ ++ kobject_get(kobj); ++ kn = kernfs_find_and_get(kobj->sd, attr->name); ++ if (kn) ++ kernfs_break_active_protection(kn); ++ return kn; ++} ++EXPORT_SYMBOL_GPL(sysfs_break_active_protection); ++ ++/** ++ * sysfs_unbreak_active_protection - restore "active" protection ++ * @kn: Pointer returned by sysfs_break_active_protection(). ++ * ++ * Undo the effects of sysfs_break_active_protection(). Since this function ++ * calls kernfs_put() on the kernfs node that corresponds to the 'attr' ++ * argument passed to sysfs_break_active_protection() that attribute may have ++ * been removed between the sysfs_break_active_protection() and ++ * sysfs_unbreak_active_protection() calls, it is not safe to access @kn after ++ * this function has returned. ++ */ ++void sysfs_unbreak_active_protection(struct kernfs_node *kn) ++{ ++ struct kobject *kobj = kn->parent->priv; ++ ++ kernfs_unbreak_active_protection(kn); ++ kernfs_put(kn); ++ kobject_put(kobj); ++} ++EXPORT_SYMBOL_GPL(sysfs_unbreak_active_protection); ++ ++/** + * sysfs_remove_file_ns - remove an object attribute with a custom ns tag + * @kobj: object we're acting for + * @attr: attribute descriptor +--- a/include/linux/sysfs.h ++++ b/include/linux/sysfs.h +@@ -237,6 +237,9 @@ int __must_check sysfs_create_files(stru + const struct attribute **attr); + int __must_check sysfs_chmod_file(struct kobject *kobj, + const struct attribute *attr, umode_t mode); ++struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj, ++ const struct attribute *attr); ++void sysfs_unbreak_active_protection(struct kernfs_node *kn); + void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr, + const void *ns); + bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr); +@@ -350,6 +353,17 @@ static inline int sysfs_chmod_file(struc + return 0; + } + ++static inline struct kernfs_node * ++sysfs_break_active_protection(struct kobject *kobj, ++ const struct attribute *attr) ++{ ++ return NULL; ++} ++ ++static inline void sysfs_unbreak_active_protection(struct kernfs_node *kn) ++{ ++} ++ + static inline void sysfs_remove_file_ns(struct kobject *kobj, + const struct attribute *attr, + const void *ns) diff --git a/queue-4.18/series b/queue-4.18/series index 8915b8da3d2..6bdd58a13f8 100644 --- a/queue-4.18/series +++ b/queue-4.18/series @@ -84,4 +84,39 @@ x86-speculation-l1tf-increase-l1tf-memory-limit-for-nehalem.patch hwmon-nct6775-fix-potential-spectre-v1.patch x86-entry-64-wipe-kasan-stack-shadow-before-rewind_stack_do_exit.patch x86-allow-generating-user-space-headers-without-a-compiler.patch +s390-mm-fix-addressing-exception-after-suspend-resume.patch +s390-lib-use-expoline-for-all-bcr-instructions.patch +s390-fix-br_r1_trampoline-for-machines-without-exrl.patch +s390-qdio-reset-old-sbal_state-flags.patch +s390-numa-move-initial-setup-of-node_to_cpumask_map.patch +s390-pci-fix-out-of-bounds-access-during-irq-setup.patch +s390-purgatory-fix-crash-with-expoline-enabled.patch +s390-purgatory-add-missing-force-to-makefile-targets.patch +kprobes-show-blacklist-addresses-as-same-as-kallsyms-does.patch +kprobes-replace-p-with-other-pointer-types.patch +kprobes-arm-fix-p-uses-in-error-messages.patch +kprobes-make-list-and-blacklist-root-user-read-only.patch +mips-correct-the-64-bit-dsp-accumulator-register-size.patch +mips-memset.s-fix-byte_fixup-for-mipsr6.patch +mips-always-use-march-arch-not-arch-shortcuts.patch +mips-change-definition-of-cpu_relax-for-loongson-3.patch +mips-lib-provide-mips64r6-__multi3-for-gcc-7.patch +tpm-return-the-actual-size-when-receiving-an-unsupported-command.patch +tpm-separate-cmd_ready-go_idle-from-runtime_pm.patch +scsi-mpt3sas-fix-calltrace-observed-while-running-io-reset.patch +scsi-mpt3sas-fix-_transport_smp_handler-error-path.patch +scsi-sysfs-introduce-sysfs_-un-break_active_protection.patch +scsi-core-avoid-that-scsi-device-removal-through-sysfs-triggers-a-deadlock.patch +iscsi-target-fix-session-creation-failure-handling.patch +mtd-rawnand-hynix-use-exec_op-in-hynix_nand_reg_write_op.patch +mtd-rawnand-fsmc-stop-using-chip-read_buf.patch +mtd-rawnand-marvell-add-suspend-and-resume-hooks.patch +mtd-rawnand-qcom-wait-for-desc-completion-in-all-bam-channels.patch +clk-rockchip-fix-clk_i2sout-parent-selection-bits-on-rk3399.patch +clk-npcm7xx-fix-memory-allocation.patch +pm-clk-signedness-bug-in-of_pm_clk_add_clks.patch +power-generic-adc-battery-fix-out-of-bounds-write-when-copying-channel-properties.patch +power-generic-adc-battery-check-for-duplicate-properties-copied-from-iio-channels.patch +watchdog-mark-watchdog-touch-functions-as-notrace.patch +cdrom-fix-info-leak-oob-read-in-cdrom_ioctl_drive_status.patch x86-kvm-avoid-unused-variable-warning.patch diff --git a/queue-4.18/tpm-return-the-actual-size-when-receiving-an-unsupported-command.patch b/queue-4.18/tpm-return-the-actual-size-when-receiving-an-unsupported-command.patch new file mode 100644 index 00000000000..bf9c7f06eb6 --- /dev/null +++ b/queue-4.18/tpm-return-the-actual-size-when-receiving-an-unsupported-command.patch @@ -0,0 +1,34 @@ +From 36a11029b07ee30bdc4553274d0efea645ed9d91 Mon Sep 17 00:00:00 2001 +From: Ricardo Schwarzmeier +Date: Tue, 26 Jun 2018 17:31:45 +0200 +Subject: tpm: Return the actual size when receiving an unsupported command + +From: Ricardo Schwarzmeier + +commit 36a11029b07ee30bdc4553274d0efea645ed9d91 upstream. + +The userpace expects to read the number of bytes stated in the header. +Returning the size of the buffer instead would be unexpected. + +Cc: stable@vger.kernel.org +Fixes: 095531f891e6 ("tpm: return a TPM_RC_COMMAND_CODE response if command is not implemented") +Signed-off-by: Ricardo Schwarzmeier +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm-interface.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/char/tpm/tpm-interface.c ++++ b/drivers/char/tpm/tpm-interface.c +@@ -423,7 +423,7 @@ static ssize_t tpm_try_transmit(struct t + header->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS); + header->return_code = cpu_to_be32(TPM2_RC_COMMAND_CODE | + TSS2_RESMGR_TPM_RC_LAYER); +- return bufsiz; ++ return sizeof(*header); + } + + if (bufsiz > TPM_BUFSIZE) diff --git a/queue-4.18/tpm-separate-cmd_ready-go_idle-from-runtime_pm.patch b/queue-4.18/tpm-separate-cmd_ready-go_idle-from-runtime_pm.patch new file mode 100644 index 00000000000..20b5ad24dc3 --- /dev/null +++ b/queue-4.18/tpm-separate-cmd_ready-go_idle-from-runtime_pm.patch @@ -0,0 +1,435 @@ +From 627448e85c766587f6fdde1ea3886d6615081c77 Mon Sep 17 00:00:00 2001 +From: Tomas Winkler +Date: Thu, 28 Jun 2018 18:13:33 +0300 +Subject: tpm: separate cmd_ready/go_idle from runtime_pm + +From: Tomas Winkler + +commit 627448e85c766587f6fdde1ea3886d6615081c77 upstream. + +Fix tpm ptt initialization error: +tpm tpm0: A TPM error (378) occurred get tpm pcr allocation. + +We cannot use go_idle cmd_ready commands via runtime_pm handles +as with the introduction of localities this is no longer an optional +feature, while runtime pm can be not enabled. +Though cmd_ready/go_idle provides a power saving, it's also a part of +TPM2 protocol and should be called explicitly. +This patch exposes cmd_read/go_idle via tpm class ops and removes +runtime pm support as it is not used by any driver. + +When calling from nested context always use both flags: +TPM_TRANSMIT_UNLOCKED and TPM_TRANSMIT_RAW. Both are needed to resolve +tpm spaces and locality request recursive calls to tpm_transmit(). +TPM_TRANSMIT_RAW should never be used standalone as it will fail +on double locking. While TPM_TRANSMIT_UNLOCKED standalone should be +called from non-recursive locked contexts. + +New wrappers are added tpm_cmd_ready() and tpm_go_idle() to +streamline tpm_try_transmit code. + +tpm_crb no longer needs own power saving functions and can drop using +tpm_pm_suspend/resume. + +This patch cannot be really separated from the locality fix. +Fixes: 888d867df441 (tpm: cmd_ready command can be issued only after granting locality) + +Cc: stable@vger.kernel.org +Fixes: 888d867df441 (tpm: cmd_ready command can be issued only after granting locality) +Signed-off-by: Tomas Winkler +Tested-by: Jarkko Sakkinen +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm-interface.c | 51 +++++++++++++++---- + drivers/char/tpm/tpm.h | 12 +++- + drivers/char/tpm/tpm2-space.c | 16 +++--- + drivers/char/tpm/tpm_crb.c | 101 ++++++++++----------------------------- + include/linux/tpm.h | 2 + 5 files changed, 90 insertions(+), 92 deletions(-) + +--- a/drivers/char/tpm/tpm-interface.c ++++ b/drivers/char/tpm/tpm-interface.c +@@ -29,7 +29,6 @@ + #include + #include + #include +-#include + #include + + #include "tpm.h" +@@ -369,10 +368,13 @@ err_len: + return -EINVAL; + } + +-static int tpm_request_locality(struct tpm_chip *chip) ++static int tpm_request_locality(struct tpm_chip *chip, unsigned int flags) + { + int rc; + ++ if (flags & TPM_TRANSMIT_RAW) ++ return 0; ++ + if (!chip->ops->request_locality) + return 0; + +@@ -385,10 +387,13 @@ static int tpm_request_locality(struct t + return 0; + } + +-static void tpm_relinquish_locality(struct tpm_chip *chip) ++static void tpm_relinquish_locality(struct tpm_chip *chip, unsigned int flags) + { + int rc; + ++ if (flags & TPM_TRANSMIT_RAW) ++ return; ++ + if (!chip->ops->relinquish_locality) + return; + +@@ -399,6 +404,28 @@ static void tpm_relinquish_locality(stru + chip->locality = -1; + } + ++static int tpm_cmd_ready(struct tpm_chip *chip, unsigned int flags) ++{ ++ if (flags & TPM_TRANSMIT_RAW) ++ return 0; ++ ++ if (!chip->ops->cmd_ready) ++ return 0; ++ ++ return chip->ops->cmd_ready(chip); ++} ++ ++static int tpm_go_idle(struct tpm_chip *chip, unsigned int flags) ++{ ++ if (flags & TPM_TRANSMIT_RAW) ++ return 0; ++ ++ if (!chip->ops->go_idle) ++ return 0; ++ ++ return chip->ops->go_idle(chip); ++} ++ + static ssize_t tpm_try_transmit(struct tpm_chip *chip, + struct tpm_space *space, + u8 *buf, size_t bufsiz, +@@ -449,14 +476,15 @@ static ssize_t tpm_try_transmit(struct t + /* Store the decision as chip->locality will be changed. */ + need_locality = chip->locality == -1; + +- if (!(flags & TPM_TRANSMIT_RAW) && need_locality) { +- rc = tpm_request_locality(chip); ++ if (need_locality) { ++ rc = tpm_request_locality(chip, flags); + if (rc < 0) + goto out_no_locality; + } + +- if (chip->dev.parent) +- pm_runtime_get_sync(chip->dev.parent); ++ rc = tpm_cmd_ready(chip, flags); ++ if (rc) ++ goto out; + + rc = tpm2_prepare_space(chip, space, ordinal, buf); + if (rc) +@@ -516,13 +544,16 @@ out_recv: + } + + rc = tpm2_commit_space(chip, space, ordinal, buf, &len); ++ if (rc) ++ dev_err(&chip->dev, "tpm2_commit_space: error %d\n", rc); + + out: +- if (chip->dev.parent) +- pm_runtime_put_sync(chip->dev.parent); ++ rc = tpm_go_idle(chip, flags); ++ if (rc) ++ goto out; + + if (need_locality) +- tpm_relinquish_locality(chip); ++ tpm_relinquish_locality(chip, flags); + + out_no_locality: + if (chip->ops->clk_enable != NULL) +--- a/drivers/char/tpm/tpm.h ++++ b/drivers/char/tpm/tpm.h +@@ -511,9 +511,17 @@ extern const struct file_operations tpm_ + extern const struct file_operations tpmrm_fops; + extern struct idr dev_nums_idr; + ++/** ++ * enum tpm_transmit_flags ++ * ++ * @TPM_TRANSMIT_UNLOCKED: used to lock sequence of tpm_transmit calls. ++ * @TPM_TRANSMIT_RAW: prevent recursive calls into setup steps ++ * (go idle, locality,..). Always use with UNLOCKED ++ * as it will fail on double locking. ++ */ + enum tpm_transmit_flags { +- TPM_TRANSMIT_UNLOCKED = BIT(0), +- TPM_TRANSMIT_RAW = BIT(1), ++ TPM_TRANSMIT_UNLOCKED = BIT(0), ++ TPM_TRANSMIT_RAW = BIT(1), + }; + + ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, +--- a/drivers/char/tpm/tpm2-space.c ++++ b/drivers/char/tpm/tpm2-space.c +@@ -39,7 +39,8 @@ static void tpm2_flush_sessions(struct t + for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++) { + if (space->session_tbl[i]) + tpm2_flush_context_cmd(chip, space->session_tbl[i], +- TPM_TRANSMIT_UNLOCKED); ++ TPM_TRANSMIT_UNLOCKED | ++ TPM_TRANSMIT_RAW); + } + } + +@@ -84,7 +85,7 @@ static int tpm2_load_context(struct tpm_ + tpm_buf_append(&tbuf, &buf[*offset], body_size); + + rc = tpm_transmit_cmd(chip, NULL, tbuf.data, PAGE_SIZE, 4, +- TPM_TRANSMIT_UNLOCKED, NULL); ++ TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW, NULL); + if (rc < 0) { + dev_warn(&chip->dev, "%s: failed with a system error %d\n", + __func__, rc); +@@ -133,7 +134,7 @@ static int tpm2_save_context(struct tpm_ + tpm_buf_append_u32(&tbuf, handle); + + rc = tpm_transmit_cmd(chip, NULL, tbuf.data, PAGE_SIZE, 0, +- TPM_TRANSMIT_UNLOCKED, NULL); ++ TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW, NULL); + if (rc < 0) { + dev_warn(&chip->dev, "%s: failed with a system error %d\n", + __func__, rc); +@@ -170,7 +171,8 @@ static void tpm2_flush_space(struct tpm_ + for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++) + if (space->context_tbl[i] && ~space->context_tbl[i]) + tpm2_flush_context_cmd(chip, space->context_tbl[i], +- TPM_TRANSMIT_UNLOCKED); ++ TPM_TRANSMIT_UNLOCKED | ++ TPM_TRANSMIT_RAW); + + tpm2_flush_sessions(chip, space); + } +@@ -377,7 +379,8 @@ static int tpm2_map_response_header(stru + + return 0; + out_no_slots: +- tpm2_flush_context_cmd(chip, phandle, TPM_TRANSMIT_UNLOCKED); ++ tpm2_flush_context_cmd(chip, phandle, ++ TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW); + dev_warn(&chip->dev, "%s: out of slots for 0x%08X\n", __func__, + phandle); + return -ENOMEM; +@@ -465,7 +468,8 @@ static int tpm2_save_space(struct tpm_ch + return rc; + + tpm2_flush_context_cmd(chip, space->context_tbl[i], +- TPM_TRANSMIT_UNLOCKED); ++ TPM_TRANSMIT_UNLOCKED | ++ TPM_TRANSMIT_RAW); + space->context_tbl[i] = ~0; + } + +--- a/drivers/char/tpm/tpm_crb.c ++++ b/drivers/char/tpm/tpm_crb.c +@@ -132,7 +132,7 @@ static bool crb_wait_for_reg_32(u32 __io + } + + /** +- * crb_go_idle - request tpm crb device to go the idle state ++ * __crb_go_idle - request tpm crb device to go the idle state + * + * @dev: crb device + * @priv: crb private data +@@ -147,7 +147,7 @@ static bool crb_wait_for_reg_32(u32 __io + * + * Return: 0 always + */ +-static int crb_go_idle(struct device *dev, struct crb_priv *priv) ++static int __crb_go_idle(struct device *dev, struct crb_priv *priv) + { + if ((priv->sm == ACPI_TPM2_START_METHOD) || + (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || +@@ -163,11 +163,20 @@ static int crb_go_idle(struct device *de + dev_warn(dev, "goIdle timed out\n"); + return -ETIME; + } ++ + return 0; + } + ++static int crb_go_idle(struct tpm_chip *chip) ++{ ++ struct device *dev = &chip->dev; ++ struct crb_priv *priv = dev_get_drvdata(dev); ++ ++ return __crb_go_idle(dev, priv); ++} ++ + /** +- * crb_cmd_ready - request tpm crb device to enter ready state ++ * __crb_cmd_ready - request tpm crb device to enter ready state + * + * @dev: crb device + * @priv: crb private data +@@ -181,7 +190,7 @@ static int crb_go_idle(struct device *de + * + * Return: 0 on success -ETIME on timeout; + */ +-static int crb_cmd_ready(struct device *dev, struct crb_priv *priv) ++static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv) + { + if ((priv->sm == ACPI_TPM2_START_METHOD) || + (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || +@@ -200,6 +209,14 @@ static int crb_cmd_ready(struct device * + return 0; + } + ++static int crb_cmd_ready(struct tpm_chip *chip) ++{ ++ struct device *dev = &chip->dev; ++ struct crb_priv *priv = dev_get_drvdata(dev); ++ ++ return __crb_cmd_ready(dev, priv); ++} ++ + static int __crb_request_locality(struct device *dev, + struct crb_priv *priv, int loc) + { +@@ -401,6 +418,8 @@ static const struct tpm_class_ops tpm_cr + .send = crb_send, + .cancel = crb_cancel, + .req_canceled = crb_req_canceled, ++ .go_idle = crb_go_idle, ++ .cmd_ready = crb_cmd_ready, + .request_locality = crb_request_locality, + .relinquish_locality = crb_relinquish_locality, + .req_complete_mask = CRB_DRV_STS_COMPLETE, +@@ -520,7 +539,7 @@ static int crb_map_io(struct acpi_device + * PTT HW bug w/a: wake up the device to access + * possibly not retained registers. + */ +- ret = crb_cmd_ready(dev, priv); ++ ret = __crb_cmd_ready(dev, priv); + if (ret) + goto out_relinquish_locality; + +@@ -565,7 +584,7 @@ out: + if (!ret) + priv->cmd_size = cmd_size; + +- crb_go_idle(dev, priv); ++ __crb_go_idle(dev, priv); + + out_relinquish_locality: + +@@ -628,32 +647,7 @@ static int crb_acpi_add(struct acpi_devi + chip->acpi_dev_handle = device->handle; + chip->flags = TPM_CHIP_FLAG_TPM2; + +- rc = __crb_request_locality(dev, priv, 0); +- if (rc) +- return rc; +- +- rc = crb_cmd_ready(dev, priv); +- if (rc) +- goto out; +- +- pm_runtime_get_noresume(dev); +- pm_runtime_set_active(dev); +- pm_runtime_enable(dev); +- +- rc = tpm_chip_register(chip); +- if (rc) { +- crb_go_idle(dev, priv); +- pm_runtime_put_noidle(dev); +- pm_runtime_disable(dev); +- goto out; +- } +- +- pm_runtime_put_sync(dev); +- +-out: +- __crb_relinquish_locality(dev, priv, 0); +- +- return rc; ++ return tpm_chip_register(chip); + } + + static int crb_acpi_remove(struct acpi_device *device) +@@ -663,52 +657,11 @@ static int crb_acpi_remove(struct acpi_d + + tpm_chip_unregister(chip); + +- pm_runtime_disable(dev); +- + return 0; + } + +-static int __maybe_unused crb_pm_runtime_suspend(struct device *dev) +-{ +- struct tpm_chip *chip = dev_get_drvdata(dev); +- struct crb_priv *priv = dev_get_drvdata(&chip->dev); +- +- return crb_go_idle(dev, priv); +-} +- +-static int __maybe_unused crb_pm_runtime_resume(struct device *dev) +-{ +- struct tpm_chip *chip = dev_get_drvdata(dev); +- struct crb_priv *priv = dev_get_drvdata(&chip->dev); +- +- return crb_cmd_ready(dev, priv); +-} +- +-static int __maybe_unused crb_pm_suspend(struct device *dev) +-{ +- int ret; +- +- ret = tpm_pm_suspend(dev); +- if (ret) +- return ret; +- +- return crb_pm_runtime_suspend(dev); +-} +- +-static int __maybe_unused crb_pm_resume(struct device *dev) +-{ +- int ret; +- +- ret = crb_pm_runtime_resume(dev); +- if (ret) +- return ret; +- +- return tpm_pm_resume(dev); +-} +- + static const struct dev_pm_ops crb_pm = { +- SET_SYSTEM_SLEEP_PM_OPS(crb_pm_suspend, crb_pm_resume) +- SET_RUNTIME_PM_OPS(crb_pm_runtime_suspend, crb_pm_runtime_resume, NULL) ++ SET_SYSTEM_SLEEP_PM_OPS(tpm_pm_suspend, tpm_pm_resume) + }; + + static const struct acpi_device_id crb_device_ids[] = { +--- a/include/linux/tpm.h ++++ b/include/linux/tpm.h +@@ -43,6 +43,8 @@ struct tpm_class_ops { + u8 (*status) (struct tpm_chip *chip); + bool (*update_timeouts)(struct tpm_chip *chip, + unsigned long *timeout_cap); ++ int (*go_idle)(struct tpm_chip *chip); ++ int (*cmd_ready)(struct tpm_chip *chip); + int (*request_locality)(struct tpm_chip *chip, int loc); + int (*relinquish_locality)(struct tpm_chip *chip, int loc); + void (*clk_enable)(struct tpm_chip *chip, bool value); diff --git a/queue-4.18/watchdog-mark-watchdog-touch-functions-as-notrace.patch b/queue-4.18/watchdog-mark-watchdog-touch-functions-as-notrace.patch new file mode 100644 index 00000000000..3c810bb1be2 --- /dev/null +++ b/queue-4.18/watchdog-mark-watchdog-touch-functions-as-notrace.patch @@ -0,0 +1,79 @@ +From cb9d7fd51d9fbb329d182423bd7b92d0f8cb0e01 Mon Sep 17 00:00:00 2001 +From: Vincent Whitchurch +Date: Tue, 21 Aug 2018 17:25:07 +0200 +Subject: watchdog: Mark watchdog touch functions as notrace + +From: Vincent Whitchurch + +commit cb9d7fd51d9fbb329d182423bd7b92d0f8cb0e01 upstream. + +Some architectures need to use stop_machine() to patch functions for +ftrace, and the assumption is that the stopped CPUs do not make function +calls to traceable functions when they are in the stopped state. + +Commit ce4f06dcbb5d ("stop_machine: Touch_nmi_watchdog() after +MULTI_STOP_PREPARE") added calls to the watchdog touch functions from +the stopped CPUs and those functions lack notrace annotations. This +leads to crashes when enabling/disabling ftrace on ARM kernels built +with the Thumb-2 instruction set. + +Fix it by adding the necessary notrace annotations. + +Fixes: ce4f06dcbb5d ("stop_machine: Touch_nmi_watchdog() after MULTI_STOP_PREPARE") +Signed-off-by: Vincent Whitchurch +Signed-off-by: Thomas Gleixner +Cc: Peter Zijlstra +Cc: oleg@redhat.com +Cc: tj@kernel.org +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20180821152507.18313-1-vincent.whitchurch@axis.com +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/watchdog.c | 4 ++-- + kernel/watchdog_hld.c | 2 +- + kernel/workqueue.c | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +--- a/kernel/watchdog.c ++++ b/kernel/watchdog.c +@@ -266,7 +266,7 @@ static void __touch_watchdog(void) + * entering idle state. This should only be used for scheduler events. + * Use touch_softlockup_watchdog() for everything else. + */ +-void touch_softlockup_watchdog_sched(void) ++notrace void touch_softlockup_watchdog_sched(void) + { + /* + * Preemption can be enabled. It doesn't matter which CPU's timestamp +@@ -275,7 +275,7 @@ void touch_softlockup_watchdog_sched(voi + raw_cpu_write(watchdog_touch_ts, 0); + } + +-void touch_softlockup_watchdog(void) ++notrace void touch_softlockup_watchdog(void) + { + touch_softlockup_watchdog_sched(); + wq_watchdog_touch(raw_smp_processor_id()); +--- a/kernel/watchdog_hld.c ++++ b/kernel/watchdog_hld.c +@@ -29,7 +29,7 @@ static struct cpumask dead_events_mask; + static unsigned long hardlockup_allcpu_dumped; + static atomic_t watchdog_cpus = ATOMIC_INIT(0); + +-void arch_touch_nmi_watchdog(void) ++notrace void arch_touch_nmi_watchdog(void) + { + /* + * Using __raw here because some code paths have +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -5559,7 +5559,7 @@ static void wq_watchdog_timer_fn(struct + mod_timer(&wq_watchdog_timer, jiffies + thresh); + } + +-void wq_watchdog_touch(int cpu) ++notrace void wq_watchdog_touch(int cpu) + { + if (cpu >= 0) + per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies;