From d56d24c85d886cbf521eddf129110d061730fe7c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 25 Aug 2025 09:34:27 +0200 Subject: [PATCH] 5.15-stable patches added patches: compiler-remove-__addressable_asm-_str-again.patch iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch iio-light-as73211-ensure-buffer-holes-are-zeroed.patch mm-memory-failure-fix-infinite-uce-for-vm_pfnmap-pfn.patch tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch tracing-remove-unneeded-goto-out-logic.patch usb-xhci-fix-slot_id-resource-race-conflict.patch --- ...-remove-__addressable_asm-_str-again.patch | 80 +++++++ ...0-change-invalid-data-error-to-ebusy.patch | 50 ++++ ...73211-ensure-buffer-holes-are-zeroed.patch | 39 ++++ ...e-fix-infinite-uce-for-vm_pfnmap-pfn.patch | 67 ++++++ queue-5.15/series | 7 + ...er-buffer-when-trace_get_user-failed.patch | 142 ++++++++++++ ...acing-remove-unneeded-goto-out-logic.patch | 149 ++++++++++++ ...i-fix-slot_id-resource-race-conflict.patch | 216 ++++++++++++++++++ 8 files changed, 750 insertions(+) create mode 100644 queue-5.15/compiler-remove-__addressable_asm-_str-again.patch create mode 100644 queue-5.15/iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch create mode 100644 queue-5.15/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch create mode 100644 queue-5.15/mm-memory-failure-fix-infinite-uce-for-vm_pfnmap-pfn.patch create mode 100644 queue-5.15/tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch create mode 100644 queue-5.15/tracing-remove-unneeded-goto-out-logic.patch create mode 100644 queue-5.15/usb-xhci-fix-slot_id-resource-race-conflict.patch diff --git a/queue-5.15/compiler-remove-__addressable_asm-_str-again.patch b/queue-5.15/compiler-remove-__addressable_asm-_str-again.patch new file mode 100644 index 0000000000..9651b0301e --- /dev/null +++ b/queue-5.15/compiler-remove-__addressable_asm-_str-again.patch @@ -0,0 +1,80 @@ +From stable+bounces-172756-greg=kroah.com@vger.kernel.org Sun Aug 24 18:49:53 2025 +From: Sasha Levin +Date: Sun, 24 Aug 2025 12:49:41 -0400 +Subject: compiler: remove __ADDRESSABLE_ASM{_STR,}() again +To: stable@vger.kernel.org +Cc: Jan Beulich , Josh Poimboeuf , Juergen Gross , Sasha Levin +Message-ID: <20250824164941.4151594-1-sashal@kernel.org> + +From: Jan Beulich + +[ Upstream commit 8ea815399c3fcce1889bd951fec25b5b9a3979c1 ] + +__ADDRESSABLE_ASM_STR() is where the necessary stringification happens. +As long as "sym" doesn't contain any odd characters, no quoting is +required for its use with .quad / .long. In fact the quotation gets in +the way with gas 2.25; it's only from 2.26 onwards that quoted symbols +are half-way properly supported. + +However, assembly being different from C anyway, drop +__ADDRESSABLE_ASM_STR() and its helper macro altogether. A simple +.global directive will suffice to get the symbol "declared", i.e. into +the symbol table. While there also stop open-coding STATIC_CALL_TRAMP() +and STATIC_CALL_KEY(). + +Fixes: 0ef8047b737d ("x86/static-call: provide a way to do very early static-call updates") +Signed-off-by: Jan Beulich +Acked-by: Josh Poimboeuf +Cc: stable@vger.kernel.org +Signed-off-by: Juergen Gross +Message-ID: <609d2c74-de13-4fae-ab1a-1ec44afb948d@suse.com> +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/xen/hypercall.h | 6 ++++-- + include/linux/compiler.h | 8 -------- + 2 files changed, 4 insertions(+), 10 deletions(-) + +--- a/arch/x86/include/asm/xen/hypercall.h ++++ b/arch/x86/include/asm/xen/hypercall.h +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -94,12 +95,13 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_h + #ifdef MODULE + #define __ADDRESSABLE_xen_hypercall + #else +-#define __ADDRESSABLE_xen_hypercall __ADDRESSABLE_ASM_STR(__SCK__xen_hypercall) ++#define __ADDRESSABLE_xen_hypercall \ ++ __stringify(.global STATIC_CALL_KEY(xen_hypercall);) + #endif + + #define __HYPERCALL \ + __ADDRESSABLE_xen_hypercall \ +- "call __SCT__xen_hypercall" ++ __stringify(call STATIC_CALL_TRAMP(xen_hypercall)) + + #define __HYPERCALL_ENTRY(x) "a" (x) + +--- a/include/linux/compiler.h ++++ b/include/linux/compiler.h +@@ -249,14 +249,6 @@ static inline void *offset_to_ptr(const + static void * __section(".discard.addressable") __used \ + __UNIQUE_ID(__PASTE(__addressable_,sym)) = (void *)&sym; + +-#define __ADDRESSABLE_ASM(sym) \ +- .pushsection .discard.addressable,"aw"; \ +- .align ARCH_SEL(8,4); \ +- ARCH_SEL(.quad, .long) __stringify(sym); \ +- .popsection; +- +-#define __ADDRESSABLE_ASM_STR(sym) __stringify(__ADDRESSABLE_ASM(sym)) +- + /* &a[0] degrades to a pointer: a different type from an array */ + #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) + diff --git a/queue-5.15/iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch b/queue-5.15/iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch new file mode 100644 index 0000000000..35dbdd4c34 --- /dev/null +++ b/queue-5.15/iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch @@ -0,0 +1,50 @@ +From stable+bounces-172751-greg=kroah.com@vger.kernel.org Sun Aug 24 17:25:31 2025 +From: Sasha Levin +Date: Sun, 24 Aug 2025 11:25:24 -0400 +Subject: iio: imu: inv_icm42600: change invalid data error to -EBUSY +To: stable@vger.kernel.org +Cc: Jean-Baptiste Maneyrol , Andy Shevchenko , Sean Nyekjaer , Jonathan Cameron , Sasha Levin +Message-ID: <20250824152524.3328278-1-sashal@kernel.org> + +From: Jean-Baptiste Maneyrol + +[ Upstream commit dfdc31e7ccf3ac1d5ec01d5120c71e14745e3dd8 ] + +Temperature sensor returns the temperature of the mechanical parts +of the chip. If both accel and gyro are off, the temperature sensor is +also automatically turned off and returns invalid data. + +In this case, returning -EBUSY error code is better then -EINVAL and +indicates userspace that it needs to retry reading temperature in +another context. + +Fixes: bc3eb0207fb5 ("iio: imu: inv_icm42600: add temperature sensor support") +Signed-off-by: Jean-Baptiste Maneyrol +Cc: stable@vger.kernel.org +Reviewed-by: Andy Shevchenko +Reviewed-by: Sean Nyekjaer +Link: https://patch.msgid.link/20250808-inv-icm42600-change-temperature-error-code-v1-1-986fbf63b77d@tdk.com +Signed-off-by: Jonathan Cameron +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c ++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +@@ -32,8 +32,12 @@ static int inv_icm42600_temp_read(struct + goto exit; + + *temp = (int16_t)be16_to_cpup(raw); ++ /* ++ * Temperature data is invalid if both accel and gyro are off. ++ * Return -EBUSY in this case. ++ */ + if (*temp == INV_ICM42600_DATA_INVALID) +- ret = -EINVAL; ++ ret = -EBUSY; + + exit: + mutex_unlock(&st->lock); diff --git a/queue-5.15/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch b/queue-5.15/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch new file mode 100644 index 0000000000..316197b93a --- /dev/null +++ b/queue-5.15/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch @@ -0,0 +1,39 @@ +From stable+bounces-172730-greg=kroah.com@vger.kernel.org Sun Aug 24 15:26:54 2025 +From: Sasha Levin +Date: Sun, 24 Aug 2025 09:26:44 -0400 +Subject: iio: light: as73211: Ensure buffer holes are zeroed +To: stable@vger.kernel.org +Cc: Jonathan Cameron , Matti Vaittinen , Andy Shevchenko , Stable@vger.kernel.org, Sasha Levin +Message-ID: <20250824132644.2870643-1-sashal@kernel.org> + +From: Jonathan Cameron + +[ Upstream commit 433b99e922943efdfd62b9a8e3ad1604838181f2 ] + +Given that the buffer is copied to a kfifo that ultimately user space +can read, ensure we zero it. + +Fixes: 403e5586b52e ("iio: light: as73211: New driver") +Reviewed-by: Matti Vaittinen +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20250802164436.515988-2-jic23@kernel.org +Cc: +Signed-off-by: Jonathan Cameron +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/light/as73211.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/light/as73211.c ++++ b/drivers/iio/light/as73211.c +@@ -573,7 +573,7 @@ static irqreturn_t as73211_trigger_handl + struct { + __le16 chan[4]; + s64 ts __aligned(8); +- } scan; ++ } scan = { }; + int data_result, ret; + + mutex_lock(&data->mutex); diff --git a/queue-5.15/mm-memory-failure-fix-infinite-uce-for-vm_pfnmap-pfn.patch b/queue-5.15/mm-memory-failure-fix-infinite-uce-for-vm_pfnmap-pfn.patch new file mode 100644 index 0000000000..922bb50926 --- /dev/null +++ b/queue-5.15/mm-memory-failure-fix-infinite-uce-for-vm_pfnmap-pfn.patch @@ -0,0 +1,67 @@ +From stable+bounces-172727-greg=kroah.com@vger.kernel.org Sun Aug 24 15:03:52 2025 +From: Sasha Levin +Date: Sun, 24 Aug 2025 09:03:41 -0400 +Subject: mm/memory-failure: fix infinite UCE for VM_PFNMAP pfn +To: stable@vger.kernel.org +Cc: Jinjiang Tu , David Hildenbrand , Miaohe Lin , Jane Chu , Kefeng Wang , Naoya Horiguchi , Oscar Salvador , Shuai Xue , Zi Yan , Andrew Morton , Sasha Levin +Message-ID: <20250824130341.2750580-1-sashal@kernel.org> + +From: Jinjiang Tu + +[ Upstream commit 2e6053fea379806269c4f7f5e36b523c9c0fb35c ] + +When memory_failure() is called for a already hwpoisoned pfn, +kill_accessing_process() will be called to kill current task. However, if +the vma of the accessing vaddr is VM_PFNMAP, walk_page_range() will skip +the vma in walk_page_test() and return 0. + +Before commit aaf99ac2ceb7 ("mm/hwpoison: do not send SIGBUS to processes +with recovered clean pages"), kill_accessing_process() will return EFAULT. +For x86, the current task will be killed in kill_me_maybe(). + +However, after this commit, kill_accessing_process() simplies return 0, +that means UCE is handled properly, but it doesn't actually. In such +case, the user task will trigger UCE infinitely. + +To fix it, add .test_walk callback for hwpoison_walk_ops to scan all vmas. + +Link: https://lkml.kernel.org/r/20250815073209.1984582-1-tujinjiang@huawei.com +Fixes: aaf99ac2ceb7 ("mm/hwpoison: do not send SIGBUS to processes with recovered clean pages") +Signed-off-by: Jinjiang Tu +Acked-by: David Hildenbrand +Acked-by: Miaohe Lin +Reviewed-by: Jane Chu +Cc: Kefeng Wang +Cc: Naoya Horiguchi +Cc: Oscar Salvador +Cc: Shuai Xue +Cc: Zi Yan +Cc: +Signed-off-by: Andrew Morton +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + mm/memory-failure.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -674,9 +674,17 @@ static int hwpoison_hugetlb_range(pte_t + #define hwpoison_hugetlb_range NULL + #endif + ++static int hwpoison_test_walk(unsigned long start, unsigned long end, ++ struct mm_walk *walk) ++{ ++ /* We also want to consider pages mapped into VM_PFNMAP. */ ++ return 0; ++} ++ + static struct mm_walk_ops hwp_walk_ops = { + .pmd_entry = hwpoison_pte_range, + .hugetlb_entry = hwpoison_hugetlb_range, ++ .test_walk = hwpoison_test_walk, + }; + + /* diff --git a/queue-5.15/series b/queue-5.15/series index 169dd72e42..e59c7f6978 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -609,3 +609,10 @@ pwm-mediatek-implement-.apply-callback.patch pwm-mediatek-handle-hardware-enable-and-clock-enable-separately.patch pwm-mediatek-fix-duty-and-period-setting.patch selftests-mptcp-pm-check-flush-doesn-t-reset-limits.patch +compiler-remove-__addressable_asm-_str-again.patch +usb-xhci-fix-slot_id-resource-race-conflict.patch +iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch +tracing-remove-unneeded-goto-out-logic.patch +tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch +iio-light-as73211-ensure-buffer-holes-are-zeroed.patch +mm-memory-failure-fix-infinite-uce-for-vm_pfnmap-pfn.patch diff --git a/queue-5.15/tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch b/queue-5.15/tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch new file mode 100644 index 0000000000..64c1658ac9 --- /dev/null +++ b/queue-5.15/tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch @@ -0,0 +1,142 @@ +From stable+bounces-172745-greg=kroah.com@vger.kernel.org Sun Aug 24 15:58:56 2025 +From: Sasha Levin +Date: Sun, 24 Aug 2025 09:58:43 -0400 +Subject: tracing: Limit access to parser->buffer when trace_get_user failed +To: stable@vger.kernel.org +Cc: Pu Lehui , "Steven Rostedt (Google)" , Sasha Levin +Message-ID: <20250824135843.2924564-2-sashal@kernel.org> + +From: Pu Lehui + +[ Upstream commit 6a909ea83f226803ea0e718f6e88613df9234d58 ] + +When the length of the string written to set_ftrace_filter exceeds +FTRACE_BUFF_MAX, the following KASAN alarm will be triggered: + +BUG: KASAN: slab-out-of-bounds in strsep+0x18c/0x1b0 +Read of size 1 at addr ffff0000d00bd5ba by task ash/165 + +CPU: 1 UID: 0 PID: 165 Comm: ash Not tainted 6.16.0-g6bcdbd62bd56-dirty +Hardware name: linux,dummy-virt (DT) +Call trace: + show_stack+0x34/0x50 (C) + dump_stack_lvl+0xa0/0x158 + print_address_description.constprop.0+0x88/0x398 + print_report+0xb0/0x280 + kasan_report+0xa4/0xf0 + __asan_report_load1_noabort+0x20/0x30 + strsep+0x18c/0x1b0 + ftrace_process_regex.isra.0+0x100/0x2d8 + ftrace_regex_release+0x484/0x618 + __fput+0x364/0xa58 + ____fput+0x28/0x40 + task_work_run+0x154/0x278 + do_notify_resume+0x1f0/0x220 + el0_svc+0xec/0xf0 + el0t_64_sync_handler+0xa0/0xe8 + el0t_64_sync+0x1ac/0x1b0 + +The reason is that trace_get_user will fail when processing a string +longer than FTRACE_BUFF_MAX, but not set the end of parser->buffer to 0. +Then an OOB access will be triggered in ftrace_regex_release-> +ftrace_process_regex->strsep->strpbrk. We can solve this problem by +limiting access to parser->buffer when trace_get_user failed. + +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/20250813040232.1344527-1-pulehui@huaweicloud.com +Fixes: 8c9af478c06b ("ftrace: Handle commands when closing set_ftrace_filter file") +Signed-off-by: Pu Lehui +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 18 ++++++++++++------ + kernel/trace/trace.h | 8 +++++++- + 2 files changed, 19 insertions(+), 7 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -1605,7 +1605,7 @@ int trace_get_user(struct trace_parser * + + ret = get_user(ch, ubuf++); + if (ret) +- return ret; ++ goto fail; + + read++; + cnt--; +@@ -1619,7 +1619,7 @@ int trace_get_user(struct trace_parser * + while (cnt && isspace(ch)) { + ret = get_user(ch, ubuf++); + if (ret) +- return ret; ++ goto fail; + read++; + cnt--; + } +@@ -1637,12 +1637,14 @@ int trace_get_user(struct trace_parser * + while (cnt && !isspace(ch) && ch) { + if (parser->idx < parser->size - 1) + parser->buffer[parser->idx++] = ch; +- else +- return -EINVAL; ++ else { ++ ret = -EINVAL; ++ goto fail; ++ } + + ret = get_user(ch, ubuf++); + if (ret) +- return ret; ++ goto fail; + read++; + cnt--; + } +@@ -1657,11 +1659,15 @@ int trace_get_user(struct trace_parser * + /* Make sure the parsed string always terminates with '\0'. */ + parser->buffer[parser->idx] = 0; + } else { +- return -EINVAL; ++ ret = -EINVAL; ++ goto fail; + } + + *ppos += read; + return read; ++fail: ++ trace_parser_fail(parser); ++ return ret; + } + + /* TODO add a seq_buf_to_buffer() */ +--- a/kernel/trace/trace.h ++++ b/kernel/trace/trace.h +@@ -1132,6 +1132,7 @@ bool ftrace_event_is_function(struct tra + */ + struct trace_parser { + bool cont; ++ bool fail; + char *buffer; + unsigned idx; + unsigned size; +@@ -1139,7 +1140,7 @@ struct trace_parser { + + static inline bool trace_parser_loaded(struct trace_parser *parser) + { +- return (parser->idx != 0); ++ return !parser->fail && parser->idx != 0; + } + + static inline bool trace_parser_cont(struct trace_parser *parser) +@@ -1153,6 +1154,11 @@ static inline void trace_parser_clear(st + parser->idx = 0; + } + ++static inline void trace_parser_fail(struct trace_parser *parser) ++{ ++ parser->fail = true; ++} ++ + extern int trace_parser_get_init(struct trace_parser *parser, int size); + extern void trace_parser_put(struct trace_parser *parser); + extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf, diff --git a/queue-5.15/tracing-remove-unneeded-goto-out-logic.patch b/queue-5.15/tracing-remove-unneeded-goto-out-logic.patch new file mode 100644 index 0000000000..0c1be9931b --- /dev/null +++ b/queue-5.15/tracing-remove-unneeded-goto-out-logic.patch @@ -0,0 +1,149 @@ +From stable+bounces-172744-greg=kroah.com@vger.kernel.org Sun Aug 24 15:59:33 2025 +From: Sasha Levin +Date: Sun, 24 Aug 2025 09:58:42 -0400 +Subject: tracing: Remove unneeded goto out logic +To: stable@vger.kernel.org +Cc: Steven Rostedt , Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Sasha Levin +Message-ID: <20250824135843.2924564-1-sashal@kernel.org> + +From: Steven Rostedt + +[ Upstream commit c89504a703fb779052213add0e8ed642f4a4f1c8 ] + +Several places in the trace.c file there's a goto out where the out is +simply a return. There's no reason to jump to the out label if it's not +doing any more logic but simply returning from the function. + +Replace the goto outs with a return and remove the out labels. + +Cc: Masami Hiramatsu +Cc: Mark Rutland +Cc: Mathieu Desnoyers +Cc: Andrew Morton +Link: https://lore.kernel.org/20250801203857.538726745@kernel.org +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 37 ++++++++++++++----------------------- + 1 file changed, 14 insertions(+), 23 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -1605,7 +1605,7 @@ int trace_get_user(struct trace_parser * + + ret = get_user(ch, ubuf++); + if (ret) +- goto out; ++ return ret; + + read++; + cnt--; +@@ -1619,7 +1619,7 @@ int trace_get_user(struct trace_parser * + while (cnt && isspace(ch)) { + ret = get_user(ch, ubuf++); + if (ret) +- goto out; ++ return ret; + read++; + cnt--; + } +@@ -1629,8 +1629,7 @@ int trace_get_user(struct trace_parser * + /* only spaces were written */ + if (isspace(ch) || !ch) { + *ppos += read; +- ret = read; +- goto out; ++ return read; + } + } + +@@ -1638,13 +1637,12 @@ int trace_get_user(struct trace_parser * + while (cnt && !isspace(ch) && ch) { + if (parser->idx < parser->size - 1) + parser->buffer[parser->idx++] = ch; +- else { +- ret = -EINVAL; +- goto out; +- } ++ else ++ return -EINVAL; ++ + ret = get_user(ch, ubuf++); + if (ret) +- goto out; ++ return ret; + read++; + cnt--; + } +@@ -1659,15 +1657,11 @@ int trace_get_user(struct trace_parser * + /* Make sure the parsed string always terminates with '\0'. */ + parser->buffer[parser->idx] = 0; + } else { +- ret = -EINVAL; +- goto out; ++ return -EINVAL; + } + + *ppos += read; +- ret = read; +- +-out: +- return ret; ++ return read; + } + + /* TODO add a seq_buf_to_buffer() */ +@@ -2136,10 +2130,10 @@ int __init register_tracer(struct tracer + mutex_unlock(&trace_types_lock); + + if (ret || !default_bootup_tracer) +- goto out_unlock; ++ return ret; + + if (strncmp(default_bootup_tracer, type->name, MAX_TRACER_SIZE)) +- goto out_unlock; ++ return 0; + + printk(KERN_INFO "Starting tracer '%s'\n", type->name); + /* Do we want this tracer to start on bootup? */ +@@ -2151,8 +2145,7 @@ int __init register_tracer(struct tracer + /* disable other selftests, since this will break it. */ + disable_tracing_selftest("running a tracer"); + +- out_unlock: +- return ret; ++ return 0; + } + + static void tracing_reset_cpu(struct array_buffer *buf, int cpu) +@@ -8711,11 +8704,10 @@ ftrace_trace_snapshot_callback(struct tr + out_reg: + ret = tracing_alloc_snapshot_instance(tr); + if (ret < 0) +- goto out; ++ return ret; + + ret = register_ftrace_function_probe(glob, tr, ops, count); + +- out: + return ret < 0 ? ret : 0; + } + +@@ -10231,7 +10223,7 @@ __init static int tracer_alloc_buffers(v + BUILD_BUG_ON(TRACE_ITER_LAST_BIT > TRACE_FLAGS_MAX_SIZE); + + if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL)) +- goto out; ++ return -ENOMEM; + + if (!alloc_cpumask_var(&global_trace.tracing_cpumask, GFP_KERNEL)) + goto out_free_buffer_mask; +@@ -10344,7 +10336,6 @@ out_free_cpumask: + free_cpumask_var(global_trace.tracing_cpumask); + out_free_buffer_mask: + free_cpumask_var(tracing_buffer_mask); +-out: + return ret; + } + diff --git a/queue-5.15/usb-xhci-fix-slot_id-resource-race-conflict.patch b/queue-5.15/usb-xhci-fix-slot_id-resource-race-conflict.patch new file mode 100644 index 0000000000..0b91362c05 --- /dev/null +++ b/queue-5.15/usb-xhci-fix-slot_id-resource-race-conflict.patch @@ -0,0 +1,216 @@ +From stable+bounces-172755-greg=kroah.com@vger.kernel.org Sun Aug 24 18:40:09 2025 +From: Sasha Levin +Date: Sun, 24 Aug 2025 12:39:51 -0400 +Subject: usb: xhci: Fix slot_id resource race conflict +To: stable@vger.kernel.org +Cc: Weitao Wang , Mathias Nyman , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250824163951.4032033-1-sashal@kernel.org> + +From: Weitao Wang + +[ Upstream commit 2eb03376151bb8585caa23ed2673583107bb5193 ] + +xHC controller may immediately reuse a slot_id after it's disabled, +giving it to a new enumerating device before the xhci driver freed +all resources related to the disabled device. + +In such a scenario, device-A with slot_id equal to 1 is disconnecting +while device-B is enumerating, device-B will fail to enumerate in the +follow sequence. + +1.[device-A] send disable slot command +2.[device-B] send enable slot command +3.[device-A] disable slot command completed and wakeup waiting thread +4.[device-B] enable slot command completed with slot_id equal to 1 and + wakeup waiting thread +5.[device-B] driver checks that slot_id is still in use (by device-A) in + xhci_alloc_virt_device, and fail to enumerate due to this + conflict +6.[device-A] xhci->devs[slot_id] set to NULL in xhci_free_virt_device + +To fix driver's slot_id resources conflict, clear xhci->devs[slot_id] and +xhci->dcbba->dev_context_ptrs[slot_id] pointers in the interrupt context +when disable slot command completes successfully. Simultaneously, adjust +function xhci_free_virt_device to accurately handle device release. + +[minor smatch warning and commit message fix -Mathias] + +Cc: stable@vger.kernel.org +Fixes: 7faac1953ed1 ("xhci: avoid race between disable slot command and host runtime suspend") +Signed-off-by: Weitao Wang +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250819125844.2042452-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-hub.c | 3 +-- + drivers/usb/host/xhci-mem.c | 22 +++++++++++----------- + drivers/usb/host/xhci-ring.c | 9 +++++++-- + drivers/usb/host/xhci.c | 18 +++++++++++++----- + drivers/usb/host/xhci.h | 3 ++- + 5 files changed, 34 insertions(+), 21 deletions(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -716,8 +716,7 @@ static int xhci_enter_test_mode(struct x + if (!xhci->devs[i]) + continue; + +- retval = xhci_disable_slot(xhci, i); +- xhci_free_virt_device(xhci, i); ++ retval = xhci_disable_and_free_slot(xhci, i); + if (retval) + xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n", + i, retval); +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -871,21 +871,20 @@ free_tts: + * will be manipulated by the configure endpoint, allocate device, or update + * hub functions while this function is removing the TT entries from the list. + */ +-void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) ++void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, ++ int slot_id) + { +- struct xhci_virt_device *dev; + int i; + int old_active_eps = 0; + + /* Slot ID 0 is reserved */ +- if (slot_id == 0 || !xhci->devs[slot_id]) ++ if (slot_id == 0 || !dev) + return; + +- dev = xhci->devs[slot_id]; +- +- xhci->dcbaa->dev_context_ptrs[slot_id] = 0; +- if (!dev) +- return; ++ /* If device ctx array still points to _this_ device, clear it */ ++ if (dev->out_ctx && ++ xhci->dcbaa->dev_context_ptrs[slot_id] == cpu_to_le64(dev->out_ctx->dma)) ++ xhci->dcbaa->dev_context_ptrs[slot_id] = 0; + + trace_xhci_free_virt_device(dev); + +@@ -924,8 +923,9 @@ void xhci_free_virt_device(struct xhci_h + + if (dev->udev && dev->udev->slot_id) + dev->udev->slot_id = 0; +- kfree(xhci->devs[slot_id]); +- xhci->devs[slot_id] = NULL; ++ if (xhci->devs[slot_id] == dev) ++ xhci->devs[slot_id] = NULL; ++ kfree(dev); + } + + /* +@@ -967,7 +967,7 @@ static void xhci_free_virt_devices_depth + out: + /* we are now at a leaf device */ + xhci_debugfs_remove_slot(xhci, slot_id); +- xhci_free_virt_device(xhci, slot_id); ++ xhci_free_virt_device(xhci, vdev, slot_id); + } + + int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1612,7 +1612,8 @@ static void xhci_handle_cmd_enable_slot( + command->slot_id = 0; + } + +-static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id) ++static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id, ++ u32 cmd_comp_code) + { + struct xhci_virt_device *virt_dev; + struct xhci_slot_ctx *slot_ctx; +@@ -1627,6 +1628,10 @@ static void xhci_handle_cmd_disable_slot + if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) + /* Delete default control endpoint resources */ + xhci_free_device_endpoint_resources(xhci, virt_dev, true); ++ if (cmd_comp_code == COMP_SUCCESS) { ++ xhci->dcbaa->dev_context_ptrs[slot_id] = 0; ++ xhci->devs[slot_id] = NULL; ++ } + } + + static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id, +@@ -1876,7 +1881,7 @@ static void handle_cmd_completion(struct + xhci_handle_cmd_enable_slot(xhci, slot_id, cmd, cmd_comp_code); + break; + case TRB_DISABLE_SLOT: +- xhci_handle_cmd_disable_slot(xhci, slot_id); ++ xhci_handle_cmd_disable_slot(xhci, slot_id, cmd_comp_code); + break; + case TRB_CONFIG_EP: + if (!cmd->completion) +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -4032,7 +4032,7 @@ static void xhci_free_dev(struct usb_hcd + xhci_disable_slot(xhci, udev->slot_id); + + spin_lock_irqsave(&xhci->lock, flags); +- xhci_free_virt_device(xhci, udev->slot_id); ++ xhci_free_virt_device(xhci, virt_dev, udev->slot_id); + spin_unlock_irqrestore(&xhci->lock, flags); + + } +@@ -4081,6 +4081,16 @@ int xhci_disable_slot(struct xhci_hcd *x + return ret; + } + ++int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id) ++{ ++ struct xhci_virt_device *vdev = xhci->devs[slot_id]; ++ int ret; ++ ++ ret = xhci_disable_slot(xhci, slot_id); ++ xhci_free_virt_device(xhci, vdev, slot_id); ++ return ret; ++} ++ + /* + * Checks if we have enough host controller resources for the default control + * endpoint. +@@ -4186,8 +4196,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, + return 1; + + disable_slot: +- xhci_disable_slot(xhci, udev->slot_id); +- xhci_free_virt_device(xhci, udev->slot_id); ++ xhci_disable_and_free_slot(xhci, udev->slot_id); + + return 0; + } +@@ -4323,8 +4332,7 @@ static int xhci_setup_device(struct usb_ + dev_warn(&udev->dev, "Device not responding to setup %s.\n", act); + + mutex_unlock(&xhci->mutex); +- ret = xhci_disable_slot(xhci, udev->slot_id); +- xhci_free_virt_device(xhci, udev->slot_id); ++ ret = xhci_disable_and_free_slot(xhci, udev->slot_id); + if (!ret) { + if (xhci_alloc_dev(hcd, udev) == 1) + xhci_setup_addressable_virt_dev(xhci, udev); +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1782,7 +1782,7 @@ void xhci_dbg_trace(struct xhci_hcd *xhc + /* xHCI memory management */ + void xhci_mem_cleanup(struct xhci_hcd *xhci); + int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags); +-void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id); ++void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, int slot_id); + int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags); + int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev); + void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci, +@@ -1874,6 +1874,7 @@ void xhci_reset_bandwidth(struct usb_hcd + int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, + struct usb_tt *tt, gfp_t mem_flags); + int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); ++int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id); + int xhci_ext_cap_init(struct xhci_hcd *xhci); + + int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); -- 2.47.3