From: Greg Kroah-Hartman Date: Fri, 6 Dec 2024 12:40:00 +0000 (+0100) Subject: 6.12-stable patches X-Git-Tag: v6.6.64~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e66a80fa797650ae88e29cd374db5eb100e1de00;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: binder-add-delivered_freeze-to-debugfs-output.patch binder-allow-freeze-notification-for-dead-nodes.patch binder-fix-binder_work_clear_freeze_notification-debug-logs.patch binder-fix-binder_work_frozen_binder-debug-logs.patch binder-fix-freeze-uaf-in-binder_release_work.patch binder-fix-memleak-of-proc-delivered_freeze.patch binder-fix-node-uaf-in-binder_add_freeze_work.patch binder-fix-oob-in-binder_add_freeze_work.patch dm-fix-typo-in-error-message.patch dm-thin-add-missing-destroy_work_on_stack.patch fs-proc-kcore.c-clear-ret-value-in-read_kcore_iter-after-successful-iov_iter_zero.patch i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch i3c-master-svc-fix-pm_runtime_set_suspended-with-runtime-pm-enabled.patch i3c-master-svc-fix-possible-assignment-of-the-same-address-to-two-devices.patch i3c-master-svc-modify-enabled_events-bit-7-0-to-act-as-ibi-enable-counter.patch iio-accel-kx022a-fix-raw-read-format.patch iio-adc-ad7923-fix-buffer-overflow-for-tx_buf-and-ring_xfer.patch iio-fix-fwnode_handle-in-__fwnode_iio_channel_get_by_name.patch iio-gts-fix-infinite-loop-for-gain_to_scaletables.patch iio-invensense-fix-multiple-odr-switch-when-fifo-is-off.patch leds-flash-mt6360-fix-device_for_each_child_node-refcounting-in-error-paths.patch mm-vmalloc-combine-all-tlb-flush-operations-of-kasan-shadow-virtual-address-into-one-operation.patch nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch nfsd-make-sure-exp-active-before-svc_export_show.patch ovl-properly-handle-large-files-in-ovl_security_fileattr.patch pci-dwc-ep-fix-advertised-resizable-bar-size-regression.patch pci-endpoint-clear-secondary-not-primary-epc-in-pci_epc_remove_epf.patch pci-endpoint-fix-pci-domain-id-release-in-pci_epc_destroy.patch pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch pci-keystone-set-mode-as-root-complex-for-ti-keystone-pcie-compatible.patch pci-of_property-assign-pci-instead-of-cpu-bus-address-to-dynamic-pci-nodes.patch pci-rockchip-ep-fix-address-translation-unit-programming.patch powerpc-adjust-adding-stack-protector-flags-to-kbuild_clags-for-clang.patch powerpc-fix-stack-protector-kconfig-test-for-clang.patch s390-stacktrace-use-break-instead-of-return-statement.patch scsi-ufs-exynos-add-check-inside-exynos_ufs_config_smu.patch scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch slab-fix-too-strict-alignment-check-in-create_cache.patch thermal-int3400-fix-reading-of-current_uuid-for-active-policy.patch util_macros.h-fix-rework-find_closest-macros.patch --- diff --git a/queue-6.12/binder-add-delivered_freeze-to-debugfs-output.patch b/queue-6.12/binder-add-delivered_freeze-to-debugfs-output.patch new file mode 100644 index 00000000000..96aeda2c6fb --- /dev/null +++ b/queue-6.12/binder-add-delivered_freeze-to-debugfs-output.patch @@ -0,0 +1,42 @@ +From cb2aeb2ec25884133110ffe5a67ff3cf7dee5ceb Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Thu, 26 Sep 2024 23:36:19 +0000 +Subject: binder: add delivered_freeze to debugfs output + +From: Carlos Llamas + +commit cb2aeb2ec25884133110ffe5a67ff3cf7dee5ceb upstream. + +Add the pending proc->delivered_freeze work to the debugfs output. This +information was omitted in the original implementation of the freeze +notification and can be valuable for debugging issues. + +Fixes: d579b04a52a1 ("binder: frozen notification") +Cc: stable@vger.kernel.org +Signed-off-by: Carlos Llamas +Acked-by: Todd Kjos +Reviewed-by: Alice Ryhl +Link: https://lore.kernel.org/r/20240926233632.821189-9-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index 7c09b5e38e32..ef353ca13c35 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -6569,6 +6569,10 @@ static void print_binder_proc(struct seq_file *m, + seq_puts(m, " has delivered dead binder\n"); + break; + } ++ list_for_each_entry(w, &proc->delivered_freeze, entry) { ++ seq_puts(m, " has delivered freeze binder\n"); ++ break; ++ } + binder_inner_proc_unlock(proc); + if (!print_all && m->count == header_pos) + m->count = start_pos; +-- +2.47.1 + diff --git a/queue-6.12/binder-allow-freeze-notification-for-dead-nodes.patch b/queue-6.12/binder-allow-freeze-notification-for-dead-nodes.patch new file mode 100644 index 00000000000..1eb3d07df07 --- /dev/null +++ b/queue-6.12/binder-allow-freeze-notification-for-dead-nodes.patch @@ -0,0 +1,88 @@ +From ca63c66935b978441055e3d87d30225267f99329 Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Thu, 26 Sep 2024 23:36:17 +0000 +Subject: binder: allow freeze notification for dead nodes + +From: Carlos Llamas + +commit ca63c66935b978441055e3d87d30225267f99329 upstream. + +Alice points out that binder_request_freeze_notification() should not +return EINVAL when the relevant node is dead [1]. The node can die at +any point even if the user input is valid. Instead, allow the request +to be allocated but skip the initial notification for dead nodes. This +avoids propagating unnecessary errors back to userspace. + +Fixes: d579b04a52a1 ("binder: frozen notification") +Cc: stable@vger.kernel.org +Suggested-by: Alice Ryhl +Link: https://lore.kernel.org/all/CAH5fLghapZJ4PbbkC8V5A6Zay-_sgTzwVpwqk6RWWUNKKyJC_Q@mail.gmail.com/ [1] +Signed-off-by: Carlos Llamas +Acked-by: Todd Kjos +Link: https://lore.kernel.org/r/20240926233632.821189-7-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 28 +++++++++++++--------------- + 1 file changed, 13 insertions(+), 15 deletions(-) + +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index 73dc6cbc1681..415fc9759249 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -3856,7 +3856,6 @@ binder_request_freeze_notification(struct binder_proc *proc, + { + struct binder_ref_freeze *freeze; + struct binder_ref *ref; +- bool is_frozen; + + freeze = kzalloc(sizeof(*freeze), GFP_KERNEL); + if (!freeze) +@@ -3872,32 +3871,31 @@ binder_request_freeze_notification(struct binder_proc *proc, + } + + binder_node_lock(ref->node); +- +- if (ref->freeze || !ref->node->proc) { +- binder_user_error("%d:%d invalid BC_REQUEST_FREEZE_NOTIFICATION %s\n", +- proc->pid, thread->pid, +- ref->freeze ? "already set" : "dead node"); ++ if (ref->freeze) { ++ binder_user_error("%d:%d BC_REQUEST_FREEZE_NOTIFICATION already set\n", ++ proc->pid, thread->pid); + binder_node_unlock(ref->node); + binder_proc_unlock(proc); + kfree(freeze); + return -EINVAL; + } +- binder_inner_proc_lock(ref->node->proc); +- is_frozen = ref->node->proc->is_frozen; +- binder_inner_proc_unlock(ref->node->proc); + + binder_stats_created(BINDER_STAT_FREEZE); + INIT_LIST_HEAD(&freeze->work.entry); + freeze->cookie = handle_cookie->cookie; + freeze->work.type = BINDER_WORK_FROZEN_BINDER; +- freeze->is_frozen = is_frozen; +- + ref->freeze = freeze; + +- binder_inner_proc_lock(proc); +- binder_enqueue_work_ilocked(&ref->freeze->work, &proc->todo); +- binder_wakeup_proc_ilocked(proc); +- binder_inner_proc_unlock(proc); ++ if (ref->node->proc) { ++ binder_inner_proc_lock(ref->node->proc); ++ freeze->is_frozen = ref->node->proc->is_frozen; ++ binder_inner_proc_unlock(ref->node->proc); ++ ++ binder_inner_proc_lock(proc); ++ binder_enqueue_work_ilocked(&freeze->work, &proc->todo); ++ binder_wakeup_proc_ilocked(proc); ++ binder_inner_proc_unlock(proc); ++ } + + binder_node_unlock(ref->node); + binder_proc_unlock(proc); +-- +2.47.1 + diff --git a/queue-6.12/binder-fix-binder_work_clear_freeze_notification-debug-logs.patch b/queue-6.12/binder-fix-binder_work_clear_freeze_notification-debug-logs.patch new file mode 100644 index 00000000000..70b3fec054d --- /dev/null +++ b/queue-6.12/binder-fix-binder_work_clear_freeze_notification-debug-logs.patch @@ -0,0 +1,50 @@ +From 595ea72efff9fa65bc52b6406e0822f90841f266 Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Thu, 26 Sep 2024 23:36:16 +0000 +Subject: binder: fix BINDER_WORK_CLEAR_FREEZE_NOTIFICATION debug logs + +From: Carlos Llamas + +commit 595ea72efff9fa65bc52b6406e0822f90841f266 upstream. + +proc 699 +context binder-test + thread 699: l 00 need_return 0 tr 0 + ref 25: desc 1 node 20 s 1 w 0 d 00000000c03e09a3 + unknown work: type 11 + +proc 640 +context binder-test + thread 640: l 00 need_return 0 tr 0 + ref 8: desc 1 node 3 s 1 w 0 d 000000002bb493e1 + has cleared freeze notification + +Fixes: d579b04a52a1 ("binder: frozen notification") +Cc: stable@vger.kernel.org +Suggested-by: Alice Ryhl +Signed-off-by: Carlos Llamas +Reviewed-by: Alice Ryhl +Acked-by: Todd Kjos +Link: https://lore.kernel.org/r/20240926233632.821189-6-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index 2be9f3559ed7..73dc6cbc1681 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -6411,6 +6411,9 @@ static void print_binder_work_ilocked(struct seq_file *m, + case BINDER_WORK_FROZEN_BINDER: + seq_printf(m, "%shas frozen binder\n", prefix); + break; ++ case BINDER_WORK_CLEAR_FREEZE_NOTIFICATION: ++ seq_printf(m, "%shas cleared freeze notification\n", prefix); ++ break; + default: + seq_printf(m, "%sunknown work: type %d\n", prefix, w->type); + break; +-- +2.47.1 + diff --git a/queue-6.12/binder-fix-binder_work_frozen_binder-debug-logs.patch b/queue-6.12/binder-fix-binder_work_frozen_binder-debug-logs.patch new file mode 100644 index 00000000000..0740335423f --- /dev/null +++ b/queue-6.12/binder-fix-binder_work_frozen_binder-debug-logs.patch @@ -0,0 +1,49 @@ +From 830d7db744b42c693bf1db7e94db86d7efd91f0e Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Thu, 26 Sep 2024 23:36:15 +0000 +Subject: binder: fix BINDER_WORK_FROZEN_BINDER debug logs + +From: Carlos Llamas + +commit 830d7db744b42c693bf1db7e94db86d7efd91f0e upstream. + +The BINDER_WORK_FROZEN_BINDER type is not handled in the binder_logs +entries and it shows up as "unknown work" when logged: + + proc 649 + context binder-test + thread 649: l 00 need_return 0 tr 0 + ref 13: desc 1 node 8 s 1 w 0 d 0000000053c4c0c3 + unknown work: type 10 + +This patch add the freeze work type and is now logged as such: + + proc 637 + context binder-test + thread 637: l 00 need_return 0 tr 0 + ref 8: desc 1 node 3 s 1 w 0 d 00000000dc39e9c6 + has frozen binder + +Fixes: d579b04a52a1 ("binder: frozen notification") +Cc: stable@vger.kernel.org +Acked-by: Todd Kjos +Signed-off-by: Carlos Llamas +Reviewed-by: Alice Ryhl +Link: https://lore.kernel.org/r/20240926233632.821189-5-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -6408,6 +6408,9 @@ static void print_binder_work_ilocked(st + case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: + seq_printf(m, "%shas cleared death notification\n", prefix); + break; ++ case BINDER_WORK_FROZEN_BINDER: ++ seq_printf(m, "%shas frozen binder\n", prefix); ++ break; + default: + seq_printf(m, "%sunknown work: type %d\n", prefix, w->type); + break; diff --git a/queue-6.12/binder-fix-freeze-uaf-in-binder_release_work.patch b/queue-6.12/binder-fix-freeze-uaf-in-binder_release_work.patch new file mode 100644 index 00000000000..4b49c5f5a80 --- /dev/null +++ b/queue-6.12/binder-fix-freeze-uaf-in-binder_release_work.patch @@ -0,0 +1,75 @@ +From 7e20434cbca814cb91a0a261ca0106815ef48e5f Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Thu, 26 Sep 2024 23:36:14 +0000 +Subject: binder: fix freeze UAF in binder_release_work() + +From: Carlos Llamas + +commit 7e20434cbca814cb91a0a261ca0106815ef48e5f upstream. + +When a binder reference is cleaned up, any freeze work queued in the +associated process should also be removed. Otherwise, the reference is +freed while its ref->freeze.work is still queued in proc->work leading +to a use-after-free issue as shown by the following KASAN report: + + ================================================================== + BUG: KASAN: slab-use-after-free in binder_release_work+0x398/0x3d0 + Read of size 8 at addr ffff31600ee91488 by task kworker/5:1/211 + + CPU: 5 UID: 0 PID: 211 Comm: kworker/5:1 Not tainted 6.11.0-rc7-00382-gfc6c92196396 #22 + Hardware name: linux,dummy-virt (DT) + Workqueue: events binder_deferred_func + Call trace: + binder_release_work+0x398/0x3d0 + binder_deferred_func+0xb60/0x109c + process_one_work+0x51c/0xbd4 + worker_thread+0x608/0xee8 + + Allocated by task 703: + __kmalloc_cache_noprof+0x130/0x280 + binder_thread_write+0xdb4/0x42a0 + binder_ioctl+0x18f0/0x25ac + __arm64_sys_ioctl+0x124/0x190 + invoke_syscall+0x6c/0x254 + + Freed by task 211: + kfree+0xc4/0x230 + binder_deferred_func+0xae8/0x109c + process_one_work+0x51c/0xbd4 + worker_thread+0x608/0xee8 + ================================================================== + +This commit fixes the issue by ensuring any queued freeze work is removed +when cleaning up a binder reference. + +Fixes: d579b04a52a1 ("binder: frozen notification") +Cc: stable@vger.kernel.org +Acked-by: Todd Kjos +Reviewed-by: Alice Ryhl +Signed-off-by: Carlos Llamas +Link: https://lore.kernel.org/r/20240926233632.821189-4-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index 8bca2de6fa24..d955135ee37a 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -1225,6 +1225,12 @@ static void binder_cleanup_ref_olocked(struct binder_ref *ref) + binder_dequeue_work(ref->proc, &ref->death->work); + binder_stats_deleted(BINDER_STAT_DEATH); + } ++ ++ if (ref->freeze) { ++ binder_dequeue_work(ref->proc, &ref->freeze->work); ++ binder_stats_deleted(BINDER_STAT_FREEZE); ++ } ++ + binder_stats_deleted(BINDER_STAT_REF); + } + +-- +2.47.1 + diff --git a/queue-6.12/binder-fix-memleak-of-proc-delivered_freeze.patch b/queue-6.12/binder-fix-memleak-of-proc-delivered_freeze.patch new file mode 100644 index 00000000000..1b12b4a1b77 --- /dev/null +++ b/queue-6.12/binder-fix-memleak-of-proc-delivered_freeze.patch @@ -0,0 +1,79 @@ +From 1db76ec2b4b206ff943e292a0b55e68ff3443598 Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Thu, 26 Sep 2024 23:36:18 +0000 +Subject: binder: fix memleak of proc->delivered_freeze + +From: Carlos Llamas + +commit 1db76ec2b4b206ff943e292a0b55e68ff3443598 upstream. + +If a freeze notification is cleared with BC_CLEAR_FREEZE_NOTIFICATION +before calling binder_freeze_notification_done(), then it is detached +from its reference (e.g. ref->freeze) but the work remains queued in +proc->delivered_freeze. This leads to a memory leak when the process +exits as any pending entries in proc->delivered_freeze are not freed: + + unreferenced object 0xffff38e8cfa36180 (size 64): + comm "binder-util", pid 655, jiffies 4294936641 + hex dump (first 32 bytes): + b8 e9 9e c8 e8 38 ff ff b8 e9 9e c8 e8 38 ff ff .....8.......8.. + 0b 00 00 00 00 00 00 00 3c 1f 4b 00 00 00 00 00 ........<.K..... + backtrace (crc 95983b32): + [<000000000d0582cf>] kmemleak_alloc+0x34/0x40 + [<000000009c99a513>] __kmalloc_cache_noprof+0x208/0x280 + [<00000000313b1704>] binder_thread_write+0xdec/0x439c + [<000000000cbd33bb>] binder_ioctl+0x1b68/0x22cc + [<000000002bbedeeb>] __arm64_sys_ioctl+0x124/0x190 + [<00000000b439adee>] invoke_syscall+0x6c/0x254 + [<00000000173558fc>] el0_svc_common.constprop.0+0xac/0x230 + [<0000000084f72311>] do_el0_svc+0x40/0x58 + [<000000008b872457>] el0_svc+0x38/0x78 + [<00000000ee778653>] el0t_64_sync_handler+0x120/0x12c + [<00000000a8ec61bf>] el0t_64_sync+0x190/0x194 + +This patch fixes the leak by ensuring that any pending entries in +proc->delivered_freeze are freed during binder_deferred_release(). + +Fixes: d579b04a52a1 ("binder: frozen notification") +Cc: stable@vger.kernel.org +Signed-off-by: Carlos Llamas +Reviewed-by: Alice Ryhl +Acked-by: Todd Kjos +Link: https://lore.kernel.org/r/20240926233632.821189-8-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index 415fc9759249..7c09b5e38e32 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -5155,6 +5155,16 @@ static void binder_release_work(struct binder_proc *proc, + } break; + case BINDER_WORK_NODE: + break; ++ case BINDER_WORK_CLEAR_FREEZE_NOTIFICATION: { ++ struct binder_ref_freeze *freeze; ++ ++ freeze = container_of(w, struct binder_ref_freeze, work); ++ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, ++ "undelivered freeze notification, %016llx\n", ++ (u64)freeze->cookie); ++ kfree(freeze); ++ binder_stats_deleted(BINDER_STAT_FREEZE); ++ } break; + default: + pr_err("unexpected work type, %d, not freed\n", + wtype); +@@ -6273,6 +6283,7 @@ static void binder_deferred_release(struct binder_proc *proc) + + binder_release_work(proc, &proc->todo); + binder_release_work(proc, &proc->delivered_death); ++ binder_release_work(proc, &proc->delivered_freeze); + + binder_debug(BINDER_DEBUG_OPEN_CLOSE, + "%s: %d threads %d, nodes %d (ref %d), refs %d, active transactions %d\n", +-- +2.47.1 + diff --git a/queue-6.12/binder-fix-node-uaf-in-binder_add_freeze_work.patch b/queue-6.12/binder-fix-node-uaf-in-binder_add_freeze_work.patch new file mode 100644 index 00000000000..eca062633b8 --- /dev/null +++ b/queue-6.12/binder-fix-node-uaf-in-binder_add_freeze_work.patch @@ -0,0 +1,96 @@ +From dc8aea47b928cc153b591b3558829ce42f685074 Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Thu, 26 Sep 2024 23:36:12 +0000 +Subject: binder: fix node UAF in binder_add_freeze_work() + +From: Carlos Llamas + +commit dc8aea47b928cc153b591b3558829ce42f685074 upstream. + +In binder_add_freeze_work() we iterate over the proc->nodes with the +proc->inner_lock held. However, this lock is temporarily dropped in +order to acquire the node->lock first (lock nesting order). This can +race with binder_node_release() and trigger a use-after-free: + + ================================================================== + BUG: KASAN: slab-use-after-free in _raw_spin_lock+0xe4/0x19c + Write of size 4 at addr ffff53c04c29dd04 by task freeze/640 + + CPU: 5 UID: 0 PID: 640 Comm: freeze Not tainted 6.11.0-07343-ga727812a8d45 #17 + Hardware name: linux,dummy-virt (DT) + Call trace: + _raw_spin_lock+0xe4/0x19c + binder_add_freeze_work+0x148/0x478 + binder_ioctl+0x1e70/0x25ac + __arm64_sys_ioctl+0x124/0x190 + + Allocated by task 637: + __kmalloc_cache_noprof+0x12c/0x27c + binder_new_node+0x50/0x700 + binder_transaction+0x35ac/0x6f74 + binder_thread_write+0xfb8/0x42a0 + binder_ioctl+0x18f0/0x25ac + __arm64_sys_ioctl+0x124/0x190 + + Freed by task 637: + kfree+0xf0/0x330 + binder_thread_read+0x1e88/0x3a68 + binder_ioctl+0x16d8/0x25ac + __arm64_sys_ioctl+0x124/0x190 + ================================================================== + +Fix the race by taking a temporary reference on the node before +releasing the proc->inner lock. This ensures the node remains alive +while in use. + +Fixes: d579b04a52a1 ("binder: frozen notification") +Cc: stable@vger.kernel.org +Reviewed-by: Alice Ryhl +Acked-by: Todd Kjos +Signed-off-by: Carlos Llamas +Link: https://lore.kernel.org/r/20240926233632.821189-2-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index 978740537a1a..4d90203ea048 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -5552,6 +5552,7 @@ static bool binder_txns_pending_ilocked(struct binder_proc *proc) + + static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen) + { ++ struct binder_node *prev = NULL; + struct rb_node *n; + struct binder_ref *ref; + +@@ -5560,7 +5561,10 @@ static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen) + struct binder_node *node; + + node = rb_entry(n, struct binder_node, rb_node); ++ binder_inc_node_tmpref_ilocked(node); + binder_inner_proc_unlock(proc); ++ if (prev) ++ binder_put_node(prev); + binder_node_lock(node); + hlist_for_each_entry(ref, &node->refs, node_entry) { + /* +@@ -5586,10 +5590,13 @@ static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen) + } + binder_inner_proc_unlock(ref->proc); + } ++ prev = node; + binder_node_unlock(node); + binder_inner_proc_lock(proc); + } + binder_inner_proc_unlock(proc); ++ if (prev) ++ binder_put_node(prev); + } + + static int binder_ioctl_freeze(struct binder_freeze_info *info, +-- +2.47.1 + diff --git a/queue-6.12/binder-fix-oob-in-binder_add_freeze_work.patch b/queue-6.12/binder-fix-oob-in-binder_add_freeze_work.patch new file mode 100644 index 00000000000..2c08d68323a --- /dev/null +++ b/queue-6.12/binder-fix-oob-in-binder_add_freeze_work.patch @@ -0,0 +1,74 @@ +From 011e69a1b23011c0db3af4b8293fdd4522cc97b0 Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Thu, 26 Sep 2024 23:36:13 +0000 +Subject: binder: fix OOB in binder_add_freeze_work() + +From: Carlos Llamas + +commit 011e69a1b23011c0db3af4b8293fdd4522cc97b0 upstream. + +In binder_add_freeze_work() we iterate over the proc->nodes with the +proc->inner_lock held. However, this lock is temporarily dropped to +acquire the node->lock first (lock nesting order). This can race with +binder_deferred_release() which removes the nodes from the proc->nodes +rbtree and adds them into binder_dead_nodes list. This leads to a broken +iteration in binder_add_freeze_work() as rb_next() will use data from +binder_dead_nodes, triggering an out-of-bounds access: + + ================================================================== + BUG: KASAN: global-out-of-bounds in rb_next+0xfc/0x124 + Read of size 8 at addr ffffcb84285f7170 by task freeze/660 + + CPU: 8 UID: 0 PID: 660 Comm: freeze Not tainted 6.11.0-07343-ga727812a8d45 #18 + Hardware name: linux,dummy-virt (DT) + Call trace: + rb_next+0xfc/0x124 + binder_add_freeze_work+0x344/0x534 + binder_ioctl+0x1e70/0x25ac + __arm64_sys_ioctl+0x124/0x190 + + The buggy address belongs to the variable: + binder_dead_nodes+0x10/0x40 + [...] + ================================================================== + +This is possible because proc->nodes (rbtree) and binder_dead_nodes +(list) share entries in binder_node through a union: + + struct binder_node { + [...] + union { + struct rb_node rb_node; + struct hlist_node dead_node; + }; + +Fix the race by checking that the proc is still alive. If not, simply +break out of the iteration. + +Fixes: d579b04a52a1 ("binder: frozen notification") +Cc: stable@vger.kernel.org +Reviewed-by: Alice Ryhl +Acked-by: Todd Kjos +Signed-off-by: Carlos Llamas +Link: https://lore.kernel.org/r/20240926233632.821189-3-cmllamas@google.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/android/binder.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index 4d90203ea048..8bca2de6fa24 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -5593,6 +5593,8 @@ static void binder_add_freeze_work(struct binder_proc *proc, bool is_frozen) + prev = node; + binder_node_unlock(node); + binder_inner_proc_lock(proc); ++ if (proc->is_dead) ++ break; + } + binder_inner_proc_unlock(proc); + if (prev) +-- +2.47.1 + diff --git a/queue-6.12/dm-fix-typo-in-error-message.patch b/queue-6.12/dm-fix-typo-in-error-message.patch new file mode 100644 index 00000000000..357d4934e31 --- /dev/null +++ b/queue-6.12/dm-fix-typo-in-error-message.patch @@ -0,0 +1,33 @@ +From 2deb70d3e66d538404d9e71bff236e6d260da66e Mon Sep 17 00:00:00 2001 +From: Ssuhung Yeh +Date: Thu, 31 Oct 2024 18:25:59 +0800 +Subject: dm: Fix typo in error message + +From: Ssuhung Yeh + +commit 2deb70d3e66d538404d9e71bff236e6d260da66e upstream. + +Remove the redundant "i" at the beginning of the error message. This "i" +came from commit 1c1318866928 ("dm: prefer +'"%s...", __func__'"), the "i" is accidentally left. + +Signed-off-by: Ssuhung Yeh +Signed-off-by: Mikulas Patocka +Fixes: 1c1318866928 ("dm: prefer '"%s...", __func__'") +Cc: stable@vger.kernel.org # v6.3+ +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/persistent-data/dm-space-map-common.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/md/persistent-data/dm-space-map-common.c ++++ b/drivers/md/persistent-data/dm-space-map-common.c +@@ -51,7 +51,7 @@ static int index_check(const struct dm_b + block_size - sizeof(__le32), + INDEX_CSUM_XOR)); + if (csum_disk != mi_le->csum) { +- DMERR_LIMIT("i%s failed: csum %u != wanted %u", __func__, ++ DMERR_LIMIT("%s failed: csum %u != wanted %u", __func__, + le32_to_cpu(csum_disk), le32_to_cpu(mi_le->csum)); + return -EILSEQ; + } diff --git a/queue-6.12/dm-thin-add-missing-destroy_work_on_stack.patch b/queue-6.12/dm-thin-add-missing-destroy_work_on_stack.patch new file mode 100644 index 00000000000..fac7ebe763f --- /dev/null +++ b/queue-6.12/dm-thin-add-missing-destroy_work_on_stack.patch @@ -0,0 +1,31 @@ +From e74fa2447bf9ed03d085b6d91f0256cc1b53f1a8 Mon Sep 17 00:00:00 2001 +From: Yuan Can +Date: Wed, 6 Nov 2024 09:03:12 +0800 +Subject: dm thin: Add missing destroy_work_on_stack() + +From: Yuan Can + +commit e74fa2447bf9ed03d085b6d91f0256cc1b53f1a8 upstream. + +This commit add missed destroy_work_on_stack() operations for pw->worker in +pool_work_wait(). + +Fixes: e7a3e871d895 ("dm thin: cleanup noflush_work to use a proper completion") +Cc: stable@vger.kernel.org +Signed-off-by: Yuan Can +Signed-off-by: Mikulas Patocka +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-thin.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -2484,6 +2484,7 @@ static void pool_work_wait(struct pool_w + init_completion(&pw->complete); + queue_work(pool->wq, &pw->worker); + wait_for_completion(&pw->complete); ++ destroy_work_on_stack(&pw->worker); + } + + /*----------------------------------------------------------------*/ diff --git a/queue-6.12/fs-proc-kcore.c-clear-ret-value-in-read_kcore_iter-after-successful-iov_iter_zero.patch b/queue-6.12/fs-proc-kcore.c-clear-ret-value-in-read_kcore_iter-after-successful-iov_iter_zero.patch new file mode 100644 index 00000000000..acec231c1d6 --- /dev/null +++ b/queue-6.12/fs-proc-kcore.c-clear-ret-value-in-read_kcore_iter-after-successful-iov_iter_zero.patch @@ -0,0 +1,37 @@ +From 088f294609d8f8816dc316681aef2eb61982e0da Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Fri, 22 Nov 2024 00:11:18 +0100 +Subject: fs/proc/kcore.c: Clear ret value in read_kcore_iter after successful iov_iter_zero + +From: Jiri Olsa + +commit 088f294609d8f8816dc316681aef2eb61982e0da upstream. + +If iov_iter_zero succeeds after failed copy_from_kernel_nofault, +we need to reset the ret value to zero otherwise it will be returned +as final return value of read_kcore_iter. + +This fixes objdump -d dump over /proc/kcore for me. + +Cc: stable@vger.kernel.org +Cc: Alexander Gordeev +Fixes: 3d5854d75e31 ("fs/proc/kcore.c: allow translation of physical memory addresses") +Signed-off-by: Jiri Olsa +Link: https://lore.kernel.org/r/20241121231118.3212000-1-jolsa@kernel.org +Acked-by: Alexander Gordeev +Signed-off-by: Christian Brauner +Signed-off-by: Greg Kroah-Hartman +--- + fs/proc/kcore.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/proc/kcore.c ++++ b/fs/proc/kcore.c +@@ -600,6 +600,7 @@ static ssize_t read_kcore_iter(struct ki + ret = -EFAULT; + goto out; + } ++ ret = 0; + /* + * We know the bounce buffer is safe to copy from, so + * use _copy_to_iter() directly. diff --git a/queue-6.12/i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch b/queue-6.12/i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch new file mode 100644 index 00000000000..36bf07cb9f5 --- /dev/null +++ b/queue-6.12/i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch @@ -0,0 +1,38 @@ +From 3082990592f7c6d7510a9133afa46e31bbe26533 Mon Sep 17 00:00:00 2001 +From: Frank Li +Date: Tue, 1 Oct 2024 12:26:08 -0400 +Subject: i3c: master: Fix miss free init_dyn_addr at i3c_master_put_i3c_addrs() + +From: Frank Li + +commit 3082990592f7c6d7510a9133afa46e31bbe26533 upstream. + +if (dev->boardinfo && dev->boardinfo->init_dyn_addr) + ^^^ here check "init_dyn_addr" + i3c_bus_set_addr_slot_status(&master->bus, dev->info.dyn_addr, ...) + ^^^^ + free "dyn_addr" +Fix copy/paste error "dyn_addr" by replacing it with "init_dyn_addr". + +Cc: stable@kernel.org +Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") +Reviewed-by: Miquel Raynal +Signed-off-by: Frank Li +Link: https://lore.kernel.org/r/20241001162608.224039-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i3c/master.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -1417,7 +1417,7 @@ static void i3c_master_put_i3c_addrs(str + I3C_ADDR_SLOT_FREE); + + if (dev->boardinfo && dev->boardinfo->init_dyn_addr) +- i3c_bus_set_addr_slot_status(&master->bus, dev->info.dyn_addr, ++ i3c_bus_set_addr_slot_status(&master->bus, dev->boardinfo->init_dyn_addr, + I3C_ADDR_SLOT_FREE); + } + diff --git a/queue-6.12/i3c-master-svc-fix-pm_runtime_set_suspended-with-runtime-pm-enabled.patch b/queue-6.12/i3c-master-svc-fix-pm_runtime_set_suspended-with-runtime-pm-enabled.patch new file mode 100644 index 00000000000..bf4dea89037 --- /dev/null +++ b/queue-6.12/i3c-master-svc-fix-pm_runtime_set_suspended-with-runtime-pm-enabled.patch @@ -0,0 +1,37 @@ +From 18599e93e4e814ce146186026c6abf83c14d5798 Mon Sep 17 00:00:00 2001 +From: Jinjie Ruan +Date: Mon, 30 Sep 2024 17:19:13 +0800 +Subject: i3c: master: svc: Fix pm_runtime_set_suspended() with runtime pm enabled + +From: Jinjie Ruan + +commit 18599e93e4e814ce146186026c6abf83c14d5798 upstream. + +It is not valid to call pm_runtime_set_suspended() for devices +with runtime PM enabled because it returns -EAGAIN if it is enabled +already and working. So, call pm_runtime_disable() before to fix it. + +Cc: stable@vger.kernel.org # v5.17 +Fixes: 05be23ef78f7 ("i3c: master: svc: add runtime pm support") +Reviewed-by: Frank Li +Reviewed-by: Miquel Raynal +Signed-off-by: Jinjie Ruan +Link: https://lore.kernel.org/r/20240930091913.2545510-1-ruanjinjie@huawei.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i3c/master/svc-i3c-master.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -1827,8 +1827,8 @@ static int svc_i3c_master_probe(struct p + rpm_disable: + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); +- pm_runtime_set_suspended(&pdev->dev); + pm_runtime_disable(&pdev->dev); ++ pm_runtime_set_suspended(&pdev->dev); + + err_disable_clks: + svc_i3c_master_unprepare_clks(master); diff --git a/queue-6.12/i3c-master-svc-fix-possible-assignment-of-the-same-address-to-two-devices.patch b/queue-6.12/i3c-master-svc-fix-possible-assignment-of-the-same-address-to-two-devices.patch new file mode 100644 index 00000000000..4d24930f8bd --- /dev/null +++ b/queue-6.12/i3c-master-svc-fix-possible-assignment-of-the-same-address-to-two-devices.patch @@ -0,0 +1,81 @@ +From 3b2ac810d86eb96e882db80a3320a3848b133208 Mon Sep 17 00:00:00 2001 +From: Frank Li +Date: Wed, 2 Oct 2024 10:50:38 -0400 +Subject: i3c: master: svc: fix possible assignment of the same address to two devices + +From: Frank Li + +commit 3b2ac810d86eb96e882db80a3320a3848b133208 upstream. + +svc_i3c_master_do_daa() { + ... + for (i = 0; i < dev_nb; i++) { + ret = i3c_master_add_i3c_dev_locked(m, addrs[i]); + if (ret) + goto rpm_out; + } +} + +If two devices (A and B) are detected in DAA and address 0xa is assigned to +device A and 0xb to device B, a failure in i3c_master_add_i3c_dev_locked() +for device A (addr: 0xa) could prevent device B (addr: 0xb) from being +registered on the bus. The I3C stack might still consider 0xb a free +address. If a subsequent Hotjoin occurs, 0xb might be assigned to Device A, +causing both devices A and B to use the same address 0xb, violating the I3C +specification. + +The return value for i3c_master_add_i3c_dev_locked() should not be checked +because subsequent steps will scan the entire I3C bus, independent of +whether i3c_master_add_i3c_dev_locked() returns success. + +If device A registration fails, there is still a chance to register device +B. i3c_master_add_i3c_dev_locked() can reset DAA if a failure occurs while +retrieving device information. + +Cc: stable@kernel.org +Fixes: 317bacf960a4 ("i3c: master: add enable(disable) hot join in sys entry") +Reviewed-by: Miquel Raynal +Signed-off-by: Frank Li +Link: https://lore.kernel.org/r/20241002-svc-i3c-hj-v6-6-7e6e1d3569ae@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i3c/master/svc-i3c-master.c | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -1056,12 +1056,27 @@ static int svc_i3c_master_do_daa(struct + if (ret) + goto rpm_out; + +- /* Register all devices who participated to the core */ +- for (i = 0; i < dev_nb; i++) { +- ret = i3c_master_add_i3c_dev_locked(m, addrs[i]); +- if (ret) +- goto rpm_out; +- } ++ /* ++ * Register all devices who participated to the core ++ * ++ * If two devices (A and B) are detected in DAA and address 0xa is assigned to ++ * device A and 0xb to device B, a failure in i3c_master_add_i3c_dev_locked() ++ * for device A (addr: 0xa) could prevent device B (addr: 0xb) from being ++ * registered on the bus. The I3C stack might still consider 0xb a free ++ * address. If a subsequent Hotjoin occurs, 0xb might be assigned to Device A, ++ * causing both devices A and B to use the same address 0xb, violating the I3C ++ * specification. ++ * ++ * The return value for i3c_master_add_i3c_dev_locked() should not be checked ++ * because subsequent steps will scan the entire I3C bus, independent of ++ * whether i3c_master_add_i3c_dev_locked() returns success. ++ * ++ * If device A registration fails, there is still a chance to register device ++ * B. i3c_master_add_i3c_dev_locked() can reset DAA if a failure occurs while ++ * retrieving device information. ++ */ ++ for (i = 0; i < dev_nb; i++) ++ i3c_master_add_i3c_dev_locked(m, addrs[i]); + + /* Configure IBI auto-rules */ + ret = svc_i3c_update_ibirules(master); diff --git a/queue-6.12/i3c-master-svc-modify-enabled_events-bit-7-0-to-act-as-ibi-enable-counter.patch b/queue-6.12/i3c-master-svc-modify-enabled_events-bit-7-0-to-act-as-ibi-enable-counter.patch new file mode 100644 index 00000000000..7f7b93b1ce0 --- /dev/null +++ b/queue-6.12/i3c-master-svc-modify-enabled_events-bit-7-0-to-act-as-ibi-enable-counter.patch @@ -0,0 +1,65 @@ +From 25bc99be5fe53853053ceeaa328068c49dc1e799 Mon Sep 17 00:00:00 2001 +From: Frank Li +Date: Fri, 1 Nov 2024 12:50:02 -0400 +Subject: i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter + +From: Frank Li + +commit 25bc99be5fe53853053ceeaa328068c49dc1e799 upstream. + +Fix issue where disabling IBI on one device disables the entire IBI +interrupt. Modify bit 7:0 of enabled_events to serve as an IBI enable +counter, ensuring that the system IBI interrupt is disabled only when all +I3C devices have IBI disabled. + +Cc: stable@kernel.org +Fixes: 7ff730ca458e ("i3c: master: svc: enable the interrupt in the enable ibi function") +Reviewed-by: Miquel Raynal +Signed-off-by: Frank Li +Link: https://lore.kernel.org/r/20241101165002.2479794-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i3c/master/svc-i3c-master.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -130,8 +130,8 @@ + #define SVC_I3C_PPBAUD_MAX 15 + #define SVC_I3C_QUICK_I2C_CLK 4170000 + +-#define SVC_I3C_EVENT_IBI BIT(0) +-#define SVC_I3C_EVENT_HOTJOIN BIT(1) ++#define SVC_I3C_EVENT_IBI GENMASK(7, 0) ++#define SVC_I3C_EVENT_HOTJOIN BIT(31) + + struct svc_i3c_cmd { + u8 addr; +@@ -214,7 +214,7 @@ struct svc_i3c_master { + spinlock_t lock; + } ibi; + struct mutex lock; +- int enabled_events; ++ u32 enabled_events; + u32 mctrl_config; + }; + +@@ -1639,7 +1639,7 @@ static int svc_i3c_master_enable_ibi(str + return ret; + } + +- master->enabled_events |= SVC_I3C_EVENT_IBI; ++ master->enabled_events++; + svc_i3c_master_enable_interrupts(master, SVC_I3C_MINT_SLVSTART); + + return i3c_master_enec_locked(m, dev->info.dyn_addr, I3C_CCC_EVENT_SIR); +@@ -1651,7 +1651,7 @@ static int svc_i3c_master_disable_ibi(st + struct svc_i3c_master *master = to_svc_i3c_master(m); + int ret; + +- master->enabled_events &= ~SVC_I3C_EVENT_IBI; ++ master->enabled_events--; + if (!master->enabled_events) + svc_i3c_master_disable_interrupts(master); + diff --git a/queue-6.12/iio-accel-kx022a-fix-raw-read-format.patch b/queue-6.12/iio-accel-kx022a-fix-raw-read-format.patch new file mode 100644 index 00000000000..1e26ffd9842 --- /dev/null +++ b/queue-6.12/iio-accel-kx022a-fix-raw-read-format.patch @@ -0,0 +1,58 @@ +From b7d2bc99b3bdc03fff9b416dd830632346d83530 Mon Sep 17 00:00:00 2001 +From: Matti Vaittinen +Date: Wed, 30 Oct 2024 15:16:11 +0200 +Subject: iio: accel: kx022a: Fix raw read format + +From: Matti Vaittinen + +commit b7d2bc99b3bdc03fff9b416dd830632346d83530 upstream. + +The KX022A provides the accelerometer data in two subsequent registers. +The registers are laid out so that the value obtained via bulk-read of +these registers can be interpreted as signed 16-bit little endian value. +The read value is converted to cpu_endianes and stored into 32bit integer. +The le16_to_cpu() casts value to unsigned 16-bit value, and when this is +assigned to 32-bit integer the resulting value will always be positive. + +This has not been a problem to users (at least not all users) of the sysfs +interface, who know the data format based on the scan info and who have +converted the read value back to 16-bit signed value. This isn't +compliant with the ABI however. + +This, however, will be a problem for those who use the in-kernel +interfaces, especially the iio_read_channel_processed_scale(). + +The iio_read_channel_processed_scale() performs multiplications to the +returned (always positive) raw value, which will cause strange results +when the data from the sensor has been negative. + +Fix the read_raw format by casting the result of the le_to_cpu() to +signed 16-bit value before assigning it to the integer. This will make +the negative readings to be correctly reported as negative. + +This fix will be visible to users by changing values returned via sysfs +to appear in correct (negative) format. + +Reported-by: Kalle Niemi +Fixes: 7c1d1677b322 ("iio: accel: Support Kionix/ROHM KX022A accelerometer") +Signed-off-by: Matti Vaittinen +Tested-by: Kalle Niemi +Cc: +Link: https://patch.msgid.link/ZyIxm_zamZfIGrnB@mva-rohm +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/accel/kionix-kx022a.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/accel/kionix-kx022a.c ++++ b/drivers/iio/accel/kionix-kx022a.c +@@ -594,7 +594,7 @@ static int kx022a_get_axis(struct kx022a + if (ret) + return ret; + +- *val = le16_to_cpu(data->buffer[0]); ++ *val = (s16)le16_to_cpu(data->buffer[0]); + + return IIO_VAL_INT; + } diff --git a/queue-6.12/iio-adc-ad7923-fix-buffer-overflow-for-tx_buf-and-ring_xfer.patch b/queue-6.12/iio-adc-ad7923-fix-buffer-overflow-for-tx_buf-and-ring_xfer.patch new file mode 100644 index 00000000000..14ccb9d05ab --- /dev/null +++ b/queue-6.12/iio-adc-ad7923-fix-buffer-overflow-for-tx_buf-and-ring_xfer.patch @@ -0,0 +1,44 @@ +From 3a4187ec454e19903fd15f6e1825a4b84e59a4cd Mon Sep 17 00:00:00 2001 +From: Nuno Sa +Date: Tue, 29 Oct 2024 13:46:37 +0000 +Subject: iio: adc: ad7923: Fix buffer overflow for tx_buf and ring_xfer + +From: Nuno Sa + +commit 3a4187ec454e19903fd15f6e1825a4b84e59a4cd upstream. + +The AD7923 was updated to support devices with 8 channels, but the size +of tx_buf and ring_xfer was not increased accordingly, leading to a +potential buffer overflow in ad7923_update_scan_mode(). + +Fixes: 851644a60d20 ("iio: adc: ad7923: Add support for the ad7908/ad7918/ad7928") +Cc: stable@vger.kernel.org +Signed-off-by: Nuno Sa +Signed-off-by: Zicheng Qu +Link: https://patch.msgid.link/20241029134637.2261336-1-quzicheng@huawei.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ad7923.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/iio/adc/ad7923.c ++++ b/drivers/iio/adc/ad7923.c +@@ -48,7 +48,7 @@ + + struct ad7923_state { + struct spi_device *spi; +- struct spi_transfer ring_xfer[5]; ++ struct spi_transfer ring_xfer[9]; + struct spi_transfer scan_single_xfer[2]; + struct spi_message ring_msg; + struct spi_message scan_single_msg; +@@ -64,7 +64,7 @@ struct ad7923_state { + * Length = 8 channels + 4 extra for 8 byte timestamp + */ + __be16 rx_buf[12] __aligned(IIO_DMA_MINALIGN); +- __be16 tx_buf[4]; ++ __be16 tx_buf[8]; + }; + + struct ad7923_chip_info { diff --git a/queue-6.12/iio-fix-fwnode_handle-in-__fwnode_iio_channel_get_by_name.patch b/queue-6.12/iio-fix-fwnode_handle-in-__fwnode_iio_channel_get_by_name.patch new file mode 100644 index 00000000000..b222651bf5d --- /dev/null +++ b/queue-6.12/iio-fix-fwnode_handle-in-__fwnode_iio_channel_get_by_name.patch @@ -0,0 +1,37 @@ +From 3993ca4add248f0f853f54f9273a7de850639f33 Mon Sep 17 00:00:00 2001 +From: Zicheng Qu +Date: Sat, 2 Nov 2024 09:25:25 +0000 +Subject: iio: Fix fwnode_handle in __fwnode_iio_channel_get_by_name() + +From: Zicheng Qu + +commit 3993ca4add248f0f853f54f9273a7de850639f33 upstream. + +In the fwnode_iio_channel_get_by_name(), iterating over parent nodes to +acquire IIO channels via fwnode_for_each_parent_node(). The variable +chan was mistakenly attempted on the original node instead of the +current parent node. This patch corrects the logic to ensure that +__fwnode_iio_channel_get_by_name() is called with the correct parent +node. + +Cc: stable@vger.kernel.org # v6.6+ +Fixes: 1e64b9c5f9a0 ("iio: inkern: move to fwnode properties") +Signed-off-by: Zicheng Qu +Link: https://patch.msgid.link/20241102092525.2389952-1-quzicheng@huawei.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/inkern.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/inkern.c ++++ b/drivers/iio/inkern.c +@@ -269,7 +269,7 @@ struct iio_channel *fwnode_iio_channel_g + return ERR_PTR(-ENODEV); + } + +- chan = __fwnode_iio_channel_get_by_name(fwnode, name); ++ chan = __fwnode_iio_channel_get_by_name(parent, name); + if (!IS_ERR(chan) || PTR_ERR(chan) != -ENODEV) { + fwnode_handle_put(parent); + return chan; diff --git a/queue-6.12/iio-gts-fix-infinite-loop-for-gain_to_scaletables.patch b/queue-6.12/iio-gts-fix-infinite-loop-for-gain_to_scaletables.patch new file mode 100644 index 00000000000..40c37892916 --- /dev/null +++ b/queue-6.12/iio-gts-fix-infinite-loop-for-gain_to_scaletables.patch @@ -0,0 +1,37 @@ +From 7452f8a0814bb73f739ee0dab60f099f3361b151 Mon Sep 17 00:00:00 2001 +From: Zicheng Qu +Date: Thu, 31 Oct 2024 01:46:26 +0000 +Subject: iio: gts: fix infinite loop for gain_to_scaletables() + +From: Zicheng Qu + +commit 7452f8a0814bb73f739ee0dab60f099f3361b151 upstream. + +In iio_gts_build_avail_time_table(), it is checked that gts->num_itime is +non-zero, but gts->num_itime is not checked in gain_to_scaletables(). The +variable time_idx is initialized as gts->num_itime - 1. This implies that +time_idx might initially be set to -1 (0 - 1 = -1). Consequently, using +while (time_idx--) could lead to an infinite loop. + +Cc: stable@vger.kernel.org # v6.6+ +Fixes: 38416c28e168 ("iio: light: Add gain-time-scale helpers") +Signed-off-by: Zicheng Qu +Reviewed-by: Matti Vaittinen +Link: https://patch.msgid.link/20241031014626.2313077-1-quzicheng@huawei.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/industrialio-gts-helper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/industrialio-gts-helper.c ++++ b/drivers/iio/industrialio-gts-helper.c +@@ -205,7 +205,7 @@ static int gain_to_scaletables(struct ii + memcpy(all_gains, gains[time_idx], gain_bytes); + new_idx = gts->num_hwgain; + +- while (time_idx--) { ++ while (time_idx-- > 0) { + for (j = 0; j < gts->num_hwgain; j++) { + int candidate = gains[time_idx][j]; + int chk; diff --git a/queue-6.12/iio-invensense-fix-multiple-odr-switch-when-fifo-is-off.patch b/queue-6.12/iio-invensense-fix-multiple-odr-switch-when-fifo-is-off.patch new file mode 100644 index 00000000000..f175e3e92c0 --- /dev/null +++ b/queue-6.12/iio-invensense-fix-multiple-odr-switch-when-fifo-is-off.patch @@ -0,0 +1,93 @@ +From ef5f5e7b6f73f79538892a8be3a3bee2342acc9f Mon Sep 17 00:00:00 2001 +From: Jean-Baptiste Maneyrol +Date: Mon, 21 Oct 2024 10:38:42 +0200 +Subject: iio: invensense: fix multiple odr switch when FIFO is off + +From: Jean-Baptiste Maneyrol + +commit ef5f5e7b6f73f79538892a8be3a3bee2342acc9f upstream. + +When multiple ODR switch happens during FIFO off, the change could +not be taken into account if you get back to previous FIFO on value. +For example, if you run sensor buffer at 50Hz, stop, change to +200Hz, then back to 50Hz and restart buffer, data will be timestamped +at 200Hz. This due to testing against mult and not new_mult. + +To prevent this, let's just run apply_odr automatically when FIFO is +off. It will also simplify driver code. + +Update inv_mpu6050 and inv_icm42600 to delete now useless apply_odr. + +Fixes: 95444b9eeb8c ("iio: invensense: fix odr switching to same value") +Cc: stable@vger.kernel.org +Signed-off-by: Jean-Baptiste Maneyrol +Link: https://patch.msgid.link/20241021-invn-inv-sensors-timestamp-fix-switch-fifo-off-v2-1-39ffd43edcc4@tdk.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/common/inv_sensors/inv_sensors_timestamp.c | 4 ++++ + drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 2 -- + drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 3 --- + drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 1 - + 4 files changed, 4 insertions(+), 6 deletions(-) + +--- a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c ++++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c +@@ -70,6 +70,10 @@ int inv_sensors_timestamp_update_odr(str + if (mult != ts->mult) + ts->new_mult = mult; + ++ /* When FIFO is off, directly apply the new ODR */ ++ if (!fifo) ++ inv_sensors_timestamp_apply_odr(ts, 0, 0, 0); ++ + return 0; + } + EXPORT_SYMBOL_NS_GPL(inv_sensors_timestamp_update_odr, IIO_INV_SENSORS_TIMESTAMP); +--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c ++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +@@ -200,7 +200,6 @@ static int inv_icm42600_accel_update_sca + { + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev); +- struct inv_sensors_timestamp *ts = &accel_st->ts; + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + unsigned int fifo_en = 0; + unsigned int sleep_temp = 0; +@@ -229,7 +228,6 @@ static int inv_icm42600_accel_update_sca + } + + /* update data FIFO write */ +- inv_sensors_timestamp_apply_odr(ts, 0, 0, 0); + ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); + + out_unlock: +--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c ++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +@@ -99,8 +99,6 @@ static int inv_icm42600_gyro_update_scan + const unsigned long *scan_mask) + { + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); +- struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev); +- struct inv_sensors_timestamp *ts = &gyro_st->ts; + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + unsigned int fifo_en = 0; + unsigned int sleep_gyro = 0; +@@ -128,7 +126,6 @@ static int inv_icm42600_gyro_update_scan + } + + /* update data FIFO write */ +- inv_sensors_timestamp_apply_odr(ts, 0, 0, 0); + ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); + + out_unlock: +--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c ++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c +@@ -112,7 +112,6 @@ int inv_mpu6050_prepare_fifo(struct inv_ + if (enable) { + /* reset timestamping */ + inv_sensors_timestamp_reset(&st->timestamp); +- inv_sensors_timestamp_apply_odr(&st->timestamp, 0, 0, 0); + /* reset FIFO */ + d = st->chip_config.user_ctrl | INV_MPU6050_BIT_FIFO_RST; + ret = regmap_write(st->map, st->reg->user_ctrl, d); diff --git a/queue-6.12/leds-flash-mt6360-fix-device_for_each_child_node-refcounting-in-error-paths.patch b/queue-6.12/leds-flash-mt6360-fix-device_for_each_child_node-refcounting-in-error-paths.patch new file mode 100644 index 00000000000..c5ff4f52ce7 --- /dev/null +++ b/queue-6.12/leds-flash-mt6360-fix-device_for_each_child_node-refcounting-in-error-paths.patch @@ -0,0 +1,50 @@ +From 73b03b27736e440e3009fe1319cbc82d2cd1290c Mon Sep 17 00:00:00 2001 +From: Javier Carrasco +Date: Fri, 27 Sep 2024 01:20:52 +0200 +Subject: leds: flash: mt6360: Fix device_for_each_child_node() refcounting in error paths + +From: Javier Carrasco + +commit 73b03b27736e440e3009fe1319cbc82d2cd1290c upstream. + +The device_for_each_child_node() macro requires explicit calls to +fwnode_handle_put() upon early exits to avoid memory leaks, and in +this case the error paths are handled after jumping to +'out_flash_realease', which misses that required call to +to decrement the refcount of the child node. + +A more elegant and robust solution is using the scoped variant of the +loop, which automatically handles such early exits. + +Fix the child node refcounting in the error paths by using +device_for_each_child_node_scoped(). + +Cc: stable@vger.kernel.org +Fixes: 679f8652064b ("leds: Add mt6360 driver") +Signed-off-by: Javier Carrasco +Link: https://lore.kernel.org/r/20240927-leds_device_for_each_child_node_scoped-v1-1-95c0614b38c8@gmail.com +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/leds/flash/leds-mt6360.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/leds/flash/leds-mt6360.c ++++ b/drivers/leds/flash/leds-mt6360.c +@@ -784,7 +784,6 @@ static void mt6360_v4l2_flash_release(st + static int mt6360_led_probe(struct platform_device *pdev) + { + struct mt6360_priv *priv; +- struct fwnode_handle *child; + size_t count; + int i = 0, ret; + +@@ -811,7 +810,7 @@ static int mt6360_led_probe(struct platf + return -ENODEV; + } + +- device_for_each_child_node(&pdev->dev, child) { ++ device_for_each_child_node_scoped(&pdev->dev, child) { + struct mt6360_led *led = priv->leds + i; + struct led_init_data init_data = { .fwnode = child, }; + u32 reg, led_color; diff --git a/queue-6.12/mm-vmalloc-combine-all-tlb-flush-operations-of-kasan-shadow-virtual-address-into-one-operation.patch b/queue-6.12/mm-vmalloc-combine-all-tlb-flush-operations-of-kasan-shadow-virtual-address-into-one-operation.patch new file mode 100644 index 00000000000..cc8bff73970 --- /dev/null +++ b/queue-6.12/mm-vmalloc-combine-all-tlb-flush-operations-of-kasan-shadow-virtual-address-into-one-operation.patch @@ -0,0 +1,337 @@ +From 9e9e085effe9b7e342138fde3cf8577d22509932 Mon Sep 17 00:00:00 2001 +From: Adrian Huang +Date: Sat, 27 Jul 2024 00:52:46 +0800 +Subject: mm/vmalloc: combine all TLB flush operations of KASAN shadow virtual address into one operation + +From: Adrian Huang + +commit 9e9e085effe9b7e342138fde3cf8577d22509932 upstream. + +When compiling kernel source 'make -j $(nproc)' with the up-and-running +KASAN-enabled kernel on a 256-core machine, the following soft lockup is +shown: + +watchdog: BUG: soft lockup - CPU#28 stuck for 22s! [kworker/28:1:1760] +CPU: 28 PID: 1760 Comm: kworker/28:1 Kdump: loaded Not tainted 6.10.0-rc5 #95 +Workqueue: events drain_vmap_area_work +RIP: 0010:smp_call_function_many_cond+0x1d8/0xbb0 +Code: 38 c8 7c 08 84 c9 0f 85 49 08 00 00 8b 45 08 a8 01 74 2e 48 89 f1 49 89 f7 48 c1 e9 03 41 83 e7 07 4c 01 e9 41 83 c7 03 f3 90 <0f> b6 01 41 38 c7 7c 08 84 c0 0f 85 d4 06 00 00 8b 45 08 a8 01 75 +RSP: 0018:ffffc9000cb3fb60 EFLAGS: 00000202 +RAX: 0000000000000011 RBX: ffff8883bc4469c0 RCX: ffffed10776e9949 +RDX: 0000000000000002 RSI: ffff8883bb74ca48 RDI: ffffffff8434dc50 +RBP: ffff8883bb74ca40 R08: ffff888103585dc0 R09: ffff8884533a1800 +R10: 0000000000000004 R11: ffffffffffffffff R12: ffffed1077888d39 +R13: dffffc0000000000 R14: ffffed1077888d38 R15: 0000000000000003 +FS: 0000000000000000(0000) GS:ffff8883bc400000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00005577b5c8d158 CR3: 0000000004850000 CR4: 0000000000350ef0 +Call Trace: + + ? watchdog_timer_fn+0x2cd/0x390 + ? __pfx_watchdog_timer_fn+0x10/0x10 + ? __hrtimer_run_queues+0x300/0x6d0 + ? sched_clock_cpu+0x69/0x4e0 + ? __pfx___hrtimer_run_queues+0x10/0x10 + ? srso_return_thunk+0x5/0x5f + ? ktime_get_update_offsets_now+0x7f/0x2a0 + ? srso_return_thunk+0x5/0x5f + ? srso_return_thunk+0x5/0x5f + ? hrtimer_interrupt+0x2ca/0x760 + ? __sysvec_apic_timer_interrupt+0x8c/0x2b0 + ? sysvec_apic_timer_interrupt+0x6a/0x90 + + + ? asm_sysvec_apic_timer_interrupt+0x16/0x20 + ? smp_call_function_many_cond+0x1d8/0xbb0 + ? __pfx_do_kernel_range_flush+0x10/0x10 + on_each_cpu_cond_mask+0x20/0x40 + flush_tlb_kernel_range+0x19b/0x250 + ? srso_return_thunk+0x5/0x5f + ? kasan_release_vmalloc+0xa7/0xc0 + purge_vmap_node+0x357/0x820 + ? __pfx_purge_vmap_node+0x10/0x10 + __purge_vmap_area_lazy+0x5b8/0xa10 + drain_vmap_area_work+0x21/0x30 + process_one_work+0x661/0x10b0 + worker_thread+0x844/0x10e0 + ? srso_return_thunk+0x5/0x5f + ? __kthread_parkme+0x82/0x140 + ? __pfx_worker_thread+0x10/0x10 + kthread+0x2a5/0x370 + ? __pfx_kthread+0x10/0x10 + ret_from_fork+0x30/0x70 + ? __pfx_kthread+0x10/0x10 + ret_from_fork_asm+0x1a/0x30 + + +Debugging Analysis: + + 1. The following ftrace log shows that the lockup CPU spends too much + time iterating vmap_nodes and flushing TLB when purging vm_area + structures. (Some info is trimmed). + + kworker: funcgraph_entry: | drain_vmap_area_work() { + kworker: funcgraph_entry: | mutex_lock() { + kworker: funcgraph_entry: 1.092 us | __cond_resched(); + kworker: funcgraph_exit: 3.306 us | } + ... ... + kworker: funcgraph_entry: | flush_tlb_kernel_range() { + ... ... + kworker: funcgraph_exit: # 7533.649 us | } + ... ... + kworker: funcgraph_entry: 2.344 us | mutex_unlock(); + kworker: funcgraph_exit: $ 23871554 us | } + + The drain_vmap_area_work() spends over 23 seconds. + + There are 2805 flush_tlb_kernel_range() calls in the ftrace log. + * One is called in __purge_vmap_area_lazy(). + * Others are called by purge_vmap_node->kasan_release_vmalloc. + purge_vmap_node() iteratively releases kasan vmalloc + allocations and flushes TLB for each vmap_area. + - [Rough calculation] Each flush_tlb_kernel_range() runs + about 7.5ms. + -- 2804 * 7.5ms = 21.03 seconds. + -- That's why a soft lock is triggered. + + 2. Extending the soft lockup time can work around the issue (For example, + # echo 60 > /proc/sys/kernel/watchdog_thresh). This confirms the + above-mentioned speculation: drain_vmap_area_work() spends too much + time. + +If we combine all TLB flush operations of the KASAN shadow virtual +address into one operation in the call path +'purge_vmap_node()->kasan_release_vmalloc()', the running time of +drain_vmap_area_work() can be saved greatly. The idea is from the +flush_tlb_kernel_range() call in __purge_vmap_area_lazy(). And, the +soft lockup won't be triggered. + +Here is the test result based on 6.10: + +[6.10 wo/ the patch] + 1. ftrace latency profiling (record a trace if the latency > 20s). + echo 20000000 > /sys/kernel/debug/tracing/tracing_thresh + echo drain_vmap_area_work > /sys/kernel/debug/tracing/set_graph_function + echo function_graph > /sys/kernel/debug/tracing/current_tracer + echo 1 > /sys/kernel/debug/tracing/tracing_on + + 2. Run `make -j $(nproc)` to compile the kernel source + + 3. Once the soft lockup is reproduced, check the ftrace log: + cat /sys/kernel/debug/tracing/trace + # tracer: function_graph + # + # CPU DURATION FUNCTION CALLS + # | | | | | | | + 76) $ 50412985 us | } /* __purge_vmap_area_lazy */ + 76) $ 50412997 us | } /* drain_vmap_area_work */ + 76) $ 29165911 us | } /* __purge_vmap_area_lazy */ + 76) $ 29165926 us | } /* drain_vmap_area_work */ + 91) $ 53629423 us | } /* __purge_vmap_area_lazy */ + 91) $ 53629434 us | } /* drain_vmap_area_work */ + 91) $ 28121014 us | } /* __purge_vmap_area_lazy */ + 91) $ 28121026 us | } /* drain_vmap_area_work */ + +[6.10 w/ the patch] + 1. Repeat step 1-2 in "[6.10 wo/ the patch]" + + 2. The soft lockup is not triggered and ftrace log is empty. + cat /sys/kernel/debug/tracing/trace + # tracer: function_graph + # + # CPU DURATION FUNCTION CALLS + # | | | | | | | + + 3. Setting 'tracing_thresh' to 10/5 seconds does not get any ftrace + log. + + 4. Setting 'tracing_thresh' to 1 second gets ftrace log. + cat /sys/kernel/debug/tracing/trace + # tracer: function_graph + # + # CPU DURATION FUNCTION CALLS + # | | | | | | | + 23) $ 1074942 us | } /* __purge_vmap_area_lazy */ + 23) $ 1074950 us | } /* drain_vmap_area_work */ + + The worst execution time of drain_vmap_area_work() is about 1 second. + +Link: https://lore.kernel.org/lkml/ZqFlawuVnOMY2k3E@pc638.lan/ +Link: https://lkml.kernel.org/r/20240726165246.31326-1-ahuang12@lenovo.com +Fixes: 282631cb2447 ("mm: vmalloc: remove global purge_vmap_area_root rb-tree") +Signed-off-by: Adrian Huang +Co-developed-by: Uladzislau Rezki (Sony) +Signed-off-by: Uladzislau Rezki (Sony) +Tested-by: Jiwei Sun +Reviewed-by: Baoquan He +Cc: Alexander Potapenko +Cc: Andrey Konovalov +Cc: Andrey Ryabinin +Cc: Christoph Hellwig +Cc: Dmitry Vyukov +Cc: Vincenzo Frascino +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/kasan.h | 12 +++++++++--- + mm/kasan/shadow.c | 14 ++++++++++---- + mm/vmalloc.c | 34 ++++++++++++++++++++++++++-------- + 3 files changed, 45 insertions(+), 15 deletions(-) + +diff --git a/include/linux/kasan.h b/include/linux/kasan.h +index 00a3bf7c0d8f..6bbfc8aa42e8 100644 +--- a/include/linux/kasan.h ++++ b/include/linux/kasan.h +@@ -29,6 +29,9 @@ typedef unsigned int __bitwise kasan_vmalloc_flags_t; + #define KASAN_VMALLOC_VM_ALLOC ((__force kasan_vmalloc_flags_t)0x02u) + #define KASAN_VMALLOC_PROT_NORMAL ((__force kasan_vmalloc_flags_t)0x04u) + ++#define KASAN_VMALLOC_PAGE_RANGE 0x1 /* Apply exsiting page range */ ++#define KASAN_VMALLOC_TLB_FLUSH 0x2 /* TLB flush */ ++ + #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) + + #include +@@ -564,7 +567,8 @@ void kasan_populate_early_vm_area_shadow(void *start, unsigned long size); + int kasan_populate_vmalloc(unsigned long addr, unsigned long size); + void kasan_release_vmalloc(unsigned long start, unsigned long end, + unsigned long free_region_start, +- unsigned long free_region_end); ++ unsigned long free_region_end, ++ unsigned long flags); + + #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ + +@@ -579,7 +583,8 @@ static inline int kasan_populate_vmalloc(unsigned long start, + static inline void kasan_release_vmalloc(unsigned long start, + unsigned long end, + unsigned long free_region_start, +- unsigned long free_region_end) { } ++ unsigned long free_region_end, ++ unsigned long flags) { } + + #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ + +@@ -614,7 +619,8 @@ static inline int kasan_populate_vmalloc(unsigned long start, + static inline void kasan_release_vmalloc(unsigned long start, + unsigned long end, + unsigned long free_region_start, +- unsigned long free_region_end) { } ++ unsigned long free_region_end, ++ unsigned long flags) { } + + static inline void *kasan_unpoison_vmalloc(const void *start, + unsigned long size, +diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c +index d6210ca48dda..88d1c9dcb507 100644 +--- a/mm/kasan/shadow.c ++++ b/mm/kasan/shadow.c +@@ -489,7 +489,8 @@ static int kasan_depopulate_vmalloc_pte(pte_t *ptep, unsigned long addr, + */ + void kasan_release_vmalloc(unsigned long start, unsigned long end, + unsigned long free_region_start, +- unsigned long free_region_end) ++ unsigned long free_region_end, ++ unsigned long flags) + { + void *shadow_start, *shadow_end; + unsigned long region_start, region_end; +@@ -522,12 +523,17 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end, + __memset(shadow_start, KASAN_SHADOW_INIT, shadow_end - shadow_start); + return; + } +- apply_to_existing_page_range(&init_mm, ++ ++ ++ if (flags & KASAN_VMALLOC_PAGE_RANGE) ++ apply_to_existing_page_range(&init_mm, + (unsigned long)shadow_start, + size, kasan_depopulate_vmalloc_pte, + NULL); +- flush_tlb_kernel_range((unsigned long)shadow_start, +- (unsigned long)shadow_end); ++ ++ if (flags & KASAN_VMALLOC_TLB_FLUSH) ++ flush_tlb_kernel_range((unsigned long)shadow_start, ++ (unsigned long)shadow_end); + } + } + +diff --git a/mm/vmalloc.c b/mm/vmalloc.c +index 634162271c00..5480b77f4167 100644 +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -2182,6 +2182,25 @@ decay_va_pool_node(struct vmap_node *vn, bool full_decay) + reclaim_list_global(&decay_list); + } + ++static void ++kasan_release_vmalloc_node(struct vmap_node *vn) ++{ ++ struct vmap_area *va; ++ unsigned long start, end; ++ ++ start = list_first_entry(&vn->purge_list, struct vmap_area, list)->va_start; ++ end = list_last_entry(&vn->purge_list, struct vmap_area, list)->va_end; ++ ++ list_for_each_entry(va, &vn->purge_list, list) { ++ if (is_vmalloc_or_module_addr((void *) va->va_start)) ++ kasan_release_vmalloc(va->va_start, va->va_end, ++ va->va_start, va->va_end, ++ KASAN_VMALLOC_PAGE_RANGE); ++ } ++ ++ kasan_release_vmalloc(start, end, start, end, KASAN_VMALLOC_TLB_FLUSH); ++} ++ + static void purge_vmap_node(struct work_struct *work) + { + struct vmap_node *vn = container_of(work, +@@ -2190,20 +2209,17 @@ static void purge_vmap_node(struct work_struct *work) + struct vmap_area *va, *n_va; + LIST_HEAD(local_list); + ++ if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) ++ kasan_release_vmalloc_node(vn); ++ + vn->nr_purged = 0; + + list_for_each_entry_safe(va, n_va, &vn->purge_list, list) { + unsigned long nr = va_size(va) >> PAGE_SHIFT; +- unsigned long orig_start = va->va_start; +- unsigned long orig_end = va->va_end; + unsigned int vn_id = decode_vn_id(va->flags); + + list_del_init(&va->list); + +- if (is_vmalloc_or_module_addr((void *)orig_start)) +- kasan_release_vmalloc(orig_start, orig_end, +- va->va_start, va->va_end); +- + nr_purged_pages += nr; + vn->nr_purged++; + +@@ -4784,7 +4800,8 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, + &free_vmap_area_list); + if (va) + kasan_release_vmalloc(orig_start, orig_end, +- va->va_start, va->va_end); ++ va->va_start, va->va_end, ++ KASAN_VMALLOC_PAGE_RANGE | KASAN_VMALLOC_TLB_FLUSH); + vas[area] = NULL; + } + +@@ -4834,7 +4851,8 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, + &free_vmap_area_list); + if (va) + kasan_release_vmalloc(orig_start, orig_end, +- va->va_start, va->va_end); ++ va->va_start, va->va_end, ++ KASAN_VMALLOC_PAGE_RANGE | KASAN_VMALLOC_TLB_FLUSH); + vas[area] = NULL; + kfree(vms[area]); + } +-- +2.47.1 + diff --git a/queue-6.12/nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch b/queue-6.12/nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch new file mode 100644 index 00000000000..1b9f3f5154b --- /dev/null +++ b/queue-6.12/nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch @@ -0,0 +1,195 @@ +From 98100e88dd8865999dc6379a3356cd799795fe7b Mon Sep 17 00:00:00 2001 +From: Yang Erkun +Date: Tue, 5 Nov 2024 19:03:14 +0800 +Subject: nfsd: fix nfs4_openowner leak when concurrent nfsd4_open occur + +From: Yang Erkun + +commit 98100e88dd8865999dc6379a3356cd799795fe7b upstream. + +The action force umount(umount -f) will attempt to kill all rpc_task even +umount operation may ultimately fail if some files remain open. +Consequently, if an action attempts to open a file, it can potentially +send two rpc_task to nfs server. + + NFS CLIENT +thread1 thread2 +open("file") +... +nfs4_do_open + _nfs4_do_open + _nfs4_open_and_get_state + _nfs4_proc_open + nfs4_run_open_task + /* rpc_task1 */ + rpc_run_task + rpc_wait_for_completion_task + + umount -f + nfs_umount_begin + rpc_killall_tasks + rpc_signal_task + rpc_task1 been wakeup + and return -512 + _nfs4_do_open // while loop + ... + nfs4_run_open_task + /* rpc_task2 */ + rpc_run_task + rpc_wait_for_completion_task + +While processing an open request, nfsd will first attempt to find or +allocate an nfs4_openowner. If it finds an nfs4_openowner that is not +marked as NFS4_OO_CONFIRMED, this nfs4_openowner will released. Since +two rpc_task can attempt to open the same file simultaneously from the +client to server, and because two instances of nfsd can run +concurrently, this situation can lead to lots of memory leak. +Additionally, when we echo 0 to /proc/fs/nfsd/threads, warning will be +triggered. + + NFS SERVER +nfsd1 nfsd2 echo 0 > /proc/fs/nfsd/threads + +nfsd4_open + nfsd4_process_open1 + find_or_alloc_open_stateowner + // alloc oo1, stateid1 + nfsd4_open + nfsd4_process_open1 + find_or_alloc_open_stateowner + // find oo1, without NFS4_OO_CONFIRMED + release_openowner + unhash_openowner_locked + list_del_init(&oo->oo_perclient) + // cannot find this oo + // from client, LEAK!!! + alloc_stateowner // alloc oo2 + + nfsd4_process_open2 + init_open_stateid + // associate oo1 + // with stateid1, stateid1 LEAK!!! + nfs4_get_vfs_file + // alloc nfsd_file1 and nfsd_file_mark1 + // all LEAK!!! + + nfsd4_process_open2 + ... + + write_threads + ... + nfsd_destroy_serv + nfsd_shutdown_net + nfs4_state_shutdown_net + nfs4_state_destroy_net + destroy_client + __destroy_client + // won't find oo1!!! + nfsd_shutdown_generic + nfsd_file_cache_shutdown + kmem_cache_destroy + for nfsd_file_slab + and nfsd_file_mark_slab + // bark since nfsd_file1 + // and nfsd_file_mark1 + // still alive + +======================================================================= +BUG nfsd_file (Not tainted): Objects remaining in nfsd_file on +__kmem_cache_shutdown() +----------------------------------------------------------------------- + +Slab 0xffd4000004438a80 objects=34 used=1 fp=0xff11000110e2ad28 +flags=0x17ffffc0000240(workingset|head|node=0|zone=2|lastcpupid=0x1fffff) +CPU: 4 UID: 0 PID: 757 Comm: sh Not tainted 6.12.0-rc6+ #19 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +1.16.1-2.fc37 04/01/2014 +Call Trace: + + dump_stack_lvl+0x53/0x70 + slab_err+0xb0/0xf0 + __kmem_cache_shutdown+0x15c/0x310 + kmem_cache_destroy+0x66/0x160 + nfsd_file_cache_shutdown+0xac/0x210 [nfsd] + nfsd_destroy_serv+0x251/0x2a0 [nfsd] + nfsd_svc+0x125/0x1e0 [nfsd] + write_threads+0x16a/0x2a0 [nfsd] + nfsctl_transaction_write+0x74/0xa0 [nfsd] + vfs_write+0x1ae/0x6d0 + ksys_write+0xc1/0x160 + do_syscall_64+0x5f/0x170 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Disabling lock debugging due to kernel taint +Object 0xff11000110e2ac38 @offset=3128 +Allocated in nfsd_file_do_acquire+0x20f/0xa30 [nfsd] age=1635 cpu=3 +pid=800 + nfsd_file_do_acquire+0x20f/0xa30 [nfsd] + nfsd_file_acquire_opened+0x5f/0x90 [nfsd] + nfs4_get_vfs_file+0x4c9/0x570 [nfsd] + nfsd4_process_open2+0x713/0x1070 [nfsd] + nfsd4_open+0x74b/0x8b0 [nfsd] + nfsd4_proc_compound+0x70b/0xc20 [nfsd] + nfsd_dispatch+0x1b4/0x3a0 [nfsd] + svc_process_common+0x5b8/0xc50 [sunrpc] + svc_process+0x2ab/0x3b0 [sunrpc] + svc_handle_xprt+0x681/0xa20 [sunrpc] + nfsd+0x183/0x220 [nfsd] + kthread+0x199/0x1e0 + ret_from_fork+0x31/0x60 + ret_from_fork_asm+0x1a/0x30 + +Add nfs4_openowner_unhashed to help found unhashed nfs4_openowner, and +break nfsd4_open process to fix this problem. + +Cc: stable@vger.kernel.org # v5.4+ +Reviewed-by: Jeff Layton +Signed-off-by: Yang Erkun +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -1660,6 +1660,14 @@ static void release_open_stateid(struct + free_ol_stateid_reaplist(&reaplist); + } + ++static bool nfs4_openowner_unhashed(struct nfs4_openowner *oo) ++{ ++ lockdep_assert_held(&oo->oo_owner.so_client->cl_lock); ++ ++ return list_empty(&oo->oo_owner.so_strhash) && ++ list_empty(&oo->oo_perclient); ++} ++ + static void unhash_openowner_locked(struct nfs4_openowner *oo) + { + struct nfs4_client *clp = oo->oo_owner.so_client; +@@ -4975,6 +4983,12 @@ retry: + spin_lock(&oo->oo_owner.so_client->cl_lock); + spin_lock(&fp->fi_lock); + ++ if (nfs4_openowner_unhashed(oo)) { ++ mutex_unlock(&stp->st_mutex); ++ stp = NULL; ++ goto out_unlock; ++ } ++ + retstp = nfsd4_find_existing_open(fp, open); + if (retstp) + goto out_unlock; +@@ -6126,6 +6140,11 @@ nfsd4_process_open2(struct svc_rqst *rqs + + if (!stp) { + stp = init_open_stateid(fp, open); ++ if (!stp) { ++ status = nfserr_jukebox; ++ goto out; ++ } ++ + if (!open->op_stp) + new_stp = true; + } diff --git a/queue-6.12/nfsd-make-sure-exp-active-before-svc_export_show.patch b/queue-6.12/nfsd-make-sure-exp-active-before-svc_export_show.patch new file mode 100644 index 00000000000..792e782a18c --- /dev/null +++ b/queue-6.12/nfsd-make-sure-exp-active-before-svc_export_show.patch @@ -0,0 +1,60 @@ +From be8f982c369c965faffa198b46060f8853e0f1f0 Mon Sep 17 00:00:00 2001 +From: Yang Erkun +Date: Mon, 21 Oct 2024 22:23:41 +0800 +Subject: nfsd: make sure exp active before svc_export_show + +From: Yang Erkun + +commit be8f982c369c965faffa198b46060f8853e0f1f0 upstream. + +The function `e_show` was called with protection from RCU. This only +ensures that `exp` will not be freed. Therefore, the reference count for +`exp` can drop to zero, which will trigger a refcount use-after-free +warning when `exp_get` is called. To resolve this issue, use +`cache_get_rcu` to ensure that `exp` remains active. + +------------[ cut here ]------------ +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 3 PID: 819 at lib/refcount.c:25 +refcount_warn_saturate+0xb1/0x120 +CPU: 3 UID: 0 PID: 819 Comm: cat Not tainted 6.12.0-rc3+ #1 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +1.16.1-2.fc37 04/01/2014 +RIP: 0010:refcount_warn_saturate+0xb1/0x120 +... +Call Trace: + + e_show+0x20b/0x230 [nfsd] + seq_read_iter+0x589/0x770 + seq_read+0x1e5/0x270 + vfs_read+0x125/0x530 + ksys_read+0xc1/0x160 + do_syscall_64+0x5f/0x170 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: bf18f163e89c ("NFSD: Using exp_get for export getting") +Cc: stable@vger.kernel.org # 4.20+ +Signed-off-by: Yang Erkun +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/export.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/export.c ++++ b/fs/nfsd/export.c +@@ -1425,9 +1425,12 @@ static int e_show(struct seq_file *m, vo + return 0; + } + +- exp_get(exp); ++ if (!cache_get_rcu(&exp->h)) ++ return 0; ++ + if (cache_check(cd, &exp->h, NULL)) + return 0; ++ + exp_put(exp); + return svc_export_show(m, cd, cp); + } diff --git a/queue-6.12/ovl-properly-handle-large-files-in-ovl_security_fileattr.patch b/queue-6.12/ovl-properly-handle-large-files-in-ovl_security_fileattr.patch new file mode 100644 index 00000000000..c983f4be8f3 --- /dev/null +++ b/queue-6.12/ovl-properly-handle-large-files-in-ovl_security_fileattr.patch @@ -0,0 +1,54 @@ +From 3b6b99ef15ea37635604992ede9ebcccef38a239 Mon Sep 17 00:00:00 2001 +From: Oleksandr Tymoshenko +Date: Wed, 30 Oct 2024 00:28:55 +0000 +Subject: ovl: properly handle large files in ovl_security_fileattr + +From: Oleksandr Tymoshenko + +commit 3b6b99ef15ea37635604992ede9ebcccef38a239 upstream. + +dentry_open in ovl_security_fileattr fails for any file +larger than 2GB if open method of the underlying filesystem +calls generic_file_open (e.g. fusefs). + +The issue can be reproduce using the following script: +(passthrough_ll is an example app from libfuse). + + $ D=/opt/test/mnt + $ mkdir -p ${D}/{source,base,top/uppr,top/work,ovlfs} + $ dd if=/dev/zero of=${D}/source/zero.bin bs=1G count=2 + $ passthrough_ll -o source=${D}/source ${D}/base + $ mount -t overlay overlay \ + -olowerdir=${D}/base,upperdir=${D}/top/uppr,workdir=${D}/top/work \ + ${D}/ovlfs + $ chmod 0777 ${D}/mnt/ovlfs/zero.bin + +Running this script results in "Value too large for defined data type" +error message from chmod. + +Signed-off-by: Oleksandr Tymoshenko +Fixes: 72db82115d2b ("ovl: copy up sync/noatime fileattr flags") +Cc: stable@vger.kernel.org # v5.15+ +Signed-off-by: Amir Goldstein +Signed-off-by: Greg Kroah-Hartman +--- + fs/overlayfs/inode.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/fs/overlayfs/inode.c ++++ b/fs/overlayfs/inode.c +@@ -616,8 +616,13 @@ static int ovl_security_fileattr(const s + struct file *file; + unsigned int cmd; + int err; ++ unsigned int flags; + +- file = dentry_open(realpath, O_RDONLY, current_cred()); ++ flags = O_RDONLY; ++ if (force_o_largefile()) ++ flags |= O_LARGEFILE; ++ ++ file = dentry_open(realpath, flags, current_cred()); + if (IS_ERR(file)) + return PTR_ERR(file); + diff --git a/queue-6.12/pci-dwc-ep-fix-advertised-resizable-bar-size-regression.patch b/queue-6.12/pci-dwc-ep-fix-advertised-resizable-bar-size-regression.patch new file mode 100644 index 00000000000..feca7d6557c --- /dev/null +++ b/queue-6.12/pci-dwc-ep-fix-advertised-resizable-bar-size-regression.patch @@ -0,0 +1,49 @@ +From 118397c9baaac0b7ec81896f8d755d09aa82c485 Mon Sep 17 00:00:00 2001 +From: Niklas Cassel +Date: Sat, 16 Nov 2024 01:59:51 +0100 +Subject: PCI: dwc: ep: Fix advertised resizable BAR size regression +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Niklas Cassel + +commit 118397c9baaac0b7ec81896f8d755d09aa82c485 upstream. + +The advertised resizable BAR size was fixed in commit 72e34b8593e0 ("PCI: +dwc: endpoint: Fix advertised resizable BAR size"). + +Commit 867ab111b242 ("PCI: dwc: ep: Add a generic dw_pcie_ep_linkdown() +API to handle Link Down event") was included shortly after this, and +moved the code to another function. When the code was moved, this fix +was mistakenly lost. + +According to the spec, it is illegal to not have a bit set in +PCI_REBAR_CAP, and 1 MB is the smallest size allowed. + +So, set bit 4 in PCI_REBAR_CAP, so that we actually advertise support +for a 1 MB BAR size. + +Fixes: 867ab111b242 ("PCI: dwc: ep: Add a generic dw_pcie_ep_linkdown() API to handle Link Down event") +Link: https://lore.kernel.org/r/20241116005950.2480427-2-cassel@kernel.org +Link: https://lore.kernel.org/r/20240606-pci-deinit-v1-3-4395534520dc@linaro.org +Link: https://lore.kernel.org/r/20240307111520.3303774-1-cassel@kernel.org +Signed-off-by: Niklas Cassel +Signed-off-by: Krzysztof Wilczyński +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/dwc/pcie-designware-ep.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/controller/dwc/pcie-designware-ep.c ++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c +@@ -689,7 +689,7 @@ static void dw_pcie_ep_init_non_sticky_r + * for 1 MB BAR size only. + */ + for (i = 0; i < nbars; i++, offset += PCI_REBAR_CTRL) +- dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, 0x0); ++ dw_pcie_writel_dbi(pci, offset + PCI_REBAR_CAP, BIT(4)); + } + + dw_pcie_setup(pci); diff --git a/queue-6.12/pci-endpoint-clear-secondary-not-primary-epc-in-pci_epc_remove_epf.patch b/queue-6.12/pci-endpoint-clear-secondary-not-primary-epc-in-pci_epc_remove_epf.patch new file mode 100644 index 00000000000..2a0e5d16cfe --- /dev/null +++ b/queue-6.12/pci-endpoint-clear-secondary-not-primary-epc-in-pci_epc_remove_epf.patch @@ -0,0 +1,61 @@ +From 688d2eb4c6fcfdcdaed0592f9df9196573ff5ce2 Mon Sep 17 00:00:00 2001 +From: Zijun Hu +Date: Thu, 7 Nov 2024 08:53:09 +0800 +Subject: PCI: endpoint: Clear secondary (not primary) EPC in pci_epc_remove_epf() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Zijun Hu + +commit 688d2eb4c6fcfdcdaed0592f9df9196573ff5ce2 upstream. + +In addition to a primary endpoint controller, an endpoint function may be +associated with a secondary endpoint controller, epf->sec_epc, to provide +NTB (non-transparent bridge) functionality. + +Previously, pci_epc_remove_epf() incorrectly cleared epf->epc instead of +epf->sec_epc when removing from the secondary endpoint controller. + +Extend the epc->list_lock coverage and clear either epf->epc or +epf->sec_epc as indicated. + +Link: https://lore.kernel.org/r/20241107-epc_rfc-v2-2-da5b6a99a66f@quicinc.com +Fixes: 63840ff53223 ("PCI: endpoint: Add support to associate secondary EPC with EPF") +Signed-off-by: Zijun Hu +Reviewed-by: Manivannan Sadhasivam +[mani: reworded subject and description] +Signed-off-by: Manivannan Sadhasivam +[bhelgaas: commit log] +Signed-off-by: Bjorn Helgaas +Signed-off-by: Krzysztof Wilczyński +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/endpoint/pci-epc-core.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/pci/endpoint/pci-epc-core.c ++++ b/drivers/pci/endpoint/pci-epc-core.c +@@ -660,18 +660,18 @@ void pci_epc_remove_epf(struct pci_epc * + if (IS_ERR_OR_NULL(epc) || !epf) + return; + ++ mutex_lock(&epc->list_lock); + if (type == PRIMARY_INTERFACE) { + func_no = epf->func_no; + list = &epf->list; ++ epf->epc = NULL; + } else { + func_no = epf->sec_epc_func_no; + list = &epf->sec_epc_list; ++ epf->sec_epc = NULL; + } +- +- mutex_lock(&epc->list_lock); + clear_bit(func_no, &epc->function_num_map); + list_del(list); +- epf->epc = NULL; + mutex_unlock(&epc->list_lock); + } + EXPORT_SYMBOL_GPL(pci_epc_remove_epf); diff --git a/queue-6.12/pci-endpoint-fix-pci-domain-id-release-in-pci_epc_destroy.patch b/queue-6.12/pci-endpoint-fix-pci-domain-id-release-in-pci_epc_destroy.patch new file mode 100644 index 00000000000..bbc1349803d --- /dev/null +++ b/queue-6.12/pci-endpoint-fix-pci-domain-id-release-in-pci_epc_destroy.patch @@ -0,0 +1,54 @@ +From 4acc902ed3743edd4ac2d3846604a99d17104359 Mon Sep 17 00:00:00 2001 +From: Zijun Hu +Date: Thu, 7 Nov 2024 08:53:08 +0800 +Subject: PCI: endpoint: Fix PCI domain ID release in pci_epc_destroy() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Zijun Hu + +commit 4acc902ed3743edd4ac2d3846604a99d17104359 upstream. + +pci_epc_destroy() invokes pci_bus_release_domain_nr() to release the PCI +domain ID, but there are two issues: + + - 'epc->dev' is passed to pci_bus_release_domain_nr() which was already + freed by device_unregister(), leading to a use-after-free issue. + + - Domain ID corresponds to the EPC device parent, so passing 'epc->dev' + is also wrong. + +Fix these issues by passing 'epc->dev.parent' to +pci_bus_release_domain_nr() and also do it before device_unregister(). + +Fixes: 0328947c5032 ("PCI: endpoint: Assign PCI domain number for endpoint controllers") +Signed-off-by: Zijun Hu +Reviewed-by: Manivannan Sadhasivam +Link: https://lore.kernel.org/r/20241107-epc_rfc-v2-1-da5b6a99a66f@quicinc.com +[mani: reworded subject and description] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Signed-off-by: Krzysztof Wilczyński +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/endpoint/pci-epc-core.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/pci/endpoint/pci-epc-core.c ++++ b/drivers/pci/endpoint/pci-epc-core.c +@@ -837,11 +837,10 @@ EXPORT_SYMBOL_GPL(pci_epc_bus_master_ena + void pci_epc_destroy(struct pci_epc *epc) + { + pci_ep_cfs_remove_epc_group(epc->group); +- device_unregister(&epc->dev); +- + #ifdef CONFIG_PCI_DOMAINS_GENERIC +- pci_bus_release_domain_nr(&epc->dev, epc->domain_nr); ++ pci_bus_release_domain_nr(epc->dev.parent, epc->domain_nr); + #endif ++ device_unregister(&epc->dev); + } + EXPORT_SYMBOL_GPL(pci_epc_destroy); + diff --git a/queue-6.12/pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch b/queue-6.12/pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch new file mode 100644 index 00000000000..690f01dcb35 --- /dev/null +++ b/queue-6.12/pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch @@ -0,0 +1,52 @@ +From 9e9ec8d8692a6f64d81ef67d4fb6255af6be684b Mon Sep 17 00:00:00 2001 +From: Kishon Vijay Abraham I +Date: Fri, 24 May 2024 16:27:14 +0530 +Subject: PCI: keystone: Add link up check to ks_pcie_other_map_bus() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kishon Vijay Abraham I + +commit 9e9ec8d8692a6f64d81ef67d4fb6255af6be684b upstream. + +K2G forwards the error triggered by a link-down state (e.g., no connected +endpoint device) on the system bus for PCI configuration transactions; +these errors are reported as an SError at system level, which is fatal and +hangs the system. + +So, apply fix similar to how it was done in the DesignWare Core driver +commit 15b23906347c ("PCI: dwc: Add link up check in dw_child_pcie_ops.map_bus()"). + +Fixes: 10a797c6e54a ("PCI: dwc: keystone: Use pci_ops for config space accessors") +Link: https://lore.kernel.org/r/20240524105714.191642-3-s-vadapalli@ti.com +Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Siddharth Vadapalli +[kwilczynski: commit log, added tag for stable releases] +Signed-off-by: Krzysztof Wilczyński +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/dwc/pci-keystone.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -455,6 +455,17 @@ static void __iomem *ks_pcie_other_map_b + struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); + u32 reg; + ++ /* ++ * Checking whether the link is up here is a last line of defense ++ * against platforms that forward errors on the system bus as ++ * SError upon PCI configuration transactions issued when the link ++ * is down. This check is racy by definition and does not stop ++ * the system from triggering an SError if the link goes down ++ * after this check is performed. ++ */ ++ if (!dw_pcie_link_up(pci)) ++ return NULL; ++ + reg = CFG_BUS(bus->number) | CFG_DEVICE(PCI_SLOT(devfn)) | + CFG_FUNC(PCI_FUNC(devfn)); + if (!pci_is_root_bus(bus->parent)) diff --git a/queue-6.12/pci-keystone-set-mode-as-root-complex-for-ti-keystone-pcie-compatible.patch b/queue-6.12/pci-keystone-set-mode-as-root-complex-for-ti-keystone-pcie-compatible.patch new file mode 100644 index 00000000000..5fde1f66869 --- /dev/null +++ b/queue-6.12/pci-keystone-set-mode-as-root-complex-for-ti-keystone-pcie-compatible.patch @@ -0,0 +1,50 @@ +From 5a938ed9481b0c06cb97aec45e722a80568256fd Mon Sep 17 00:00:00 2001 +From: Kishon Vijay Abraham I +Date: Fri, 24 May 2024 16:27:13 +0530 +Subject: PCI: keystone: Set mode as Root Complex for "ti,keystone-pcie" compatible +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kishon Vijay Abraham I + +commit 5a938ed9481b0c06cb97aec45e722a80568256fd upstream. + +commit 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x +Platforms") introduced configuring "enum dw_pcie_device_mode" as part of +device data ("struct ks_pcie_of_data"). However it failed to set the +mode for "ti,keystone-pcie" compatible. + +Since the mode defaults to "DW_PCIE_UNKNOWN_TYPE", the following error +message is displayed for the v3.65a controller: + + "INVALID device type 0" + +Despite the driver probing successfully, the controller may not be +functional in the Root Complex mode of operation. + +So, set the mode as Root Complex for "ti,keystone-pcie" compatible to +fix this. + +Fixes: 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms") +Link: https://lore.kernel.org/r/20240524105714.191642-2-s-vadapalli@ti.com +Signed-off-by: Kishon Vijay Abraham I +Signed-off-by: Siddharth Vadapalli +[kwilczynski: commit log, added tag for stable releases] +Signed-off-by: Krzysztof Wilczyński +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/dwc/pci-keystone.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1093,6 +1093,7 @@ static int ks_pcie_am654_set_mode(struct + + static const struct ks_pcie_of_data ks_pcie_rc_of_data = { + .host_ops = &ks_pcie_host_ops, ++ .mode = DW_PCIE_RC_TYPE, + .version = DW_PCIE_VER_365A, + }; + diff --git a/queue-6.12/pci-of_property-assign-pci-instead-of-cpu-bus-address-to-dynamic-pci-nodes.patch b/queue-6.12/pci-of_property-assign-pci-instead-of-cpu-bus-address-to-dynamic-pci-nodes.patch new file mode 100644 index 00000000000..7caa967706b --- /dev/null +++ b/queue-6.12/pci-of_property-assign-pci-instead-of-cpu-bus-address-to-dynamic-pci-nodes.patch @@ -0,0 +1,39 @@ +From 5e316d34b53039346e252d0019e2f4167af2c0ef Mon Sep 17 00:00:00 2001 +From: Andrea della Porta +Date: Fri, 8 Nov 2024 10:42:56 +0100 +Subject: PCI: of_property: Assign PCI instead of CPU bus address to dynamic PCI nodes + +From: Andrea della Porta + +commit 5e316d34b53039346e252d0019e2f4167af2c0ef upstream. + +When populating "ranges" property for a PCI bridge or endpoint, +of_pci_prop_ranges() incorrectly uses the CPU address of the resource. In +such PCI nodes, the window should instead be in PCI address space. Call +pci_bus_address() on the resource in order to obtain the PCI bus address. + +[Previous discussion at: +https://lore.kernel.org/all/8b4fa91380fc4754ea80f47330c613e4f6b6592c.1724159867.git.andrea.porta@suse.com/] + +Link: https://lore.kernel.org/r/20241108094256.28933-1-andrea.porta@suse.com +Fixes: 407d1a51921e ("PCI: Create device tree node for bridge") +Tested-by: Herve Codina +Signed-off-by: Andrea della Porta +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/of_property.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/of_property.c ++++ b/drivers/pci/of_property.c +@@ -126,7 +126,7 @@ static int of_pci_prop_ranges(struct pci + if (of_pci_get_addr_flags(&res[j], &flags)) + continue; + +- val64 = res[j].start; ++ val64 = pci_bus_address(pdev, &res[j] - pdev->resource); + of_pci_set_address(pdev, rp[i].parent_addr, val64, 0, flags, + false); + if (pci_is_bridge(pdev)) { diff --git a/queue-6.12/pci-rockchip-ep-fix-address-translation-unit-programming.patch b/queue-6.12/pci-rockchip-ep-fix-address-translation-unit-programming.patch new file mode 100644 index 00000000000..d96511eda1c --- /dev/null +++ b/queue-6.12/pci-rockchip-ep-fix-address-translation-unit-programming.patch @@ -0,0 +1,98 @@ +From 64f093c4d99d797b68b407a9d8767aadc3e3ea7a Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Thu, 17 Oct 2024 10:58:36 +0900 +Subject: PCI: rockchip-ep: Fix address translation unit programming +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Damien Le Moal + +commit 64f093c4d99d797b68b407a9d8767aadc3e3ea7a upstream. + +The Rockchip PCIe endpoint controller handles PCIe transfers addresses +by masking the lower bits of the programmed PCI address and using the +same number of lower bits masked from the CPU address space used for the +mapping. For a PCI mapping of bytes starting from , +the number of bits masked is the number of address bits changing in the +address range [pci_addr..pci_addr + size - 1]. + +However, rockchip_pcie_prog_ep_ob_atu() calculates num_pass_bits only +using the size of the mapping, resulting in an incorrect number of mask +bits depending on the value of the PCI address to map. + +Fix this by introducing the helper function +rockchip_pcie_ep_ob_atu_num_bits() to correctly calculate the number of +mask bits to use to program the address translation unit. The number of +mask bits is calculated depending on both the PCI address and size of +the mapping, and clamped between 8 and 20 using the macros +ROCKCHIP_PCIE_AT_MIN_NUM_BITS and ROCKCHIP_PCIE_AT_MAX_NUM_BITS. As +defined in the Rockchip RK3399 TRM V1.3 Part2, Sections 17.5.5.1.1 and +17.6.8.2.1, this clamping is necessary because: + + 1) The lower 8 bits of the PCI address to be mapped by the outbound + region are ignored. So a minimum of 8 address bits are needed and + imply that the PCI address must be aligned to 256. + + 2) The outbound memory regions are 1MB in size. So while we can specify + up to 63-bits for the PCI address (num_bits filed uses bits 0 to 5 of + the outbound address region 0 register), we must limit the number of + valid address bits to 20 to match the memory window maximum size (1 + << 20 = 1MB). + +Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") +Link: https://lore.kernel.org/r/20241017015849.190271-2-dlemoal@kernel.org +Signed-off-by: Damien Le Moal +Signed-off-by: Krzysztof Wilczyński +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pcie-rockchip-ep.c | 16 +++++++++++++--- + drivers/pci/controller/pcie-rockchip.h | 4 ++++ + 2 files changed, 17 insertions(+), 3 deletions(-) + +--- a/drivers/pci/controller/pcie-rockchip-ep.c ++++ b/drivers/pci/controller/pcie-rockchip-ep.c +@@ -63,15 +63,25 @@ static void rockchip_pcie_clear_ep_ob_at + ROCKCHIP_PCIE_AT_OB_REGION_DESC1(region)); + } + ++static int rockchip_pcie_ep_ob_atu_num_bits(struct rockchip_pcie *rockchip, ++ u64 pci_addr, size_t size) ++{ ++ int num_pass_bits = fls64(pci_addr ^ (pci_addr + size - 1)); ++ ++ return clamp(num_pass_bits, ++ ROCKCHIP_PCIE_AT_MIN_NUM_BITS, ++ ROCKCHIP_PCIE_AT_MAX_NUM_BITS); ++} ++ + static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn, + u32 r, u64 cpu_addr, u64 pci_addr, + size_t size) + { +- int num_pass_bits = fls64(size - 1); ++ int num_pass_bits; + u32 addr0, addr1, desc0; + +- if (num_pass_bits < 8) +- num_pass_bits = 8; ++ num_pass_bits = rockchip_pcie_ep_ob_atu_num_bits(rockchip, ++ pci_addr, size); + + addr0 = ((num_pass_bits - 1) & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) | + (lower_32_bits(pci_addr) & PCIE_CORE_OB_REGION_ADDR0_LO_ADDR); +--- a/drivers/pci/controller/pcie-rockchip.h ++++ b/drivers/pci/controller/pcie-rockchip.h +@@ -245,6 +245,10 @@ + (PCIE_EP_PF_CONFIG_REGS_BASE + (((fn) << 12) & GENMASK(19, 12))) + #define ROCKCHIP_PCIE_EP_VIRT_FUNC_BASE(fn) \ + (PCIE_EP_PF_CONFIG_REGS_BASE + 0x10000 + (((fn) << 12) & GENMASK(19, 12))) ++ ++#define ROCKCHIP_PCIE_AT_MIN_NUM_BITS 8 ++#define ROCKCHIP_PCIE_AT_MAX_NUM_BITS 20 ++ + #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \ + (PCIE_CORE_AXI_CONF_BASE + 0x0828 + (fn) * 0x0040 + (bar) * 0x0008) + #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \ diff --git a/queue-6.12/powerpc-adjust-adding-stack-protector-flags-to-kbuild_clags-for-clang.patch b/queue-6.12/powerpc-adjust-adding-stack-protector-flags-to-kbuild_clags-for-clang.patch new file mode 100644 index 00000000000..c6a6536554f --- /dev/null +++ b/queue-6.12/powerpc-adjust-adding-stack-protector-flags-to-kbuild_clags-for-clang.patch @@ -0,0 +1,66 @@ +From bee08a9e6ab03caf14481d97b35a258400ffab8f Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Wed, 9 Oct 2024 12:26:09 -0700 +Subject: powerpc: Adjust adding stack protector flags to KBUILD_CLAGS for clang + +From: Nathan Chancellor + +commit bee08a9e6ab03caf14481d97b35a258400ffab8f upstream. + +After fixing the HAVE_STACKPROTECTER checks for clang's in-progress +per-task stack protector support [1], the build fails during prepare0 +because '-mstack-protector-guard-offset' has not been added to +KBUILD_CFLAGS yet but the other '-mstack-protector-guard' flags have. + + clang: error: '-mstack-protector-guard=tls' is used without '-mstack-protector-guard-offset', and there is no default + clang: error: '-mstack-protector-guard=tls' is used without '-mstack-protector-guard-offset', and there is no default + make[4]: *** [scripts/Makefile.build:229: scripts/mod/empty.o] Error 1 + make[4]: *** [scripts/Makefile.build:102: scripts/mod/devicetable-offsets.s] Error 1 + +Mirror other architectures and add all '-mstack-protector-guard' flags +to KBUILD_CFLAGS atomically during stack_protector_prepare, which +resolves the issue and allows clang's implementation to fully work with +the kernel. + +Cc: stable@vger.kernel.org # 6.1+ +Link: https://github.com/llvm/llvm-project/pull/110928 [1] +Reviewed-by: Keith Packard +Tested-by: Keith Packard +Signed-off-by: Nathan Chancellor +Signed-off-by: Michael Ellerman +Link: https://patch.msgid.link/20241009-powerpc-fix-stackprotector-test-clang-v2-2-12fb86b31857@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/Makefile | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +--- a/arch/powerpc/Makefile ++++ b/arch/powerpc/Makefile +@@ -100,13 +100,6 @@ KBUILD_AFLAGS += -m$(BITS) + KBUILD_LDFLAGS += -m elf$(BITS)$(LDEMULATION) + endif + +-cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard=tls +-ifdef CONFIG_PPC64 +-cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard-reg=r13 +-else +-cflags-$(CONFIG_STACKPROTECTOR) += -mstack-protector-guard-reg=r2 +-endif +- + LDFLAGS_vmlinux-y := -Bstatic + LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie + LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) += -z notext +@@ -402,9 +395,11 @@ prepare: stack_protector_prepare + PHONY += stack_protector_prepare + stack_protector_prepare: prepare0 + ifdef CONFIG_PPC64 +- $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h)) ++ $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 \ ++ -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h)) + else +- $(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h)) ++ $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 \ ++ -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h)) + endif + endif + diff --git a/queue-6.12/powerpc-fix-stack-protector-kconfig-test-for-clang.patch b/queue-6.12/powerpc-fix-stack-protector-kconfig-test-for-clang.patch new file mode 100644 index 00000000000..cfe07bff5fc --- /dev/null +++ b/queue-6.12/powerpc-fix-stack-protector-kconfig-test-for-clang.patch @@ -0,0 +1,81 @@ +From 46e1879deea22eed31e9425d58635895fc0e8040 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Wed, 9 Oct 2024 12:26:08 -0700 +Subject: powerpc: Fix stack protector Kconfig test for clang + +From: Nathan Chancellor + +commit 46e1879deea22eed31e9425d58635895fc0e8040 upstream. + +Clang's in-progress per-task stack protector support [1] does not work +with the current Kconfig checks because '-mstack-protector-guard-offset' +is not provided, unlike all other architecture Kconfig checks. + + $ fd Kconfig -x rg -l mstack-protector-guard-offset + ./arch/arm/Kconfig + ./arch/riscv/Kconfig + ./arch/arm64/Kconfig + +This produces an error from clang, which is interpreted as the flags not +being supported at all when they really are. + + $ clang --target=powerpc64-linux-gnu \ + -mstack-protector-guard=tls \ + -mstack-protector-guard-reg=r13 \ + -c -o /dev/null -x c /dev/null + clang: error: '-mstack-protector-guard=tls' is used without '-mstack-protector-guard-offset', and there is no default + +This argument will always be provided by the build system, so mirror +other architectures and use '-mstack-protector-guard-offset=0' for +testing support, which fixes the issue for clang and does not regress +support with GCC. + +Even with the first problem addressed, the 32-bit test continues to fail +because Kbuild uses the powerpc64le-linux-gnu target for clang and +nothing flips the target to 32-bit, resulting in an error about an +invalid register valid: + + $ clang --target=powerpc64le-linux-gnu \ + -mstack-protector-guard=tls + -mstack-protector-guard-reg=r2 \ + -mstack-protector-guard-offset=0 \ + -x c -c -o /dev/null /dev/null + clang: error: invalid value 'r2' in 'mstack-protector-guard-reg=', expected one of: r13 + +While GCC allows arbitrary registers, the implementation of +'-mstack-protector-guard=tls' in LLVM shares the same code path as the +user space thread local storage implementation, which uses a fixed +register (2 for 32-bit and 13 for 62-bit), so the command line parsing +enforces this limitation. + +Use the Kconfig macro '$(m32-flag)', which expands to '-m32' when +supported, in the stack protector support cc-option call to properly +switch the target to a 32-bit one, which matches what happens in Kbuild. +While the 64-bit macro does not strictly need it, add the equivalent +64-bit option for symmetry. + +Cc: stable@vger.kernel.org # 6.1+ +Link: https://github.com/llvm/llvm-project/pull/110928 [1] +Reviewed-by: Keith Packard +Tested-by: Keith Packard +Signed-off-by: Nathan Chancellor +Signed-off-by: Michael Ellerman +Link: https://patch.msgid.link/20241009-powerpc-fix-stackprotector-test-clang-v2-1-12fb86b31857@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/Kconfig | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/Kconfig ++++ b/arch/powerpc/Kconfig +@@ -275,8 +275,8 @@ config PPC + select HAVE_RSEQ + select HAVE_SETUP_PER_CPU_AREA if PPC64 + select HAVE_SOFTIRQ_ON_OWN_STACK +- select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2) +- select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13) ++ select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,$(m32-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 -mstack-protector-guard-offset=0) ++ select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,$(m64-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 -mstack-protector-guard-offset=0) + select HAVE_STATIC_CALL if PPC32 + select HAVE_SYSCALL_TRACEPOINTS + select HAVE_VIRT_CPU_ACCOUNTING diff --git a/queue-6.12/s390-stacktrace-use-break-instead-of-return-statement.patch b/queue-6.12/s390-stacktrace-use-break-instead-of-return-statement.patch new file mode 100644 index 00000000000..5b956c43555 --- /dev/null +++ b/queue-6.12/s390-stacktrace-use-break-instead-of-return-statement.patch @@ -0,0 +1,45 @@ +From 588a9836a4ef7ec3bfcffda526dfa399637e6cfc Mon Sep 17 00:00:00 2001 +From: Heiko Carstens +Date: Mon, 18 Nov 2024 13:14:07 +0100 +Subject: s390/stacktrace: Use break instead of return statement + +From: Heiko Carstens + +commit 588a9836a4ef7ec3bfcffda526dfa399637e6cfc upstream. + +arch_stack_walk_user_common() contains a return statement instead of a +break statement in case store_ip() fails while trying to store a callchain +entry of a user space process. +This may lead to a missing pagefault_enable() call. + +If this happens any subsequent page fault of the process won't be resolved +by the page fault handler and this in turn will lead to the process being +killed. + +Use a break instead of a return statement to fix this. + +Fixes: ebd912ff9919 ("s390/stacktrace: Merge perf_callchain_user() and arch_stack_walk_user()") +Cc: stable@vger.kernel.org +Reviewed-by: Jens Remus +Signed-off-by: Heiko Carstens +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/kernel/stacktrace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c +index 9f59837d159e..40edfde25f5b 100644 +--- a/arch/s390/kernel/stacktrace.c ++++ b/arch/s390/kernel/stacktrace.c +@@ -151,7 +151,7 @@ void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *coo + break; + } + if (!store_ip(consume_entry, cookie, entry, perf, ip)) +- return; ++ break; + first = false; + } + pagefault_enable(); +-- +2.47.1 + diff --git a/queue-6.12/scsi-ufs-exynos-add-check-inside-exynos_ufs_config_smu.patch b/queue-6.12/scsi-ufs-exynos-add-check-inside-exynos_ufs_config_smu.patch new file mode 100644 index 00000000000..ea1f04d7b7d --- /dev/null +++ b/queue-6.12/scsi-ufs-exynos-add-check-inside-exynos_ufs_config_smu.patch @@ -0,0 +1,51 @@ +From c662cedea14efdcf373d8d886ec18019d50e0772 Mon Sep 17 00:00:00 2001 +From: Peter Griffin +Date: Thu, 31 Oct 2024 15:00:23 +0000 +Subject: scsi: ufs: exynos: Add check inside exynos_ufs_config_smu() + +From: Peter Griffin + +commit c662cedea14efdcf373d8d886ec18019d50e0772 upstream. + +Move the EXYNOS_UFS_OPT_UFSPR_SECURE check inside +exynos_ufs_config_smu(). + +This way all call sites will benefit from the check. This fixes a bug +currently in the exynos_ufs_resume() path on gs101 as it calls +exynos_ufs_config_smu() and we end up accessing registers that can only +be accessed from secure world which results in a serror. + +Fixes: d11e0a318df8 ("scsi: ufs: exynos: Add support for Tensor gs101 SoC") +Signed-off-by: Peter Griffin +Link: https://lore.kernel.org/r/20241031150033.3440894-5-peter.griffin@linaro.org +Cc: stable@vger.kernel.org +Reviewed-by: Tudor Ambarus +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ufs/host/ufs-exynos.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/ufs/host/ufs-exynos.c ++++ b/drivers/ufs/host/ufs-exynos.c +@@ -724,6 +724,9 @@ static void exynos_ufs_config_smu(struct + { + u32 reg, val; + ++ if (ufs->opts & EXYNOS_UFS_OPT_UFSPR_SECURE) ++ return; ++ + exynos_ufs_disable_auto_ctrl_hcc_save(ufs, &val); + + /* make encryption disabled by default */ +@@ -1440,8 +1443,8 @@ static int exynos_ufs_init(struct ufs_hb + if (ret) + goto out; + exynos_ufs_specify_phy_time_attr(ufs); +- if (!(ufs->opts & EXYNOS_UFS_OPT_UFSPR_SECURE)) +- exynos_ufs_config_smu(ufs); ++ ++ exynos_ufs_config_smu(ufs); + + hba->host->dma_alignment = DATA_UNIT_SIZE - 1; + return 0; diff --git a/queue-6.12/scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch b/queue-6.12/scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch new file mode 100644 index 00000000000..59b55d01e4d --- /dev/null +++ b/queue-6.12/scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch @@ -0,0 +1,87 @@ +From ceef938bbf8b93ba3a218b4adc244cde94b582aa Mon Sep 17 00:00:00 2001 +From: Peter Griffin +Date: Thu, 31 Oct 2024 15:00:31 +0000 +Subject: scsi: ufs: exynos: Fix hibern8 notify callbacks + +From: Peter Griffin + +commit ceef938bbf8b93ba3a218b4adc244cde94b582aa upstream. + +v1 of the patch which introduced the ufshcd_vops_hibern8_notify() +callback used a bool instead of an enum. In v2 this was updated to an +enum based on the review feedback in [1]. + +ufs-exynos hibernate calls have always been broken upstream as it +follows the v1 bool implementation. + +Link: https://patchwork.kernel.org/project/linux-scsi/patch/001f01d23994$719997c0$54ccc740$@samsung.com/ [1] +Fixes: 55f4b1f73631 ("scsi: ufs: ufs-exynos: Add UFS host support for Exynos SoCs") +Signed-off-by: Peter Griffin +Link: https://lore.kernel.org/r/20241031150033.3440894-13-peter.griffin@linaro.org +Cc: stable@vger.kernel.org +Reviewed-by: Tudor Ambarus +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ufs/host/ufs-exynos.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/ufs/host/ufs-exynos.c ++++ b/drivers/ufs/host/ufs-exynos.c +@@ -1487,12 +1487,12 @@ static void exynos_ufs_dev_hw_reset(stru + hci_writel(ufs, 1 << 0, HCI_GPIO_OUT); + } + +-static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, u8 enter) ++static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, enum uic_cmd_dme cmd) + { + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; + +- if (!enter) { ++ if (cmd == UIC_CMD_DME_HIBER_EXIT) { + if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) + exynos_ufs_disable_auto_ctrl_hcc(ufs); + exynos_ufs_ungate_clks(ufs); +@@ -1520,11 +1520,11 @@ static void exynos_ufs_pre_hibern8(struc + } + } + +-static void exynos_ufs_post_hibern8(struct ufs_hba *hba, u8 enter) ++static void exynos_ufs_post_hibern8(struct ufs_hba *hba, enum uic_cmd_dme cmd) + { + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + +- if (!enter) { ++ if (cmd == UIC_CMD_DME_HIBER_EXIT) { + u32 cur_mode = 0; + u32 pwrmode; + +@@ -1543,7 +1543,7 @@ static void exynos_ufs_post_hibern8(stru + + if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB)) + exynos_ufs_establish_connt(ufs); +- } else { ++ } else if (cmd == UIC_CMD_DME_HIBER_ENTER) { + ufs->entry_hibern8_t = ktime_get(); + exynos_ufs_gate_clks(ufs); + if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL) +@@ -1630,15 +1630,15 @@ static int exynos_ufs_pwr_change_notify( + } + + static void exynos_ufs_hibern8_notify(struct ufs_hba *hba, +- enum uic_cmd_dme enter, ++ enum uic_cmd_dme cmd, + enum ufs_notify_change_status notify) + { + switch ((u8)notify) { + case PRE_CHANGE: +- exynos_ufs_pre_hibern8(hba, enter); ++ exynos_ufs_pre_hibern8(hba, cmd); + break; + case POST_CHANGE: +- exynos_ufs_post_hibern8(hba, enter); ++ exynos_ufs_post_hibern8(hba, cmd); + break; + } + } diff --git a/queue-6.12/series b/queue-6.12/series index df48a931183..1dddf078a9c 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -73,3 +73,43 @@ ceph-pass-cred-pointer-to-ceph_mds_auth_match.patch ceph-fix-cred-leak-in-ceph_mds_check_access.patch mtd-spinand-winbond-fix-512gw-and-02jw-oob-layout.patch mtd-spinand-winbond-fix-512gw-01gw-01jw-and-02jw-ecc-information.patch +util_macros.h-fix-rework-find_closest-macros.patch +s390-stacktrace-use-break-instead-of-return-statement.patch +scsi-ufs-exynos-add-check-inside-exynos_ufs_config_smu.patch +scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch +i3c-master-svc-fix-pm_runtime_set_suspended-with-runtime-pm-enabled.patch +i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch +i3c-master-svc-fix-possible-assignment-of-the-same-address-to-two-devices.patch +i3c-master-svc-modify-enabled_events-bit-7-0-to-act-as-ibi-enable-counter.patch +pci-keystone-set-mode-as-root-complex-for-ti-keystone-pcie-compatible.patch +pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch +pci-endpoint-fix-pci-domain-id-release-in-pci_epc_destroy.patch +pci-endpoint-clear-secondary-not-primary-epc-in-pci_epc_remove_epf.patch +slab-fix-too-strict-alignment-check-in-create_cache.patch +fs-proc-kcore.c-clear-ret-value-in-read_kcore_iter-after-successful-iov_iter_zero.patch +thermal-int3400-fix-reading-of-current_uuid-for-active-policy.patch +leds-flash-mt6360-fix-device_for_each_child_node-refcounting-in-error-paths.patch +ovl-properly-handle-large-files-in-ovl_security_fileattr.patch +mm-vmalloc-combine-all-tlb-flush-operations-of-kasan-shadow-virtual-address-into-one-operation.patch +dm-fix-typo-in-error-message.patch +dm-thin-add-missing-destroy_work_on_stack.patch +pci-dwc-ep-fix-advertised-resizable-bar-size-regression.patch +pci-of_property-assign-pci-instead-of-cpu-bus-address-to-dynamic-pci-nodes.patch +pci-rockchip-ep-fix-address-translation-unit-programming.patch +nfsd-make-sure-exp-active-before-svc_export_show.patch +nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch +iio-accel-kx022a-fix-raw-read-format.patch +iio-invensense-fix-multiple-odr-switch-when-fifo-is-off.patch +iio-fix-fwnode_handle-in-__fwnode_iio_channel_get_by_name.patch +iio-adc-ad7923-fix-buffer-overflow-for-tx_buf-and-ring_xfer.patch +iio-gts-fix-infinite-loop-for-gain_to_scaletables.patch +powerpc-fix-stack-protector-kconfig-test-for-clang.patch +powerpc-adjust-adding-stack-protector-flags-to-kbuild_clags-for-clang.patch +binder-fix-node-uaf-in-binder_add_freeze_work.patch +binder-fix-oob-in-binder_add_freeze_work.patch +binder-fix-freeze-uaf-in-binder_release_work.patch +binder-fix-binder_work_frozen_binder-debug-logs.patch +binder-fix-binder_work_clear_freeze_notification-debug-logs.patch +binder-allow-freeze-notification-for-dead-nodes.patch +binder-fix-memleak-of-proc-delivered_freeze.patch +binder-add-delivered_freeze-to-debugfs-output.patch diff --git a/queue-6.12/slab-fix-too-strict-alignment-check-in-create_cache.patch b/queue-6.12/slab-fix-too-strict-alignment-check-in-create_cache.patch new file mode 100644 index 00000000000..9ffa015e5db --- /dev/null +++ b/queue-6.12/slab-fix-too-strict-alignment-check-in-create_cache.patch @@ -0,0 +1,59 @@ +From 9008fe8fad8255edfdbecea32d7eb0485d939d0d Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Wed, 20 Nov 2024 13:46:21 +0100 +Subject: slab: Fix too strict alignment check in create_cache() + +From: Geert Uytterhoeven + +commit 9008fe8fad8255edfdbecea32d7eb0485d939d0d upstream. + +On m68k, where the minimum alignment of unsigned long is 2 bytes: + + Kernel panic - not syncing: __kmem_cache_create_args: Failed to create slab 'io_kiocb'. Error -22 + CPU: 0 UID: 0 PID: 1 Comm: swapper Not tainted 6.12.0-atari-03776-g7eaa1f99261a #1783 + Stack from 0102fe5c: + 0102fe5c 00514a2b 00514a2b ffffff00 00000001 0051f5ed 00425e78 00514a2b + 0041eb74 ffffffea 00000310 0051f5ed ffffffea ffffffea 00601f60 00000044 + 0102ff20 000e7a68 0051ab8e 004383b8 0051f5ed ffffffea 000000b8 00000007 + 01020c00 00000000 000e77f0 0041e5f0 005f67c0 0051f5ed 000000b6 0102fef4 + 00000310 0102fef4 00000000 00000016 005f676c 0060a34c 00000010 00000004 + 00000038 0000009a 01000000 000000b8 005f668e 0102e000 00001372 0102ff88 + Call Trace: [<00425e78>] dump_stack+0xc/0x10 + [<0041eb74>] panic+0xd8/0x26c + [<000e7a68>] __kmem_cache_create_args+0x278/0x2e8 + [<000e77f0>] __kmem_cache_create_args+0x0/0x2e8 + [<0041e5f0>] memset+0x0/0x8c + [<005f67c0>] io_uring_init+0x54/0xd2 + +The minimal alignment of an integral type may differ from its size, +hence is not safe to assume that an arbitrary freeptr_t (which is +basically an unsigned long) is always aligned to 4 or 8 bytes. + +As nothing seems to require the additional alignment, it is safe to fix +this by relaxing the check to the actual minimum alignment of freeptr_t. + +Fixes: aaa736b186239b7d ("io_uring: specify freeptr usage for SLAB_TYPESAFE_BY_RCU io_kiocb cache") +Fixes: d345bd2e9834e2da ("mm: add kmem_cache_create_rcu()") +Reported-by: Guenter Roeck +Closes: https://lore.kernel.org/37c588d4-2c32-4aad-a19e-642961f200d7@roeck-us.net +Cc: +Signed-off-by: Geert Uytterhoeven +Tested-by: Guenter Roeck +Reviewed-by: Jens Axboe +Signed-off-by: Vlastimil Babka +Signed-off-by: Greg Kroah-Hartman +--- + mm/slab_common.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/slab_common.c ++++ b/mm/slab_common.c +@@ -230,7 +230,7 @@ static struct kmem_cache *create_cache(c + if (args->use_freeptr_offset && + (args->freeptr_offset >= object_size || + !(flags & SLAB_TYPESAFE_BY_RCU) || +- !IS_ALIGNED(args->freeptr_offset, sizeof(freeptr_t)))) ++ !IS_ALIGNED(args->freeptr_offset, __alignof__(freeptr_t)))) + goto out; + + err = -ENOMEM; diff --git a/queue-6.12/thermal-int3400-fix-reading-of-current_uuid-for-active-policy.patch b/queue-6.12/thermal-int3400-fix-reading-of-current_uuid-for-active-policy.patch new file mode 100644 index 00000000000..f39cb4645e7 --- /dev/null +++ b/queue-6.12/thermal-int3400-fix-reading-of-current_uuid-for-active-policy.patch @@ -0,0 +1,47 @@ +From 7082503622986537f57bdb5ef23e69e70cfad881 Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Thu, 14 Nov 2024 12:02:13 -0800 +Subject: thermal: int3400: Fix reading of current_uuid for active policy + +From: Srinivas Pandruvada + +commit 7082503622986537f57bdb5ef23e69e70cfad881 upstream. + +When the current_uuid attribute is set to the active policy UUID, +reading back the same attribute is returning "INVALID" instead of +the active policy UUID on some platforms before Ice Lake. + +In platforms before Ice Lake, firmware provides a list of supported +thermal policies. In this case, user space can select any of the +supported thermal policies via a write to attribute "current_uuid". + +In commit c7ff29763989 ("thermal: int340x: Update OS policy capability +handshake")', the OS policy handshake was updated to support Ice Lake +and later platforms and it treated priv->current_uuid_index=0 as +invalid. However, priv->current_uuid_index=0 is for the active policy, +only priv->current_uuid_index=-1 is invalid. + +Fix this issue by updating the priv->current_uuid_index check. + +Fixes: c7ff29763989 ("thermal: int340x: Update OS policy capability handshake") +Signed-off-by: Srinivas Pandruvada +Cc: 5.18+ # 5.18+ +Link: https://patch.msgid.link/20241114200213.422303-1-srinivas.pandruvada@linux.intel.com +[ rjw: Subject and changelog edits ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/thermal/intel/int340x_thermal/int3400_thermal.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c ++++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +@@ -137,7 +137,7 @@ static ssize_t current_uuid_show(struct + struct int3400_thermal_priv *priv = dev_get_drvdata(dev); + int i, length = 0; + +- if (priv->current_uuid_index > 0) ++ if (priv->current_uuid_index >= 0) + return sprintf(buf, "%s\n", + int3400_thermal_uuids[priv->current_uuid_index]); + diff --git a/queue-6.12/util_macros.h-fix-rework-find_closest-macros.patch b/queue-6.12/util_macros.h-fix-rework-find_closest-macros.patch new file mode 100644 index 00000000000..9d26f679861 --- /dev/null +++ b/queue-6.12/util_macros.h-fix-rework-find_closest-macros.patch @@ -0,0 +1,188 @@ +From bc73b4186736341ab5cd2c199da82db6e1134e13 Mon Sep 17 00:00:00 2001 +From: Alexandru Ardelean +Date: Tue, 5 Nov 2024 16:54:05 +0200 +Subject: util_macros.h: fix/rework find_closest() macros + +From: Alexandru Ardelean + +commit bc73b4186736341ab5cd2c199da82db6e1134e13 upstream. + +A bug was found in the find_closest() (find_closest_descending() is also +affected after some testing), where for certain values with small +progressions, the rounding (done by averaging 2 values) causes an +incorrect index to be returned. The rounding issues occur for +progressions of 1, 2 and 3. It goes away when the progression/interval +between two values is 4 or larger. + +It's particularly bad for progressions of 1. For example if there's an +array of 'a = { 1, 2, 3 }', using 'find_closest(2, a ...)' would return 0 +(the index of '1'), rather than returning 1 (the index of '2'). This +means that for exact values (with a progression of 1), find_closest() will +misbehave and return the index of the value smaller than the one we're +searching for. + +For progressions of 2 and 3, the exact values are obtained correctly; but +values aren't approximated correctly (as one would expect). Starting with +progressions of 4, all seems to be good (one gets what one would expect). + +While one could argue that 'find_closest()' should not be used for arrays +with progressions of 1 (i.e. '{1, 2, 3, ...}', the macro should still +behave correctly. + +The bug was found while testing the 'drivers/iio/adc/ad7606.c', +specifically the oversampling feature. +For reference, the oversampling values are listed as: + static const unsigned int ad7606_oversampling_avail[7] = { + 1, 2, 4, 8, 16, 32, 64, + }; + +When doing: + 1. $ echo 1 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio + $ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio + 1 # this is fine + 2. $ echo 2 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio + $ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio + 1 # this is wrong; 2 should be returned here + 3. $ echo 3 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio + $ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio + 2 # this is fine + 4. $ echo 4 > /sys/bus/iio/devices/iio\:device0/oversampling_ratio + $ cat /sys/bus/iio/devices/iio\:device0/oversampling_ratio + 4 # this is fine +And from here-on, the values are as correct (one gets what one would +expect.) + +While writing a kunit test for this bug, a peculiar issue was found for the +array in the 'drivers/hwmon/ina2xx.c' & 'drivers/iio/adc/ina2xx-adc.c' +drivers. While running the kunit test (for 'ina226_avg_tab' from these +drivers): + * idx = find_closest([-1 to 2], ina226_avg_tab, ARRAY_SIZE(ina226_avg_tab)); + This returns idx == 0, so value. + * idx = find_closest(3, ina226_avg_tab, ARRAY_SIZE(ina226_avg_tab)); + This returns idx == 0, value 1; and now one could argue whether 3 is + closer to 4 or to 1. This quirk only appears for value '3' in this + array, but it seems to be a another rounding issue. + * And from 4 onwards the 'find_closest'() works fine (one gets what one + would expect). + +This change reworks the find_closest() macros to also check the difference +between the left and right elements when 'x'. If the distance to the right +is smaller (than the distance to the left), the index is incremented by 1. +This also makes redundant the need for using the DIV_ROUND_CLOSEST() macro. + +In order to accommodate for any mix of negative + positive values, the +internal variables '__fc_x', '__fc_mid_x', '__fc_left' & '__fc_right' are +forced to 'long' type. This also addresses any potential bugs/issues with +'x' being of an unsigned type. In those situations any comparison between +signed & unsigned would be promoted to a comparison between 2 unsigned +numbers; this is especially annoying when '__fc_left' & '__fc_right' +underflow. + +The find_closest_descending() macro was also reworked and duplicated from +the find_closest(), and it is being iterated in reverse. The main reason +for this is to get the same indices as 'find_closest()' (but in reverse). +The comparison for '__fc_right < __fc_left' favors going the array in +ascending order. +For example for array '{ 1024, 512, 256, 128, 64, 16, 4, 1 }' and x = 3, we +get: + __fc_mid_x = 2 + __fc_left = -1 + __fc_right = -2 + Then '__fc_right < __fc_left' evaluates to true and '__fc_i++' becomes 7 + which is not quite incorrect, but 3 is closer to 4 than to 1. + +This change has been validated with the kunit from the next patch. + +Link: https://lkml.kernel.org/r/20241105145406.554365-1-aardelean@baylibre.com +Fixes: 95d119528b0b ("util_macros.h: add find_closest() macro") +Signed-off-by: Alexandru Ardelean +Cc: Bartosz Golaszewski +Cc: Greg Kroah-Hartman +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/util_macros.h | 56 +++++++++++++++++++++++++++++++------------- + 1 file changed, 40 insertions(+), 16 deletions(-) + +--- a/include/linux/util_macros.h ++++ b/include/linux/util_macros.h +@@ -4,19 +4,6 @@ + + #include + +-#define __find_closest(x, a, as, op) \ +-({ \ +- typeof(as) __fc_i, __fc_as = (as) - 1; \ +- typeof(x) __fc_x = (x); \ +- typeof(*a) const *__fc_a = (a); \ +- for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ +- if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \ +- __fc_a[__fc_i + 1], 2)) \ +- break; \ +- } \ +- (__fc_i); \ +-}) +- + /** + * find_closest - locate the closest element in a sorted array + * @x: The reference value. +@@ -25,8 +12,27 @@ + * @as: Size of 'a'. + * + * Returns the index of the element closest to 'x'. ++ * Note: If using an array of negative numbers (or mixed positive numbers), ++ * then be sure that 'x' is of a signed-type to get good results. + */ +-#define find_closest(x, a, as) __find_closest(x, a, as, <=) ++#define find_closest(x, a, as) \ ++({ \ ++ typeof(as) __fc_i, __fc_as = (as) - 1; \ ++ long __fc_mid_x, __fc_x = (x); \ ++ long __fc_left, __fc_right; \ ++ typeof(*a) const *__fc_a = (a); \ ++ for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \ ++ __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i + 1]) / 2; \ ++ if (__fc_x <= __fc_mid_x) { \ ++ __fc_left = __fc_x - __fc_a[__fc_i]; \ ++ __fc_right = __fc_a[__fc_i + 1] - __fc_x; \ ++ if (__fc_right < __fc_left) \ ++ __fc_i++; \ ++ break; \ ++ } \ ++ } \ ++ (__fc_i); \ ++}) + + /** + * find_closest_descending - locate the closest element in a sorted array +@@ -36,9 +42,27 @@ + * @as: Size of 'a'. + * + * Similar to find_closest() but 'a' is expected to be sorted in descending +- * order. ++ * order. The iteration is done in reverse order, so that the comparison ++ * of '__fc_right' & '__fc_left' also works for unsigned numbers. + */ +-#define find_closest_descending(x, a, as) __find_closest(x, a, as, >=) ++#define find_closest_descending(x, a, as) \ ++({ \ ++ typeof(as) __fc_i, __fc_as = (as) - 1; \ ++ long __fc_mid_x, __fc_x = (x); \ ++ long __fc_left, __fc_right; \ ++ typeof(*a) const *__fc_a = (a); \ ++ for (__fc_i = __fc_as; __fc_i >= 1; __fc_i--) { \ ++ __fc_mid_x = (__fc_a[__fc_i] + __fc_a[__fc_i - 1]) / 2; \ ++ if (__fc_x <= __fc_mid_x) { \ ++ __fc_left = __fc_x - __fc_a[__fc_i]; \ ++ __fc_right = __fc_a[__fc_i - 1] - __fc_x; \ ++ if (__fc_right < __fc_left) \ ++ __fc_i--; \ ++ break; \ ++ } \ ++ } \ ++ (__fc_i); \ ++}) + + /** + * is_insidevar - check if the @ptr points inside the @var memory range.