From bf5448ee9a9a7185ff7fef5a0b5a4d6586ca3a59 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 3 Feb 2026 17:29:20 +0100 Subject: [PATCH] 5.15-stable patches added patches: alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-blkcg_reset_stats.patch bluetooth-fix-hci_suspend_sync-crash.patch can-esd_usb-esd_usb_read_bulk_callback-fix-urb-memory-leak.patch comedi-fix-getting-range-information-for-subdevices-16-to-255.patch dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch drm-amdkfd-fix-a-memory-leak-in-device_queue_manager_init.patch drm-ttm-fix-undefined-behavior-in-bit-shift-for-ttm_tt_flag_priv_populated.patch espintcp-fix-skb-leaks.patch ext4-fix-memory-leaks-in-ext4_fname_-setup_filename-prepare_lookup.patch fs-ntfs3-initialize-allocated-memory-before-use.patch genirq-irq_sim-initialize-work-context-pointers-properly.patch hid-uclogic-add-null-check-in-uclogic_input_configured.patch hid-uclogic-correct-devm-device-reference-for-hidinput-input_dev-name.patch iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-under-concurrency.patch ksmbd-smbd-fix-dma_unmap_sg-nents.patch mei-trace-treat-reg-parameter-as-string.patch mm-pagewalk-add-walk_page_range_vma.patch net-add-locking-to-protect-skb-dev-access-in-ip_output.patch net-stmmac-make-sure-that-ptp_rate-is-not-0-before-configuring-est.patch nfsd-fix-race-between-nfsd-registration-and-exports_proc.patch nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch nvme-fix-pcie-subsystem-reset-controller-state-transition.patch nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch of-platform-use-default-match-table-for-firmware.patch scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch usbnet-fix-using-smp_processor_id-in-preemptible-code-warnings.patch w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch w1-w1_therm-use-swap-to-make-code-cleaner.patch wifi-cfg80211-add-a-work-abstraction-with-special-semantics.patch wifi-mac80211-move-tdls-work-to-wiphy-work.patch wifi-mac80211-use-wiphy-work-for-sdata-work.patch xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch --- ...-buffer-overflow-in-config-retrieval.patch | 57 +++ ...ndant-max-link-speed-from-nanopi-r4s.patch | 40 ++ ...-after-clearing-in-blkcg_reset_stats.patch | 58 +++ ...bluetooth-fix-hci_suspend_sync-crash.patch | 66 ++++ ...ad_bulk_callback-fix-urb-memory-leak.patch | 59 +++ ...information-for-subdevices-16-to-255.patch | 100 +++++ ...-fix-device-leak-on-route-allocation.patch | 91 +++++ ...ode-leak-on-route-allocation-failure.patch | 48 +++ ...ry-leak-in-device_queue_manager_init.patch | 67 ++++ ...shift-for-ttm_tt_flag_priv_populated.patch | 100 +++++ queue-5.15/espintcp-fix-skb-leaks.patch | 69 ++++ ...fname_-setup_filename-prepare_lookup.patch | 99 +++++ ...itialize-allocated-memory-before-use.patch | 75 ++++ ...alize-work-context-pointers-properly.patch | 39 ++ ...ll-check-in-uclogic_input_configured.patch | 44 +++ ...eference-for-hidinput-input_dev-name.patch | 70 ++++ ...adc-fix-of-populate-on-driver-rebind.patch | 69 ++++ ...ver-holes-in-scan_get_next_rmap_item.patch | 230 +++++++++++ ...d_tree_connect_put-under-concurrency.patch | 101 +++++ .../ksmbd-smbd-fix-dma_unmap_sg-nents.patch | 72 ++++ ...-trace-treat-reg-parameter-as-string.patch | 104 +++++ .../mm-pagewalk-add-walk_page_range_vma.patch | 77 ++++ ...-protect-skb-dev-access-in-ip_output.patch | 116 ++++++ ...rate-is-not-0-before-configuring-est.patch | 62 +++ ...n-nfsd-registration-and-exports_proc.patch | 169 ++++++++ ..._ctrl-callback-to-match-name-pattern.patch | 47 +++ ...em-reset-controller-state-transition.patch | 58 +++ ...directly-handle-subsys-reset-fallout.patch | 205 ++++++++++ ...use-default-match-table-for-firmware.patch | 40 ++ ...ntial-memory-leak-in-scsiback_remove.patch | 40 ++ queue-5.15/series | 38 ++ ...d-dst_dev_rcu-in-get_netdev_for_sock.patch | 62 +++ ...ssor_id-in-preemptible-code-warnings.patch | 78 ++++ ...-one-buffer-overflow-in-alarms_store.patch | 136 +++++++ ..._therm-use-swap-to-make-code-cleaner.patch | 50 +++ ...k-abstraction-with-special-semantics.patch | 368 ++++++++++++++++++ ...ac80211-move-tdls-work-to-wiphy-work.patch | 104 +++++ ...c80211-use-wiphy-work-for-sdata-work.patch | 315 +++++++++++++++ ...parse-alloc-of-last-full-inode-chunk.patch | 85 ++++ 39 files changed, 3708 insertions(+) create mode 100644 queue-5.15/alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch create mode 100644 queue-5.15/arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch create mode 100644 queue-5.15/blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-blkcg_reset_stats.patch create mode 100644 queue-5.15/bluetooth-fix-hci_suspend_sync-crash.patch create mode 100644 queue-5.15/can-esd_usb-esd_usb_read_bulk_callback-fix-urb-memory-leak.patch create mode 100644 queue-5.15/comedi-fix-getting-range-information-for-subdevices-16-to-255.patch create mode 100644 queue-5.15/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch create mode 100644 queue-5.15/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch create mode 100644 queue-5.15/drm-amdkfd-fix-a-memory-leak-in-device_queue_manager_init.patch create mode 100644 queue-5.15/drm-ttm-fix-undefined-behavior-in-bit-shift-for-ttm_tt_flag_priv_populated.patch create mode 100644 queue-5.15/espintcp-fix-skb-leaks.patch create mode 100644 queue-5.15/ext4-fix-memory-leaks-in-ext4_fname_-setup_filename-prepare_lookup.patch create mode 100644 queue-5.15/fs-ntfs3-initialize-allocated-memory-before-use.patch create mode 100644 queue-5.15/genirq-irq_sim-initialize-work-context-pointers-properly.patch create mode 100644 queue-5.15/hid-uclogic-add-null-check-in-uclogic_input_configured.patch create mode 100644 queue-5.15/hid-uclogic-correct-devm-device-reference-for-hidinput-input_dev-name.patch create mode 100644 queue-5.15/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch create mode 100644 queue-5.15/ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch create mode 100644 queue-5.15/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-under-concurrency.patch create mode 100644 queue-5.15/ksmbd-smbd-fix-dma_unmap_sg-nents.patch create mode 100644 queue-5.15/mei-trace-treat-reg-parameter-as-string.patch create mode 100644 queue-5.15/mm-pagewalk-add-walk_page_range_vma.patch create mode 100644 queue-5.15/net-add-locking-to-protect-skb-dev-access-in-ip_output.patch create mode 100644 queue-5.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-configuring-est.patch create mode 100644 queue-5.15/nfsd-fix-race-between-nfsd-registration-and-exports_proc.patch create mode 100644 queue-5.15/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch create mode 100644 queue-5.15/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch create mode 100644 queue-5.15/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch create mode 100644 queue-5.15/of-platform-use-default-match-table-for-firmware.patch create mode 100644 queue-5.15/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch create mode 100644 queue-5.15/tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch create mode 100644 queue-5.15/usbnet-fix-using-smp_processor_id-in-preemptible-code-warnings.patch create mode 100644 queue-5.15/w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch create mode 100644 queue-5.15/w1-w1_therm-use-swap-to-make-code-cleaner.patch create mode 100644 queue-5.15/wifi-cfg80211-add-a-work-abstraction-with-special-semantics.patch create mode 100644 queue-5.15/wifi-mac80211-move-tdls-work-to-wiphy-work.patch create mode 100644 queue-5.15/wifi-mac80211-use-wiphy-work-for-sdata-work.patch create mode 100644 queue-5.15/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch diff --git a/queue-5.15/alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch b/queue-5.15/alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch new file mode 100644 index 0000000000..9d9e16808d --- /dev/null +++ b/queue-5.15/alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch @@ -0,0 +1,57 @@ +From stable+bounces-212648-greg=kroah.com@vger.kernel.org Wed Jan 28 18:46:33 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 12:42:20 -0500 +Subject: ALSA: scarlett2: Fix buffer overflow in config retrieval +To: stable@vger.kernel.org +Cc: Samasth Norway Ananda , Takashi Iwai , Sasha Levin +Message-ID: <20260128174220.2597086-1-sashal@kernel.org> + +From: Samasth Norway Ananda + +[ Upstream commit 6f5c69f72e50d51be3a8c028ae7eda42c82902cb ] + +The scarlett2_usb_get_config() function has a logic error in the +endianness conversion code that can cause buffer overflows when +count > 1. + +The code checks `if (size == 2)` where `size` is the total buffer size in +bytes, then loops `count` times treating each element as u16 (2 bytes). +This causes the loop to access `count * 2` bytes when the buffer only +has `size` bytes allocated. + +Fix by checking the element size (config_item->size) instead of the +total buffer size. This ensures the endianness conversion matches the +actual element type. + +Fixes: ac34df733d2d ("ALSA: usb-audio: scarlett2: Update get_config to do endian conversion") +Cc: stable@vger.kernel.org +Signed-off-by: Samasth Norway Ananda +Link: https://patch.msgid.link/20260117012706.1715574-1-samasth.norway.ananda@oracle.com +Signed-off-by: Takashi Iwai +[ add 32-bit handling block ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + sound/usb/mixer_scarlett_gen2.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/sound/usb/mixer_scarlett_gen2.c ++++ b/sound/usb/mixer_scarlett_gen2.c +@@ -1194,11 +1194,16 @@ static int scarlett2_usb_get_config( + err = scarlett2_usb_get(mixer, config_item->offset, buf, size); + if (err < 0) + return err; +- if (size == 2) { ++ if (config_item->size == 16) { + u16 *buf_16 = buf; + + for (i = 0; i < count; i++, buf_16++) + *buf_16 = le16_to_cpu(*(__le16 *)buf_16); ++ } else if (config_item->size == 32) { ++ u32 *buf_32 = (u32 *)buf; ++ ++ for (i = 0; i < count; i++, buf_32++) ++ *buf_32 = le32_to_cpu(*(__le32 *)buf_32); + } + return 0; + } diff --git a/queue-5.15/arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch b/queue-5.15/arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch new file mode 100644 index 0000000000..49796bc493 --- /dev/null +++ b/queue-5.15/arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch @@ -0,0 +1,40 @@ +From stable+bounces-211650-greg=kroah.com@vger.kernel.org Mon Jan 26 17:35:37 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 11:35:26 -0500 +Subject: arm64: dts: rockchip: remove redundant max-link-speed from nanopi-r4s +To: stable@vger.kernel.org +Cc: Geraldo Nascimento , Dragan Simic , Shawn Lin , Heiko Stuebner , Sasha Levin +Message-ID: <20260126163526.3391456-1-sashal@kernel.org> + +From: Geraldo Nascimento + +[ Upstream commit ce652c98a7bfa0b7c675ef5cd85c44c186db96af ] + +This is already the default in rk3399-base.dtsi, remove redundant +declaration from rk3399-nanopi-r4s.dtsi. + +Fixes: db792e9adbf8 ("rockchip: rk3399: Add support for FriendlyARM NanoPi R4S") +Cc: stable@vger.kernel.org +Reported-by: Dragan Simic +Reviewed-by: Dragan Simic +Signed-off-by: Geraldo Nascimento +Acked-by: Shawn Lin +Link: https://patch.msgid.link/6694456a735844177c897581f785cc00c064c7d1.1763415706.git.geraldogabriel@gmail.com +Signed-off-by: Heiko Stuebner +[ adapted file path from rk3399-nanopi-r4s.dtsi to rk3399-nanopi-r4s.dts ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts | 1 - + 1 file changed, 1 deletion(-) + +--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts +@@ -73,7 +73,6 @@ + }; + + &pcie0 { +- max-link-speed = <1>; + num-lanes = <1>; + vpcie3v3-supply = <&vcc3v3_sys>; + }; diff --git a/queue-5.15/blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-blkcg_reset_stats.patch b/queue-5.15/blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-blkcg_reset_stats.patch new file mode 100644 index 0000000000..012c83e8b5 --- /dev/null +++ b/queue-5.15/blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-blkcg_reset_stats.patch @@ -0,0 +1,58 @@ +From stable+bounces-211720-greg=kroah.com@vger.kernel.org Tue Jan 27 05:03:44 2026 +From: alvalan9@foxmail.com +Date: Tue, 27 Jan 2026 04:03:26 +0000 +Subject: blk-cgroup: Reinit blkg_iostat_set after clearing in blkcg_reset_stats() +To: stable@vger.kernel.org +Cc: Waiman Long , Ming Lei , Tejun Heo , Jens Axboe , Alva Lan +Message-ID: + +From: Waiman Long + +[ Upstream commit 3d2af77e31ade05ff7ccc3658c3635ec1bea0979 ] + +When blkg_alloc() is called to allocate a blkcg_gq structure +with the associated blkg_iostat_set's, there are 2 fields within +blkg_iostat_set that requires proper initialization - blkg & sync. +The former field was introduced by commit 3b8cc6298724 ("blk-cgroup: +Optimize blkcg_rstat_flush()") while the later one was introduced by +commit f73316482977 ("blk-cgroup: reimplement basic IO stats using +cgroup rstat"). + +Unfortunately those fields in the blkg_iostat_set's are not properly +re-initialized when they are cleared in v1's blkcg_reset_stats(). This +can lead to a kernel panic due to NULL pointer access of the blkg +pointer. The missing initialization of sync is less problematic and +can be a problem in a debug kernel due to missing lockdep initialization. + +Fix these problems by re-initializing them after memory clearing. + +Fixes: 3b8cc6298724 ("blk-cgroup: Optimize blkcg_rstat_flush()") +Fixes: f73316482977 ("blk-cgroup: reimplement basic IO stats using cgroup rstat") +Signed-off-by: Waiman Long +Reviewed-by: Ming Lei +Acked-by: Tejun Heo +Link: https://lore.kernel.org/r/20230606180724.2455066-1-longman@redhat.com +Signed-off-by: Jens Axboe +[ Remove this line: bis -> blkg = blkg for blkg was introduced by commit + 3b8cc6298724 ("blk-cgroup: Optimize blkcg_rstat_flush()") since v6.2. ] +Signed-off-by: Alva Lan +Signed-off-by: Greg Kroah-Hartman +--- + block/blk-cgroup.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/block/blk-cgroup.c ++++ b/block/blk-cgroup.c +@@ -491,8 +491,12 @@ static int blkcg_reset_stats(struct cgro + struct blkg_iostat_set *bis = + per_cpu_ptr(blkg->iostat_cpu, cpu); + memset(bis, 0, sizeof(*bis)); ++ ++ /* Re-initialize the cleared blkg_iostat_set */ ++ u64_stats_init(&bis->sync); + } + memset(&blkg->iostat, 0, sizeof(blkg->iostat)); ++ u64_stats_init(&blkg->iostat.sync); + + for (i = 0; i < BLKCG_MAX_POLS; i++) { + struct blkcg_policy *pol = blkcg_policy[i]; diff --git a/queue-5.15/bluetooth-fix-hci_suspend_sync-crash.patch b/queue-5.15/bluetooth-fix-hci_suspend_sync-crash.patch new file mode 100644 index 0000000000..379304281c --- /dev/null +++ b/queue-5.15/bluetooth-fix-hci_suspend_sync-crash.patch @@ -0,0 +1,66 @@ +From stable+bounces-213055-greg=kroah.com@vger.kernel.org Mon Feb 2 11:55:20 2026 +From: jetlan9@163.com +Date: Mon, 2 Feb 2026 10:48:57 +0000 +Subject: Bluetooth: Fix hci_suspend_sync crash +To: stable@vger.kernel.org +Cc: Ying Hsu , Luiz Augusto von Dentz , Wenshan Lan +Message-ID: <20260202104857.4134-1-jetlan9@163.com> + +From: Ying Hsu + +[ Upstream commit 573ebae162111063eedc6c838a659ba628f66a0f ] + +If hci_unregister_dev() frees the hci_dev object but hci_suspend_notifier +may still be accessing it, it can cause the program to crash. +Here's the call trace: + <4>[102152.653246] Call Trace: + <4>[102152.653254] hci_suspend_sync+0x109/0x301 [bluetooth] + <4>[102152.653259] hci_suspend_dev+0x78/0xcd [bluetooth] + <4>[102152.653263] hci_suspend_notifier+0x42/0x7a [bluetooth] + <4>[102152.653268] notifier_call_chain+0x43/0x6b + <4>[102152.653271] __blocking_notifier_call_chain+0x48/0x69 + <4>[102152.653273] __pm_notifier_call_chain+0x22/0x39 + <4>[102152.653276] pm_suspend+0x287/0x57c + <4>[102152.653278] state_store+0xae/0xe5 + <4>[102152.653281] kernfs_fop_write+0x109/0x173 + <4>[102152.653284] __vfs_write+0x16f/0x1a2 + <4>[102152.653287] ? selinux_file_permission+0xca/0x16f + <4>[102152.653289] ? security_file_permission+0x36/0x109 + <4>[102152.653291] vfs_write+0x114/0x21d + <4>[102152.653293] __x64_sys_write+0x7b/0xdb + <4>[102152.653296] do_syscall_64+0x59/0x194 + <4>[102152.653299] entry_SYSCALL_64_after_hwframe+0x5c/0xc1 + +This patch holds the reference count of the hci_dev object while +processing it in hci_suspend_notifier to avoid potential crash +caused by the race condition. + +Signed-off-by: Ying Hsu +Signed-off-by: Luiz Augusto von Dentz +[ Adjust context ] +Signed-off-by: Wenshan Lan +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/hci_core.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -3706,6 +3706,9 @@ static int hci_suspend_notifier(struct n + int ret = 0; + u8 state = BT_RUNNING; + ++ /* To avoid a potential race with hci_unregister_dev. */ ++ hci_dev_hold(hdev); ++ + /* If powering down, wait for completion. */ + if (mgmt_powering_down(hdev)) { + set_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks); +@@ -3757,6 +3760,7 @@ done: + bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d", + action, ret); + ++ hci_dev_put(hdev); + return NOTIFY_DONE; + } + diff --git a/queue-5.15/can-esd_usb-esd_usb_read_bulk_callback-fix-urb-memory-leak.patch b/queue-5.15/can-esd_usb-esd_usb_read_bulk_callback-fix-urb-memory-leak.patch new file mode 100644 index 0000000000..454f70540f --- /dev/null +++ b/queue-5.15/can-esd_usb-esd_usb_read_bulk_callback-fix-urb-memory-leak.patch @@ -0,0 +1,59 @@ +From 5a4391bdc6c8357242f62f22069c865b792406b3 Mon Sep 17 00:00:00 2001 +From: Marc Kleine-Budde +Date: Sat, 10 Jan 2026 12:52:27 +0100 +Subject: can: esd_usb: esd_usb_read_bulk_callback(): fix URB memory leak + +From: Marc Kleine-Budde + +commit 5a4391bdc6c8357242f62f22069c865b792406b3 upstream. + +Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb: +gs_usb_receive_bulk_callback(): fix URB memory leak"). + +In esd_usb_open(), the URBs for USB-in transfers are allocated, added to +the dev->rx_submitted anchor and submitted. In the complete callback +esd_usb_read_bulk_callback(), the URBs are processed and resubmitted. In +esd_usb_close() the URBs are freed by calling +usb_kill_anchored_urbs(&dev->rx_submitted). + +However, this does not take into account that the USB framework unanchors +the URB before the complete function is called. This means that once an +in-URB has been completed, it is no longer anchored and is ultimately not +released in esd_usb_close(). + +Fix the memory leak by anchoring the URB in the +esd_usb_read_bulk_callback() to the dev->rx_submitted anchor. + +Fixes: 96d8e90382dc ("can: Add driver for esd CAN-USB/2 device") +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260116-can_usb-fix-memory-leak-v2-2-4b8cb2915571@pengutronix.de +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/esd_usb2.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/net/can/usb/esd_usb2.c ++++ b/drivers/net/can/usb/esd_usb2.c +@@ -440,13 +440,20 @@ resubmit_urb: + urb->transfer_buffer, RX_BUFFER_SIZE, + esd_usb2_read_bulk_callback, dev); + ++ usb_anchor_urb(urb, &dev->rx_submitted); ++ + retval = usb_submit_urb(urb, GFP_ATOMIC); ++ if (!retval) ++ return; ++ ++ usb_unanchor_urb(urb); ++ + if (retval == -ENODEV) { + for (i = 0; i < dev->net_count; i++) { + if (dev->nets[i]) + netif_device_detach(dev->nets[i]->netdev); + } +- } else if (retval) { ++ } else { + dev_err(dev->udev->dev.parent, + "failed resubmitting read bulk urb: %d\n", retval); + } diff --git a/queue-5.15/comedi-fix-getting-range-information-for-subdevices-16-to-255.patch b/queue-5.15/comedi-fix-getting-range-information-for-subdevices-16-to-255.patch new file mode 100644 index 0000000000..057d92729b --- /dev/null +++ b/queue-5.15/comedi-fix-getting-range-information-for-subdevices-16-to-255.patch @@ -0,0 +1,100 @@ +From 10d28cffb3f6ec7ad67f0a4cd32c2afa92909452 Mon Sep 17 00:00:00 2001 +From: Ian Abbott +Date: Wed, 3 Dec 2025 16:24:38 +0000 +Subject: comedi: Fix getting range information for subdevices 16 to 255 + +From: Ian Abbott + +commit 10d28cffb3f6ec7ad67f0a4cd32c2afa92909452 upstream. + +The `COMEDI_RANGEINFO` ioctl does not work properly for subdevice +indices above 15. Currently, the only in-tree COMEDI drivers that +support more than 16 subdevices are the "8255" driver and the +"comedi_bond" driver. Making the ioctl work for subdevice indices up to +255 is achievable. It needs minor changes to the handling of the +`COMEDI_RANGEINFO` and `COMEDI_CHANINFO` ioctls that should be mostly +harmless to user-space, apart from making them less broken. Details +follow... + +The `COMEDI_RANGEINFO` ioctl command gets the list of supported ranges +(usually with units of volts or milliamps) for a COMEDI subdevice or +channel. (Only some subdevices have per-channel range tables, indicated +by the `SDF_RANGETYPE` flag in the subdevice information.) It uses a +`range_type` value and a user-space pointer, both supplied by +user-space, but the `range_type` value should match what was obtained +using the `COMEDI_CHANINFO` ioctl (if the subdevice has per-channel +range tables) or `COMEDI_SUBDINFO` ioctl (if the subdevice uses a +single range table for all channels). Bits 15 to 0 of the `range_type` +value contain the length of the range table, which is the only part that +user-space should care about (so it can use a suitably sized buffer to +fetch the range table). Bits 23 to 16 store the channel index, which is +assumed to be no more than 255 if the subdevice has per-channel range +tables, and is set to 0 if the subdevice has a single range table. For +`range_type` values produced by the `COMEDI_SUBDINFO` ioctl, bits 31 to +24 contain the subdevice index, which is assumed to be no more than 255. +But for `range_type` values produced by the `COMEDI_CHANINFO` ioctl, +bits 27 to 24 contain the subdevice index, which is assumed to be no +more than 15, and bits 31 to 28 contain the COMEDI device's minor device +number for some unknown reason lost in the mists of time. The +`COMEDI_RANGEINFO` ioctl extract the length from bits 15 to 0 of the +user-supplied `range_type` value, extracts the channel index from bits +23 to 16 (only used if the subdevice has per-channel range tables), +extracts the subdevice index from bits 27 to 24, and ignores bits 31 to +28. So for subdevice indices 16 to 255, the `COMEDI_SUBDINFO` or +`COMEDI_CHANINFO` ioctl will report a `range_type` value that doesn't +work with the `COMEDI_RANGEINFO` ioctl. It will either get the range +table for the subdevice index modulo 16, or will fail with `-EINVAL`. + +To fix this, always use bits 31 to 24 of the `range_type` value to hold +the subdevice index (assumed to be no more than 255). This affects the +`COMEDI_CHANINFO` and `COMEDI_RANGEINFO` ioctls. There should not be +anything in user-space that depends on the old, broken usage, although +it may now see different values in bits 31 to 28 of the `range_type` +values reported by the `COMEDI_CHANINFO` ioctl for subdevices that have +per-channel subdevices. User-space should not be trying to decode bits +31 to 16 of the `range_type` values anyway. + +Fixes: ed9eccbe8970 ("Staging: add comedi core") +Cc: stable@vger.kernel.org #5.17+ +Signed-off-by: Ian Abbott +Link: https://patch.msgid.link/20251203162438.176841-1-abbotti@mev.co.uk +Signed-off-by: Greg Kroah-Hartman +--- + drivers/comedi/comedi.h | 2 +- + drivers/comedi/comedi_fops.c | 2 +- + drivers/comedi/range.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/comedi/comedi.h ++++ b/drivers/comedi/comedi.h +@@ -640,7 +640,7 @@ struct comedi_chaninfo { + + /** + * struct comedi_rangeinfo - used to retrieve the range table for a channel +- * @range_type: Encodes subdevice index (bits 27:24), channel index ++ * @range_type: Encodes subdevice index (bits 31:24), channel index + * (bits 23:16) and range table length (bits 15:0). + * @range_ptr: Pointer to array of @struct comedi_krange to be filled + * in with the range table for the channel or subdevice. +--- a/drivers/comedi/comedi_fops.c ++++ b/drivers/comedi/comedi_fops.c +@@ -1095,7 +1095,7 @@ static int do_chaninfo_ioctl(struct come + for (i = 0; i < s->n_chan; i++) { + int x; + +- x = (dev->minor << 28) | (it->subdev << 24) | (i << 16) | ++ x = (it->subdev << 24) | (i << 16) | + (s->range_table_list[i]->length); + if (put_user(x, it->rangelist + i)) + return -EFAULT; +--- a/drivers/comedi/range.c ++++ b/drivers/comedi/range.c +@@ -52,7 +52,7 @@ int do_rangeinfo_ioctl(struct comedi_dev + const struct comedi_lrange *lr; + struct comedi_subdevice *s; + +- subd = (it->range_type >> 24) & 0xf; ++ subd = (it->range_type >> 24) & 0xff; + chan = (it->range_type >> 16) & 0xff; + + if (!dev->attached) diff --git a/queue-5.15/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch b/queue-5.15/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch new file mode 100644 index 0000000000..f4c8562733 --- /dev/null +++ b/queue-5.15/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch @@ -0,0 +1,91 @@ +From stable+bounces-210741-greg=kroah.com@vger.kernel.org Wed Jan 21 13:27:37 2026 +From: Sasha Levin +Date: Wed, 21 Jan 2026 07:24:42 -0500 +Subject: dmaengine: stm32: dmamux: fix device leak on route allocation +To: stable@vger.kernel.org +Cc: Johan Hovold , Pierre-Yves MORDRET , Amelie Delaunay , Vinod Koul , Sasha Levin +Message-ID: <20260121122442.1527792-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit dd6e4943889fb354efa3f700e42739da9bddb6ef ] + +Make sure to drop the reference taken when looking up the DMA mux +platform device during route allocation. + +Note that holding a reference to a device does not prevent its driver +data from going away so there is no point in keeping the reference. + +Fixes: df7e762db5f6 ("dmaengine: Add STM32 DMAMUX driver") +Cc: stable@vger.kernel.org # 4.15 +Cc: Pierre-Yves MORDRET +Signed-off-by: Johan Hovold +Reviewed-by: Amelie Delaunay +Link: https://patch.msgid.link/20251117161258.10679-11-johan@kernel.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/stm32-dmamux.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +--- a/drivers/dma/stm32-dmamux.c ++++ b/drivers/dma/stm32-dmamux.c +@@ -88,23 +88,25 @@ static void *stm32_dmamux_route_allocate + struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev); + struct stm32_dmamux *mux; + u32 i, min, max; +- int ret; ++ int ret = -EINVAL; + unsigned long flags; + + if (dma_spec->args_count != 3) { + dev_err(&pdev->dev, "invalid number of dma mux args\n"); +- return ERR_PTR(-EINVAL); ++ goto err_put_pdev; + } + + if (dma_spec->args[0] > dmamux->dmamux_requests) { + dev_err(&pdev->dev, "invalid mux request number: %d\n", + dma_spec->args[0]); +- return ERR_PTR(-EINVAL); ++ goto err_put_pdev; + } + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); +- if (!mux) +- return ERR_PTR(-ENOMEM); ++ if (!mux) { ++ ret = -ENOMEM; ++ goto err_put_pdev; ++ } + + spin_lock_irqsave(&dmamux->lock, flags); + mux->chan_id = find_first_zero_bit(dmamux->dma_inuse, +@@ -131,7 +133,6 @@ static void *stm32_dmamux_route_allocate + dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", i - 1); + if (!dma_spec->np) { + dev_err(&pdev->dev, "can't get dma master\n"); +- ret = -EINVAL; + goto error; + } + +@@ -158,6 +159,8 @@ static void *stm32_dmamux_route_allocate + dev_dbg(&pdev->dev, "Mapping DMAMUX(%u) to DMA%u(%u)\n", + mux->request, mux->master, mux->chan_id); + ++ put_device(&pdev->dev); ++ + return mux; + + err_put_dma_spec_np: +@@ -167,6 +170,9 @@ error: + + error_chan_id: + kfree(mux); ++err_put_pdev: ++ put_device(&pdev->dev); ++ + return ERR_PTR(ret); + } + diff --git a/queue-5.15/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch b/queue-5.15/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch new file mode 100644 index 0000000000..ba59e971b4 --- /dev/null +++ b/queue-5.15/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch @@ -0,0 +1,48 @@ +From stable+bounces-210744-greg=kroah.com@vger.kernel.org Wed Jan 21 13:34:54 2026 +From: Sasha Levin +Date: Wed, 21 Jan 2026 07:29:54 -0500 +Subject: dmaengine: stm32: dmamux: fix OF node leak on route allocation failure +To: stable@vger.kernel.org +Cc: Johan Hovold , Pierre-Yves MORDRET , Amelie Delaunay , Vinod Koul , Sasha Levin +Message-ID: <20260121122954.1531423-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit b1b590a590af13ded598e70f0b72bc1e515787a1 ] + +Make sure to drop the reference taken to the DMA master OF node also on +late route allocation failures. + +Fixes: df7e762db5f6 ("dmaengine: Add STM32 DMAMUX driver") +Cc: stable@vger.kernel.org # 4.15 +Cc: Pierre-Yves MORDRET +Signed-off-by: Johan Hovold +Reviewed-by: Amelie Delaunay +Link: https://patch.msgid.link/20251117161258.10679-12-johan@kernel.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/stm32-dmamux.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/dma/stm32-dmamux.c ++++ b/drivers/dma/stm32-dmamux.c +@@ -140,7 +140,7 @@ static void *stm32_dmamux_route_allocate + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) { + spin_unlock_irqrestore(&dmamux->lock, flags); +- goto error; ++ goto err_put_dma_spec_np; + } + spin_unlock_irqrestore(&dmamux->lock, flags); + +@@ -160,6 +160,8 @@ static void *stm32_dmamux_route_allocate + + return mux; + ++err_put_dma_spec_np: ++ of_node_put(dma_spec->np); + error: + clear_bit(mux->chan_id, dmamux->dma_inuse); + diff --git a/queue-5.15/drm-amdkfd-fix-a-memory-leak-in-device_queue_manager_init.patch b/queue-5.15/drm-amdkfd-fix-a-memory-leak-in-device_queue_manager_init.patch new file mode 100644 index 0000000000..386b01ae32 --- /dev/null +++ b/queue-5.15/drm-amdkfd-fix-a-memory-leak-in-device_queue_manager_init.patch @@ -0,0 +1,67 @@ +From 80614c509810fc051312d1a7ccac8d0012d6b8d0 Mon Sep 17 00:00:00 2001 +From: Haoxiang Li +Date: Thu, 8 Jan 2026 15:18:22 +0800 +Subject: drm/amdkfd: fix a memory leak in device_queue_manager_init() + +From: Haoxiang Li + +commit 80614c509810fc051312d1a7ccac8d0012d6b8d0 upstream. + +If dqm->ops.initialize() fails, add deallocate_hiq_sdma_mqd() +to release the memory allocated by allocate_hiq_sdma_mqd(). +Move deallocate_hiq_sdma_mqd() up to ensure proper function +visibility at the point of use. + +Fixes: 11614c36bc8f ("drm/amdkfd: Allocate MQD trunk for HIQ and SDMA") +Signed-off-by: Haoxiang Li +Signed-off-by: Felix Kuehling +Reviewed-by: Oak Zeng +Reviewed-by: Felix Kuehling +Signed-off-by: Alex Deucher +(cherry picked from commit b7cccc8286bb9919a0952c812872da1dcfe9d390) +Cc: stable@vger.kernel.org +Signed-off-by: Felix Kuehling +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +@@ -1847,6 +1847,14 @@ static int allocate_hiq_sdma_mqd(struct + return retval; + } + ++static void deallocate_hiq_sdma_mqd(struct kfd_dev *dev, ++ struct kfd_mem_obj *mqd) ++{ ++ WARN(!mqd, "No hiq sdma mqd trunk to free"); ++ ++ amdgpu_amdkfd_free_gtt_mem(dev->kgd, &mqd->gtt_mem); ++} ++ + struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) + { + struct device_queue_manager *dqm; +@@ -1980,19 +1988,13 @@ struct device_queue_manager *device_queu + if (!dqm->ops.initialize(dqm)) + return dqm; + ++ deallocate_hiq_sdma_mqd(dev, &dqm->hiq_sdma_mqd); ++ + out_free: + kfree(dqm); + return NULL; + } + +-static void deallocate_hiq_sdma_mqd(struct kfd_dev *dev, +- struct kfd_mem_obj *mqd) +-{ +- WARN(!mqd, "No hiq sdma mqd trunk to free"); +- +- amdgpu_amdkfd_free_gtt_mem(dev->kgd, mqd->gtt_mem); +-} +- + void device_queue_manager_uninit(struct device_queue_manager *dqm) + { + dqm->ops.uninitialize(dqm); diff --git a/queue-5.15/drm-ttm-fix-undefined-behavior-in-bit-shift-for-ttm_tt_flag_priv_populated.patch b/queue-5.15/drm-ttm-fix-undefined-behavior-in-bit-shift-for-ttm_tt_flag_priv_populated.patch new file mode 100644 index 0000000000..2da46bbe06 --- /dev/null +++ b/queue-5.15/drm-ttm-fix-undefined-behavior-in-bit-shift-for-ttm_tt_flag_priv_populated.patch @@ -0,0 +1,100 @@ +From stable+bounces-209987-greg=kroah.com@vger.kernel.org Fri Jan 16 06:02:39 2026 +From: Rahul Sharma +Date: Fri, 16 Jan 2026 13:02:05 +0800 +Subject: drm/ttm: fix undefined behavior in bit shift for TTM_TT_FLAG_PRIV_POPULATED +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, "Gaosheng Cui" , "Christian König" , "Rahul Sharma" +Message-ID: <20260116050205.2296956-1-black.hawk@163.com> + +From: Gaosheng Cui + +[ Upstream 387659939c00156f8d6bab0fbc55b4eaf2b6bc5b commit ] + +Shifting signed 32-bit value by 31 bits is undefined, so changing +significant bit to unsigned. The UBSAN warning calltrace like below: + +UBSAN: shift-out-of-bounds in ./include/drm/ttm/ttm_tt.h:122:26 +left shift of 1 by 31 places cannot be represented in type 'int' +Call Trace: + + dump_stack_lvl+0x7d/0xa5 + dump_stack+0x15/0x1b + ubsan_epilogue+0xe/0x4e + __ubsan_handle_shift_out_of_bounds+0x1e7/0x20c + ttm_bo_move_memcpy+0x3b4/0x460 [ttm] + bo_driver_move+0x32/0x40 [drm_vram_helper] + ttm_bo_handle_move_mem+0x118/0x200 [ttm] + ttm_bo_validate+0xfa/0x220 [ttm] + drm_gem_vram_pin_locked+0x70/0x1b0 [drm_vram_helper] + drm_gem_vram_pin+0x48/0xb0 [drm_vram_helper] + drm_gem_vram_plane_helper_prepare_fb+0x53/0xe0 [drm_vram_helper] + drm_gem_vram_simple_display_pipe_prepare_fb+0x26/0x30 [drm_vram_helper] + drm_simple_kms_plane_prepare_fb+0x4d/0xe0 [drm_kms_helper] + drm_atomic_helper_prepare_planes+0xda/0x210 [drm_kms_helper] + drm_atomic_helper_commit+0xc3/0x1e0 [drm_kms_helper] + drm_atomic_commit+0x9c/0x160 [drm] + drm_client_modeset_commit_atomic+0x33a/0x380 [drm] + drm_client_modeset_commit_locked+0x77/0x220 [drm] + drm_client_modeset_commit+0x31/0x60 [drm] + __drm_fb_helper_restore_fbdev_mode_unlocked+0xa7/0x170 [drm_kms_helper] + drm_fb_helper_set_par+0x51/0x90 [drm_kms_helper] + fbcon_init+0x316/0x790 + visual_init+0x113/0x1d0 + do_bind_con_driver+0x2a3/0x5c0 + do_take_over_console+0xa9/0x270 + do_fbcon_takeover+0xa1/0x170 + do_fb_registered+0x2a8/0x340 + fbcon_fb_registered+0x47/0xe0 + register_framebuffer+0x294/0x4a0 + __drm_fb_helper_initial_config_and_unlock+0x43c/0x880 [drm_kms_helper] + drm_fb_helper_initial_config+0x52/0x80 [drm_kms_helper] + drm_fbdev_client_hotplug+0x156/0x1b0 [drm_kms_helper] + drm_fbdev_generic_setup+0xfc/0x290 [drm_kms_helper] + bochs_pci_probe+0x6ca/0x772 [bochs] + local_pci_probe+0x4d/0xb0 + pci_device_probe+0x119/0x320 + really_probe+0x181/0x550 + __driver_probe_device+0xc6/0x220 + driver_probe_device+0x32/0x100 + __driver_attach+0x195/0x200 + bus_for_each_dev+0xbb/0x120 + driver_attach+0x27/0x30 + bus_add_driver+0x22e/0x2f0 + driver_register+0xa9/0x190 + __pci_register_driver+0x90/0xa0 + bochs_pci_driver_init+0x52/0x1000 [bochs] + do_one_initcall+0x76/0x430 + do_init_module+0x61/0x28a + load_module+0x1f82/0x2e50 + __do_sys_finit_module+0xf8/0x190 + __x64_sys_finit_module+0x23/0x30 + do_syscall_64+0x58/0x80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + + +Fixes: 3312be8f6fc8 ("drm/ttm: move populated state into page flags") +Signed-off-by: Gaosheng Cui +Reviewed-by: Christian König +Link: https://patchwork.freedesktop.org/patch/msgid/20221031113350.4180975-1-cuigaosheng1@huawei.com +Signed-off-by: Christian König +[ The context change is due to the commit 43d46f0b78bb +("drm/ttm: s/FLAG_SG/FLAG_EXTERNAL/") in v5.16 +which is irrelevant to the logic of this patch. +In addition, v6.1 has included the fix. ] +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + include/drm/ttm/ttm_tt.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/drm/ttm/ttm_tt.h ++++ b/include/drm/ttm/ttm_tt.h +@@ -43,7 +43,7 @@ struct ttm_operation_ctx; + #define TTM_PAGE_FLAG_SG (1 << 8) + #define TTM_PAGE_FLAG_NO_RETRY (1 << 9) + +-#define TTM_PAGE_FLAG_PRIV_POPULATED (1 << 31) ++#define TTM_PAGE_FLAG_PRIV_POPULATED (1U << 31) + + /** + * struct ttm_tt diff --git a/queue-5.15/espintcp-fix-skb-leaks.patch b/queue-5.15/espintcp-fix-skb-leaks.patch new file mode 100644 index 0000000000..3189d60905 --- /dev/null +++ b/queue-5.15/espintcp-fix-skb-leaks.patch @@ -0,0 +1,69 @@ +From stable+bounces-211954-greg=kroah.com@vger.kernel.org Wed Jan 28 12:07:12 2026 +From: Bin Lan +Date: Wed, 28 Jan 2026 11:06:35 +0000 +Subject: espintcp: fix skb leaks +To: stable@vger.kernel.org +Cc: Sabrina Dubroca , Simon Horman , Steffen Klassert , Bin Lan +Message-ID: <20260128110635.4109-1-lanbincn@139.com> + +From: Sabrina Dubroca + +[ Upstream commit 63c1f19a3be3169e51a5812d22a6d0c879414076 ] + +A few error paths are missing a kfree_skb. + +Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)") +Signed-off-by: Sabrina Dubroca +Reviewed-by: Simon Horman +Signed-off-by: Steffen Klassert +[ Minor context change fixed. ] +Signed-off-by: Bin Lan +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/esp4.c | 4 +++- + net/ipv6/esp6.c | 4 +++- + net/xfrm/espintcp.c | 4 +++- + 3 files changed, 9 insertions(+), 3 deletions(-) + +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -196,8 +196,10 @@ static int esp_output_tcp_finish(struct + + sk = esp_find_tcp_sk(x); + err = PTR_ERR_OR_ZERO(sk); +- if (err) ++ if (err) { ++ kfree_skb(skb); + goto out; ++ } + + bh_lock_sock(sk); + if (sock_owned_by_user(sk)) +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -214,8 +214,10 @@ static int esp_output_tcp_finish(struct + + sk = esp6_find_tcp_sk(x); + err = PTR_ERR_OR_ZERO(sk); +- if (err) ++ if (err) { ++ kfree_skb(skb); + goto out; ++ } + + bh_lock_sock(sk); + if (sock_owned_by_user(sk)) +--- a/net/xfrm/espintcp.c ++++ b/net/xfrm/espintcp.c +@@ -170,8 +170,10 @@ int espintcp_queue_out(struct sock *sk, + { + struct espintcp_ctx *ctx = espintcp_getctx(sk); + +- if (skb_queue_len(&ctx->out_queue) >= READ_ONCE(netdev_max_backlog)) ++ if (skb_queue_len(&ctx->out_queue) >= READ_ONCE(netdev_max_backlog)) { ++ kfree_skb(skb); + return -ENOBUFS; ++ } + + __skb_queue_tail(&ctx->out_queue, skb); + diff --git a/queue-5.15/ext4-fix-memory-leaks-in-ext4_fname_-setup_filename-prepare_lookup.patch b/queue-5.15/ext4-fix-memory-leaks-in-ext4_fname_-setup_filename-prepare_lookup.patch new file mode 100644 index 0000000000..2dc8748504 --- /dev/null +++ b/queue-5.15/ext4-fix-memory-leaks-in-ext4_fname_-setup_filename-prepare_lookup.patch @@ -0,0 +1,99 @@ +From stable+bounces-211955-greg=kroah.com@vger.kernel.org Wed Jan 28 12:08:03 2026 +From: Bin Lan +Date: Wed, 28 Jan 2026 11:07:20 +0000 +Subject: ext4: fix memory leaks in ext4_fname_{setup_filename,prepare_lookup} +To: stable@vger.kernel.org +Cc: "Luís Henriques" , stable@kernel.org, "Eric Biggers" , "Theodore Ts'o" , "Bin Lan" +Message-ID: <20260128110720.4134-1-lanbincn@139.com> + +From: Luís Henriques + +[ Upstream commit 7ca4b085f430f3774c3838b3da569ceccd6a0177 ] + +If the filename casefolding fails, we'll be leaking memory from the +fscrypt_name struct, namely from the 'crypto_buf.name' member. + +Make sure we free it in the error path on both ext4_fname_setup_filename() +and ext4_fname_prepare_lookup() functions. + +Cc: stable@kernel.org +Fixes: 1ae98e295fa2 ("ext4: optimize match for casefolded encrypted dirs") +Signed-off-by: Luís Henriques +Reviewed-by: Eric Biggers +Link: https://lore.kernel.org/r/20230803091713.13239-1-lhenriques@suse.de +Signed-off-by: Theodore Ts'o +[ fs/ext4/crypto.c was removed by commit + a7550b30ab70 ("ext4 crypto: migrate into vfs's crypto engine") since + v4.8, so apply this patch to fs/ext4/ext4.h in v5.15. Move + ext4_fname_free_filename() to the front of ext4_fname_setup_filename() + to fix a build issue. ] +Signed-off-by: Bin Lan +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/ext4.h | 38 +++++++++++++++++++++----------------- + 1 file changed, 21 insertions(+), 17 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -2749,6 +2749,23 @@ static inline void ext4_fname_from_fscry + dst->crypto_buf = src->crypto_buf; + } + ++static inline void ext4_fname_free_filename(struct ext4_filename *fname) ++{ ++ struct fscrypt_name name; ++ ++ name.crypto_buf = fname->crypto_buf; ++ fscrypt_free_filename(&name); ++ ++ fname->crypto_buf.name = NULL; ++ fname->usr_fname = NULL; ++ fname->disk_name.name = NULL; ++ ++#ifdef CONFIG_UNICODE ++ kfree(fname->cf_name.name); ++ fname->cf_name.name = NULL; ++#endif ++} ++ + static inline int ext4_fname_setup_filename(struct inode *dir, + const struct qstr *iname, + int lookup, +@@ -2765,6 +2782,8 @@ static inline int ext4_fname_setup_filen + + #ifdef CONFIG_UNICODE + err = ext4_fname_setup_ci_filename(dir, iname, fname); ++ if (err) ++ ext4_fname_free_filename(fname); + #endif + return err; + } +@@ -2784,26 +2803,11 @@ static inline int ext4_fname_prepare_loo + + #ifdef CONFIG_UNICODE + err = ext4_fname_setup_ci_filename(dir, &dentry->d_name, fname); ++ if (err) ++ ext4_fname_free_filename(fname); + #endif + return err; + } +- +-static inline void ext4_fname_free_filename(struct ext4_filename *fname) +-{ +- struct fscrypt_name name; +- +- name.crypto_buf = fname->crypto_buf; +- fscrypt_free_filename(&name); +- +- fname->crypto_buf.name = NULL; +- fname->usr_fname = NULL; +- fname->disk_name.name = NULL; +- +-#ifdef CONFIG_UNICODE +- kfree(fname->cf_name.name); +- fname->cf_name.name = NULL; +-#endif +-} + #else /* !CONFIG_FS_ENCRYPTION */ + static inline int ext4_fname_setup_filename(struct inode *dir, + const struct qstr *iname, diff --git a/queue-5.15/fs-ntfs3-initialize-allocated-memory-before-use.patch b/queue-5.15/fs-ntfs3-initialize-allocated-memory-before-use.patch new file mode 100644 index 0000000000..dbf7fb4c0a --- /dev/null +++ b/queue-5.15/fs-ntfs3-initialize-allocated-memory-before-use.patch @@ -0,0 +1,75 @@ +From 1468888505@139.com Mon Jan 26 07:20:00 2026 +From: Li hongliang <1468888505@139.com> +Date: Mon, 26 Jan 2026 14:19:56 +0800 +Subject: fs/ntfs3: Initialize allocated memory before use +To: gregkh@linuxfoundation.org, stable@vger.kernel.org, kubik.bartlomiej@gmail.com +Cc: patches@lists.linux.dev, linux-kernel@vger.kernel.org, almaz.alexandrovich@paragon-software.com, ntfs3@lists.linux.dev, khalid@kernel.org +Message-ID: <20260126061956.1206899-1-1468888505@139.com> + +From: Bartlomiej Kubik + +[ Upstream commit a8a3ca23bbd9d849308a7921a049330dc6c91398 ] + +KMSAN reports: Multiple uninitialized values detected: + +- KMSAN: uninit-value in ntfs_read_hdr (3) +- KMSAN: uninit-value in bcmp (3) + +Memory is allocated by __getname(), which is a wrapper for +kmem_cache_alloc(). This memory is used before being properly +cleared. Change kmem_cache_alloc() to kmem_cache_zalloc() to +properly allocate and clear memory before use. + +Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block") +Fixes: 78ab59fee07f ("fs/ntfs3: Rework file operations") +Tested-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com +Reported-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=332bd4e9d148f11a87dc + +Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block") +Fixes: 78ab59fee07f ("fs/ntfs3: Rework file operations") +Tested-by: syzbot+0399100e525dd9696764@syzkaller.appspotmail.com +Reported-by: syzbot+0399100e525dd9696764@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=0399100e525dd9696764 + +Reviewed-by: Khalid Aziz +Signed-off-by: Bartlomiej Kubik +Signed-off-by: Konstantin Komarov +Signed-off-by: Li hongliang <1468888505@139.com> +Signed-off-by: Greg Kroah-Hartman +--- + fs/ntfs3/inode.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -1298,7 +1298,7 @@ struct inode *ntfs_create_inode(struct u + fa |= FILE_ATTRIBUTE_READONLY; + + /* Allocate PATH_MAX bytes. */ +- new_de = __getname(); ++ new_de = kmem_cache_zalloc(names_cachep, GFP_KERNEL); + if (!new_de) { + err = -ENOMEM; + goto out1; +@@ -1694,10 +1694,9 @@ int ntfs_link_inode(struct inode *inode, + struct ATTR_FILE_NAME *de_name; + + /* Allocate PATH_MAX bytes. */ +- de = __getname(); ++ de = kmem_cache_zalloc(names_cachep, GFP_KERNEL); + if (!de) + return -ENOMEM; +- memset(de, 0, PATH_MAX); + + /* Mark rw ntfs as dirty. It will be cleared at umount. */ + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); +@@ -1742,7 +1741,7 @@ int ntfs_unlink_inode(struct inode *dir, + return -EINVAL; + + /* Allocate PATH_MAX bytes. */ +- de = __getname(); ++ de = kmem_cache_zalloc(names_cachep, GFP_KERNEL); + if (!de) + return -ENOMEM; + diff --git a/queue-5.15/genirq-irq_sim-initialize-work-context-pointers-properly.patch b/queue-5.15/genirq-irq_sim-initialize-work-context-pointers-properly.patch new file mode 100644 index 0000000000..aa6ff95234 --- /dev/null +++ b/queue-5.15/genirq-irq_sim-initialize-work-context-pointers-properly.patch @@ -0,0 +1,39 @@ +From black.hawk@163.com Tue Feb 3 03:07:43 2026 +From: Rahul Sharma +Date: Tue, 3 Feb 2026 10:07:14 +0800 +Subject: genirq/irq_sim: Initialize work context pointers properly +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, Gyeyoung Baek , Thomas Gleixner , Rahul Sharma +Message-ID: <20260203020714.799655-1-black.hawk@163.com> + +From: Gyeyoung Baek + +[ Upstream commit 8a2277a3c9e4cc5398f80821afe7ecbe9bdf2819 ] + +Initialize `ops` member's pointers properly by using kzalloc() instead of +kmalloc() when allocating the simulation work context. Otherwise the +pointers contain random content leading to invalid dereferencing. + +Signed-off-by: Gyeyoung Baek +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/all/20250612124827.63259-1-gye976@gmail.com +[ The context change is due to the commit 011f583781fa +("genirq/irq_sim: add an extended irq_sim initializer") +which is irrelevant to the logic of this patch. ] +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + kernel/irq/irq_sim.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/irq/irq_sim.c ++++ b/kernel/irq/irq_sim.c +@@ -166,7 +166,7 @@ struct irq_domain *irq_domain_create_sim + { + struct irq_sim_work_ctx *work_ctx; + +- work_ctx = kmalloc(sizeof(*work_ctx), GFP_KERNEL); ++ work_ctx = kzalloc(sizeof(*work_ctx), GFP_KERNEL); + if (!work_ctx) + goto err_out; + diff --git a/queue-5.15/hid-uclogic-add-null-check-in-uclogic_input_configured.patch b/queue-5.15/hid-uclogic-add-null-check-in-uclogic_input_configured.patch new file mode 100644 index 0000000000..c4d2b846b3 --- /dev/null +++ b/queue-5.15/hid-uclogic-add-null-check-in-uclogic_input_configured.patch @@ -0,0 +1,44 @@ +From stable+bounces-213143-greg=kroah.com@vger.kernel.org Tue Feb 3 02:27:31 2026 +From: jetlan9@163.com +Date: Tue, 3 Feb 2026 01:21:44 +0000 +Subject: HID: uclogic: Add NULL check in uclogic_input_configured() +To: stable@vger.kernel.org +Cc: Henry Martin , Jiri Kosina , Wenshan Lan +Message-ID: <20260203012144.4215-2-jetlan9@163.com> + +From: Henry Martin + +[ Upstream commit bd07f751208ba190f9b0db5e5b7f35d5bb4a8a1e ] + +devm_kasprintf() returns NULL when memory allocation fails. Currently, +uclogic_input_configured() does not check for this case, which results +in a NULL pointer dereference. + +Add NULL check after devm_kasprintf() to prevent this issue. + +Fixes: dd613a4e45f8 ("HID: uclogic: Correct devm device reference for hidinput input_dev name") +Signed-off-by: Henry Martin +Signed-off-by: Jiri Kosina +[ Adjust context ] +Signed-off-by: Wenshan Lan +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-uclogic-core.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/hid/hid-uclogic-core.c ++++ b/drivers/hid/hid-uclogic-core.c +@@ -143,9 +143,12 @@ static int uclogic_input_configured(stru + break; + } + +- if (suffix) ++ if (suffix) { + hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "%s %s", hdev->name, suffix); ++ if (!hi->input->name) ++ return -ENOMEM; ++ } + + return 0; + } diff --git a/queue-5.15/hid-uclogic-correct-devm-device-reference-for-hidinput-input_dev-name.patch b/queue-5.15/hid-uclogic-correct-devm-device-reference-for-hidinput-input_dev-name.patch new file mode 100644 index 0000000000..da1f8a3ee9 --- /dev/null +++ b/queue-5.15/hid-uclogic-correct-devm-device-reference-for-hidinput-input_dev-name.patch @@ -0,0 +1,70 @@ +From stable+bounces-213142-greg=kroah.com@vger.kernel.org Tue Feb 3 02:24:59 2026 +From: jetlan9@163.com +Date: Tue, 3 Feb 2026 01:21:43 +0000 +Subject: HID: uclogic: Correct devm device reference for hidinput input_dev name +To: stable@vger.kernel.org +Cc: Rahul Rameshbabu , syzbot+3a0ebe8a52b89c63739d@syzkaller.appspotmail.com, Maxime Ripard , Dmitry Torokhov , Benjamin Tissoires , Wenshan Lan +Message-ID: <20260203012144.4215-1-jetlan9@163.com> + +From: Rahul Rameshbabu + +[ Upstream commit dd613a4e45f8d35f49a63a2064e5308fa5619e29 ] + +Reference the HID device rather than the input device for the devm +allocation of the input_dev name. Referencing the input_dev would lead to a +use-after-free when the input_dev was unregistered and subsequently fires a +uevent that depends on the name. At the point of firing the uevent, the +name would be freed by devres management. + +Use devm_kasprintf to simplify the logic for allocating memory and +formatting the input_dev name string. + +Reported-by: syzbot+3a0ebe8a52b89c63739d@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-input/ZOZIZCND+L0P1wJc@penguin/T/ +Reported-by: Maxime Ripard +Closes: https://lore.kernel.org/linux-input/ZOZIZCND+L0P1wJc@penguin/T/#m443f3dce92520f74b6cf6ffa8653f9c92643d4ae +Fixes: cce2dbdf258e ("HID: uclogic: name the input nodes based on their tool") +Suggested-by: Maxime Ripard +Suggested-by: Dmitry Torokhov +Signed-off-by: Rahul Rameshbabu +Reviewed-by: Maxime Ripard +Link: https://lore.kernel.org/r/20230824061308.222021-2-sergeantsagara@protonmail.com +Signed-off-by: Benjamin Tissoires +[ Adjust context ] +Signed-off-by: Wenshan Lan +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-uclogic-core.c | 13 +++---------- + 1 file changed, 3 insertions(+), 10 deletions(-) + +--- a/drivers/hid/hid-uclogic-core.c ++++ b/drivers/hid/hid-uclogic-core.c +@@ -104,10 +104,8 @@ static int uclogic_input_configured(stru + { + struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); + struct uclogic_params *params = &drvdata->params; +- char *name; + const char *suffix = NULL; + struct hid_field *field; +- size_t len; + + /* no report associated (HID_QUIRK_MULTI_INPUT not set) */ + if (!hi->report) +@@ -145,14 +143,9 @@ static int uclogic_input_configured(stru + break; + } + +- if (suffix) { +- len = strlen(hdev->name) + 2 + strlen(suffix); +- name = devm_kzalloc(&hi->input->dev, len, GFP_KERNEL); +- if (name) { +- snprintf(name, len, "%s %s", hdev->name, suffix); +- hi->input->name = name; +- } +- } ++ if (suffix) ++ hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, ++ "%s %s", hdev->name, suffix); + + return 0; + } diff --git a/queue-5.15/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch b/queue-5.15/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch new file mode 100644 index 0000000000..633b200787 --- /dev/null +++ b/queue-5.15/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch @@ -0,0 +1,69 @@ +From stable+bounces-211906-greg=kroah.com@vger.kernel.org Wed Jan 28 01:56:51 2026 +From: Sasha Levin +Date: Tue, 27 Jan 2026 19:56:45 -0500 +Subject: iio: adc: exynos_adc: fix OF populate on driver rebind +To: stable@vger.kernel.org +Cc: Johan Hovold , Krzysztof Kozlowski , Jonathan Cameron , Sasha Levin +Message-ID: <20260128005645.2300956-1-sashal@kernel.org> + +From: Johan Hovold + +[ Upstream commit ea6b4feba85e996e840e0b661bc42793df6eb701 ] + +Since commit c6e126de43e7 ("of: Keep track of populated platform +devices") child devices will not be created by of_platform_populate() +if the devices had previously been deregistered individually so that the +OF_POPULATED flag is still set in the corresponding OF nodes. + +Switch to using of_platform_depopulate() instead of open coding so that +the child devices are created if the driver is rebound. + +Fixes: c6e126de43e7 ("of: Keep track of populated platform devices") +Cc: stable@vger.kernel.org # 3.16 +Signed-off-by: Johan Hovold +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Jonathan Cameron +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/exynos_adc.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +--- a/drivers/iio/adc/exynos_adc.c ++++ b/drivers/iio/adc/exynos_adc.c +@@ -721,14 +721,7 @@ static const struct iio_chan_spec exynos + ADC_CHANNEL(9, "adc9"), + }; + +-static int exynos_adc_remove_devices(struct device *dev, void *c) +-{ +- struct platform_device *pdev = to_platform_device(dev); +- +- platform_device_unregister(pdev); + +- return 0; +-} + + static int exynos_adc_ts_open(struct input_dev *dev) + { +@@ -929,8 +922,7 @@ static int exynos_adc_probe(struct platf + return 0; + + err_of_populate: +- device_for_each_child(&indio_dev->dev, NULL, +- exynos_adc_remove_devices); ++ of_platform_depopulate(&indio_dev->dev); + if (has_ts) { + input_unregister_device(info->input); + free_irq(info->tsirq, info); +@@ -959,8 +951,7 @@ static int exynos_adc_remove(struct plat + free_irq(info->tsirq, info); + input_unregister_device(info->input); + } +- device_for_each_child(&indio_dev->dev, NULL, +- exynos_adc_remove_devices); ++ of_platform_depopulate(&indio_dev->dev); + iio_device_unregister(indio_dev); + free_irq(info->irq, info); + if (info->data->exit_hw) diff --git a/queue-5.15/ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch b/queue-5.15/ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch new file mode 100644 index 0000000000..4eef2bc9b5 --- /dev/null +++ b/queue-5.15/ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch @@ -0,0 +1,230 @@ +From stable+bounces-210079-greg=kroah.com@vger.kernel.org Fri Jan 16 18:22:59 2026 +From: Pedro Demarchi Gomes +Date: Fri, 16 Jan 2026 14:19:14 -0300 +Subject: ksm: use range-walk function to jump over holes in scan_get_next_rmap_item +To: stable@vger.kernel.org +Cc: Zhi.Yang@windriver.com, Pedro Demarchi Gomes , David Hildenbrand , craftfever , Chengming Zhou , xu xin , Andrew Morton +Message-ID: <20260116171914.298018-2-pedrodemargomes@gmail.com> + +From: Pedro Demarchi Gomes + +[ Upstream commit f5548c318d6520d4fa3c5ed6003eeb710763cbc5 ] + +Currently, scan_get_next_rmap_item() walks every page address in a VMA to +locate mergeable pages. This becomes highly inefficient when scanning +large virtual memory areas that contain mostly unmapped regions, causing +ksmd to use large amount of cpu without deduplicating much pages. + +This patch replaces the per-address lookup with a range walk using +walk_page_range(). The range walker allows KSM to skip over entire +unmapped holes in a VMA, avoiding unnecessary lookups. This problem was +previously discussed in [1]. + +Consider the following test program which creates a 32 TiB mapping in the +virtual address space but only populates a single page: + +/* 32 TiB */ +const size_t size = 32ul * 1024 * 1024 * 1024 * 1024; + +int main() { + char *area = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_NORESERVE | MAP_PRIVATE | MAP_ANON, -1, 0); + + if (area == MAP_FAILED) { + perror("mmap() failed\n"); + return -1; + } + + /* Populate a single page such that we get an anon_vma. */ + *area = 0; + + /* Enable KSM. */ + madvise(area, size, MADV_MERGEABLE); + pause(); + return 0; +} + +$ ./ksm-sparse & +$ echo 1 > /sys/kernel/mm/ksm/run + +Without this patch ksmd uses 100% of the cpu for a long time (more then 1 +hour in my test machine) scanning all the 32 TiB virtual address space +that contain only one mapped page. This makes ksmd essentially deadlocked +not able to deduplicate anything of value. With this patch ksmd walks +only the one mapped page and skips the rest of the 32 TiB virtual address +space, making the scan fast using little cpu. + +Link: https://lkml.kernel.org/r/20251023035841.41406-1-pedrodemargomes@gmail.com +Link: https://lkml.kernel.org/r/20251022153059.22763-1-pedrodemargomes@gmail.com +Link: https://lore.kernel.org/linux-mm/423de7a3-1c62-4e72-8e79-19a6413e420c@redhat.com/ [1] +Fixes: 31dbd01f3143 ("ksm: Kernel SamePage Merging") +Signed-off-by: Pedro Demarchi Gomes +Co-developed-by: David Hildenbrand +Signed-off-by: David Hildenbrand +Reported-by: craftfever +Closes: https://lkml.kernel.org/r/020cf8de6e773bb78ba7614ef250129f11a63781@murena.io +Suggested-by: David Hildenbrand +Acked-by: David Hildenbrand +Cc: Chengming Zhou +Cc: xu xin +Cc: +Signed-off-by: Andrew Morton +[ change folio to page, replace pmdp_get_lockless with pmd_read_atomic and pmdp_get with + READ_ONCE(*pmdp) ] +Signed-off-by: Pedro Demarchi Gomes +Signed-off-by: Greg Kroah-Hartman +--- + mm/ksm.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 105 insertions(+), 10 deletions(-) + +--- a/mm/ksm.c ++++ b/mm/ksm.c +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + + #include + #include "internal.h" +@@ -2214,6 +2215,89 @@ static struct rmap_item *get_next_rmap_i + return rmap_item; + } + ++struct ksm_next_page_arg { ++ struct page *page; ++ unsigned long addr; ++}; ++ ++static int ksm_next_page_pmd_entry(pmd_t *pmdp, unsigned long addr, unsigned long end, ++ struct mm_walk *walk) ++{ ++ struct ksm_next_page_arg *private = walk->private; ++ struct vm_area_struct *vma = walk->vma; ++ pte_t *start_ptep = NULL, *ptep, pte; ++ struct mm_struct *mm = walk->mm; ++ struct page *page; ++ spinlock_t *ptl; ++ pmd_t pmd; ++ ++ if (ksm_test_exit(mm)) ++ return 0; ++ ++ cond_resched(); ++ ++ pmd = pmd_read_atomic(pmdp); ++ if (!pmd_present(pmd)) ++ return 0; ++ ++ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && pmd_leaf(pmd)) { ++ ptl = pmd_lock(mm, pmdp); ++ pmd = READ_ONCE(*pmdp); ++ ++ if (!pmd_present(pmd)) { ++ goto not_found_unlock; ++ } else if (pmd_leaf(pmd)) { ++ page = vm_normal_page_pmd(vma, addr, pmd); ++ if (!page) ++ goto not_found_unlock; ++ ++ if (is_zone_device_page(page) || !PageAnon(page)) ++ goto not_found_unlock; ++ ++ page += ((addr & (PMD_SIZE - 1)) >> PAGE_SHIFT); ++ goto found_unlock; ++ } ++ spin_unlock(ptl); ++ } ++ ++ start_ptep = pte_offset_map_lock(mm, pmdp, addr, &ptl); ++ if (!start_ptep) ++ return 0; ++ ++ for (ptep = start_ptep; addr < end; ptep++, addr += PAGE_SIZE) { ++ pte = ptep_get(ptep); ++ ++ if (!pte_present(pte)) ++ continue; ++ ++ page = vm_normal_page(vma, addr, pte); ++ if (!page) ++ continue; ++ ++ if (is_zone_device_page(page) || !PageAnon(page)) ++ continue; ++ goto found_unlock; ++ } ++ ++not_found_unlock: ++ spin_unlock(ptl); ++ if (start_ptep) ++ pte_unmap(start_ptep); ++ return 0; ++found_unlock: ++ get_page(page); ++ spin_unlock(ptl); ++ if (start_ptep) ++ pte_unmap(start_ptep); ++ private->page = page; ++ private->addr = addr; ++ return 1; ++} ++ ++static struct mm_walk_ops ksm_next_page_ops = { ++ .pmd_entry = ksm_next_page_pmd_entry, ++}; ++ + static struct rmap_item *scan_get_next_rmap_item(struct page **page) + { + struct mm_struct *mm; +@@ -2293,29 +2377,40 @@ next_mm: + ksm_scan.address = vma->vm_end; + + while (ksm_scan.address < vma->vm_end) { ++ struct ksm_next_page_arg ksm_next_page_arg; ++ struct page *tmp_page = NULL; ++ int found; ++ + if (ksm_test_exit(mm)) + break; +- *page = follow_page(vma, ksm_scan.address, FOLL_GET); +- if (IS_ERR_OR_NULL(*page)) { +- ksm_scan.address += PAGE_SIZE; +- cond_resched(); +- continue; ++ ++ found = walk_page_range_vma(vma, ksm_scan.address, ++ vma->vm_end, ++ &ksm_next_page_ops, ++ &ksm_next_page_arg); ++ ++ if (found > 0) { ++ tmp_page = ksm_next_page_arg.page; ++ ksm_scan.address = ksm_next_page_arg.addr; ++ } else { ++ VM_WARN_ON_ONCE(found < 0); ++ ksm_scan.address = vma->vm_end - PAGE_SIZE; + } +- if (PageAnon(*page)) { +- flush_anon_page(vma, *page, ksm_scan.address); +- flush_dcache_page(*page); ++ if (tmp_page) { ++ flush_anon_page(vma, tmp_page, ksm_scan.address); ++ flush_dcache_page(tmp_page); + rmap_item = get_next_rmap_item(slot, + ksm_scan.rmap_list, ksm_scan.address); + if (rmap_item) { + ksm_scan.rmap_list = + &rmap_item->rmap_list; + ksm_scan.address += PAGE_SIZE; ++ *page = tmp_page; + } else +- put_page(*page); ++ put_page(tmp_page); + mmap_read_unlock(mm); + return rmap_item; + } +- put_page(*page); + ksm_scan.address += PAGE_SIZE; + cond_resched(); + } diff --git a/queue-5.15/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-under-concurrency.patch b/queue-5.15/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-under-concurrency.patch new file mode 100644 index 0000000000..bf24407c45 --- /dev/null +++ b/queue-5.15/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-under-concurrency.patch @@ -0,0 +1,101 @@ +From stable+bounces-211192-greg=kroah.com@vger.kernel.org Thu Jan 22 04:56:32 2026 +From: Rajani Kantha <681739313@139.com> +Date: Thu, 22 Jan 2026 11:42:12 +0800 +Subject: ksmbd: fix use-after-free in ksmbd_tree_connect_put under concurrency +To: gregkh@linuxfoundation.org, stable@vger.kernel.org, linkinjeon@kernel.org +Cc: patches@lists.linux.dev, linux-kernel@vger.kernel.org, senozhatsky@chromium.org, sfrench@samba.org, hyc.lee@gmail.com, linux-cifs@vger.kernel.org, pioooooooooip@gmail.com, liuzhitong1993@gmail.com, stfrench@microsoft.com +Message-ID: <20260122034212.3111671-1-681739313@139.com> + +From: Namjae Jeon + +[ Upstream commit b39a1833cc4a2755b02603eec3a71a85e9dff926 ] + +Under high concurrency, A tree-connection object (tcon) is freed on +a disconnect path while another path still holds a reference and later +executes *_put()/write on it. + +Reported-by: Qianchang Zhao +Reported-by: Zhitong Liu +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Rajani Kantha <681739313@139.com> +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/mgmt/tree_connect.c | 18 ++++-------------- + fs/ksmbd/mgmt/tree_connect.h | 1 - + fs/ksmbd/smb2pdu.c | 3 --- + 3 files changed, 4 insertions(+), 18 deletions(-) + +--- a/fs/ksmbd/mgmt/tree_connect.c ++++ b/fs/ksmbd/mgmt/tree_connect.c +@@ -76,7 +76,6 @@ ksmbd_tree_conn_connect(struct ksmbd_con + tree_conn->t_state = TREE_NEW; + status.tree_conn = tree_conn; + atomic_set(&tree_conn->refcount, 1); +- init_waitqueue_head(&tree_conn->refcount_q); + + ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn, + GFP_KERNEL)); +@@ -98,14 +97,8 @@ out_error: + + void ksmbd_tree_connect_put(struct ksmbd_tree_connect *tcon) + { +- /* +- * Checking waitqueue to releasing tree connect on +- * tree disconnect. waitqueue_active is safe because it +- * uses atomic operation for condition. +- */ +- if (!atomic_dec_return(&tcon->refcount) && +- waitqueue_active(&tcon->refcount_q)) +- wake_up(&tcon->refcount_q); ++ if (atomic_dec_and_test(&tcon->refcount)) ++ kfree(tcon); + } + + int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess, +@@ -117,14 +110,11 @@ int ksmbd_tree_conn_disconnect(struct ks + xa_erase(&sess->tree_conns, tree_conn->id); + write_unlock(&sess->tree_conns_lock); + +- if (!atomic_dec_and_test(&tree_conn->refcount)) +- wait_event(tree_conn->refcount_q, +- atomic_read(&tree_conn->refcount) == 0); +- + ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id); + ksmbd_release_tree_conn_id(sess, tree_conn->id); + ksmbd_share_config_put(tree_conn->share_conf); +- kfree(tree_conn); ++ if (atomic_dec_and_test(&tree_conn->refcount)) ++ kfree(tree_conn); + return ret; + } + +--- a/fs/ksmbd/mgmt/tree_connect.h ++++ b/fs/ksmbd/mgmt/tree_connect.h +@@ -32,7 +32,6 @@ struct ksmbd_tree_connect { + int maximal_access; + bool posix_extensions; + atomic_t refcount; +- wait_queue_head_t refcount_q; + unsigned int t_state; + }; + +--- a/fs/ksmbd/smb2pdu.c ++++ b/fs/ksmbd/smb2pdu.c +@@ -2169,7 +2169,6 @@ int smb2_tree_disconnect(struct ksmbd_wo + goto err_out; + } + +- WARN_ON_ONCE(atomic_dec_and_test(&tcon->refcount)); + tcon->t_state = TREE_DISCONNECTED; + write_unlock(&sess->tree_conns_lock); + +@@ -2179,8 +2178,6 @@ int smb2_tree_disconnect(struct ksmbd_wo + goto err_out; + } + +- work->tcon = NULL; +- + rsp->StructureSize = cpu_to_le16(4); + err = ksmbd_iov_pin_rsp(work, rsp, + sizeof(struct smb2_tree_disconnect_rsp)); diff --git a/queue-5.15/ksmbd-smbd-fix-dma_unmap_sg-nents.patch b/queue-5.15/ksmbd-smbd-fix-dma_unmap_sg-nents.patch new file mode 100644 index 0000000000..81507862d1 --- /dev/null +++ b/queue-5.15/ksmbd-smbd-fix-dma_unmap_sg-nents.patch @@ -0,0 +1,72 @@ +From stable+bounces-212705-greg=kroah.com@vger.kernel.org Wed Jan 28 23:43:18 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 17:40:22 -0500 +Subject: ksmbd: smbd: fix dma_unmap_sg() nents +To: stable@vger.kernel.org +Cc: Thomas Fourier , Namjae Jeon , Steve French , Sasha Levin +Message-ID: <20260128224022.2810098-1-sashal@kernel.org> + +From: Thomas Fourier + +[ Upstream commit 98e3e2b561bc88f4dd218d1c05890672874692f6 ] + +The dma_unmap_sg() functions should be called with the same nents as the +dma_map_sg(), not the value the map function returned. + +Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers") +Cc: +Signed-off-by: Thomas Fourier +Acked-by: Namjae Jeon +Signed-off-by: Steve French +[ Context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/ksmbd/transport_rdma.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +--- a/fs/ksmbd/transport_rdma.c ++++ b/fs/ksmbd/transport_rdma.c +@@ -1086,14 +1086,12 @@ static int get_sg_list(void *buf, int si + + static int get_mapped_sg_list(struct ib_device *device, void *buf, int size, + struct scatterlist *sg_list, int nentries, +- enum dma_data_direction dir) ++ enum dma_data_direction dir, int *npages) + { +- int npages; +- +- npages = get_sg_list(buf, size, sg_list, nentries); +- if (npages < 0) ++ *npages = get_sg_list(buf, size, sg_list, nentries); ++ if (*npages < 0) + return -EINVAL; +- return ib_dma_map_sg(device, sg_list, npages, dir); ++ return ib_dma_map_sg(device, sg_list, *npages, dir); + } + + static int post_sendmsg(struct smb_direct_transport *t, +@@ -1162,12 +1160,13 @@ static int smb_direct_post_send_data(str + for (i = 0; i < niov; i++) { + struct ib_sge *sge; + int sg_cnt; ++ int npages; + + sg_init_table(sg, SMB_DIRECT_MAX_SEND_SGES - 1); + sg_cnt = get_mapped_sg_list(t->cm_id->device, + iov[i].iov_base, iov[i].iov_len, + sg, SMB_DIRECT_MAX_SEND_SGES - 1, +- DMA_TO_DEVICE); ++ DMA_TO_DEVICE, &npages); + if (sg_cnt <= 0) { + pr_err("failed to map buffer\n"); + ret = -ENOMEM; +@@ -1175,7 +1174,7 @@ static int smb_direct_post_send_data(str + } else if (sg_cnt + msg->num_sge > SMB_DIRECT_MAX_SEND_SGES) { + pr_err("buffer not fitted into sges\n"); + ret = -E2BIG; +- ib_dma_unmap_sg(t->cm_id->device, sg, sg_cnt, ++ ib_dma_unmap_sg(t->cm_id->device, sg, npages, + DMA_TO_DEVICE); + goto err; + } diff --git a/queue-5.15/mei-trace-treat-reg-parameter-as-string.patch b/queue-5.15/mei-trace-treat-reg-parameter-as-string.patch new file mode 100644 index 0000000000..cb0a4ec42a --- /dev/null +++ b/queue-5.15/mei-trace-treat-reg-parameter-as-string.patch @@ -0,0 +1,104 @@ +From stable+bounces-212704-greg=kroah.com@vger.kernel.org Wed Jan 28 23:43:15 2026 +From: Sasha Levin +Date: Wed, 28 Jan 2026 17:40:18 -0500 +Subject: mei: trace: treat reg parameter as string +To: stable@vger.kernel.org +Cc: Alexander Usyskin , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20260128224019.2809980-1-sashal@kernel.org> + +From: Alexander Usyskin + +[ Upstream commit 06d5a7afe1d0b47102936d8fba568572c2b4b941 ] + +The commit +afd2627f727b ("tracing: Check "%s" dereference via the field and not the TP_printk format") +forbids to emit event with a plain char* without a wrapper. + +The reg parameter always passed as static string and wrapper +is not strictly required, contrary to dev parameter. +Use the string wrapper anyway to check sanity of the reg parameters, +store it value independently and prevent internal kernel data leaks. + +Since some code refactoring has taken place, explicit backporting may +be needed for kernels older than 6.10. + +Cc: stable@vger.kernel.org # v6.11+ +Fixes: a0a927d06d79 ("mei: me: add io register tracing") +Signed-off-by: Alexander Usyskin +Link: https://patch.msgid.link/20260111145125.1754912-1-alexander.usyskin@intel.com +Signed-off-by: Greg Kroah-Hartman +[ adapted __assign_str() calls to use two arguments ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/misc/mei/mei-trace.h | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/drivers/misc/mei/mei-trace.h ++++ b/drivers/misc/mei/mei-trace.h +@@ -21,18 +21,18 @@ TRACE_EVENT(mei_reg_read, + TP_ARGS(dev, reg, offs, val), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) +- __field(const char *, reg) ++ __string(reg, reg) + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)); +- __entry->reg = reg; ++ __assign_str(reg, reg); + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] read %s:[%#x] = %#x", +- __get_str(dev), __entry->reg, __entry->offs, __entry->val) ++ __get_str(dev), __get_str(reg), __entry->offs, __entry->val) + ); + + TRACE_EVENT(mei_reg_write, +@@ -40,18 +40,18 @@ TRACE_EVENT(mei_reg_write, + TP_ARGS(dev, reg, offs, val), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) +- __field(const char *, reg) ++ __string(reg, reg) + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)); +- __entry->reg = reg; ++ __assign_str(reg, reg); + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] write %s[%#x] = %#x", +- __get_str(dev), __entry->reg, __entry->offs, __entry->val) ++ __get_str(dev), __get_str(reg), __entry->offs, __entry->val) + ); + + TRACE_EVENT(mei_pci_cfg_read, +@@ -59,18 +59,18 @@ TRACE_EVENT(mei_pci_cfg_read, + TP_ARGS(dev, reg, offs, val), + TP_STRUCT__entry( + __string(dev, dev_name(dev)) +- __field(const char *, reg) ++ __string(reg, reg) + __field(u32, offs) + __field(u32, val) + ), + TP_fast_assign( + __assign_str(dev, dev_name(dev)); +- __entry->reg = reg; ++ __assign_str(reg, reg); + __entry->offs = offs; + __entry->val = val; + ), + TP_printk("[%s] pci cfg read %s:[%#x] = %#x", +- __get_str(dev), __entry->reg, __entry->offs, __entry->val) ++ __get_str(dev), __get_str(reg), __entry->offs, __entry->val) + ); + + #endif /* _MEI_TRACE_H_ */ diff --git a/queue-5.15/mm-pagewalk-add-walk_page_range_vma.patch b/queue-5.15/mm-pagewalk-add-walk_page_range_vma.patch new file mode 100644 index 0000000000..996609ac08 --- /dev/null +++ b/queue-5.15/mm-pagewalk-add-walk_page_range_vma.patch @@ -0,0 +1,77 @@ +From stable+bounces-210078-greg=kroah.com@vger.kernel.org Fri Jan 16 18:22:38 2026 +From: Pedro Demarchi Gomes +Date: Fri, 16 Jan 2026 14:19:13 -0300 +Subject: mm/pagewalk: add walk_page_range_vma() +To: stable@vger.kernel.org +Cc: Zhi.Yang@windriver.com, David Hildenbrand , Andrea Arcangeli , Hugh Dickins , Jason Gunthorpe , John Hubbard , Matthew Wilcox , Peter Xu , Shuah Khan , Vlastimil Babka , Andrew Morton , Pedro Demarchi Gomes +Message-ID: <20260116171914.298018-1-pedrodemargomes@gmail.com> + +From: David Hildenbrand + +[ Upstream commit e07cda5f232fac4de0925d8a4c92e51e41fa2f6e ] + +Let's add walk_page_range_vma(), which is similar to walk_page_vma(), +however, is only interested in a subset of the VMA range. + +To be used in KSM code to stop using follow_page() next. + +Link: https://lkml.kernel.org/r/20221021101141.84170-8-david@redhat.com +Signed-off-by: David Hildenbrand +Cc: Andrea Arcangeli +Cc: Hugh Dickins +Cc: Jason Gunthorpe +Cc: John Hubbard +Cc: Matthew Wilcox (Oracle) +Cc: Peter Xu +Cc: Shuah Khan +Cc: Vlastimil Babka +Signed-off-by: Andrew Morton +Stable-dep-of: f5548c318d6 ("ksm: use range-walk function to jump over holes in scan_get_next_rmap_item") +Signed-off-by: Pedro Demarchi Gomes +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/pagewalk.h | 3 +++ + mm/pagewalk.c | 20 ++++++++++++++++++++ + 2 files changed, 23 insertions(+) + +--- a/include/linux/pagewalk.h ++++ b/include/linux/pagewalk.h +@@ -99,6 +99,9 @@ int walk_page_range_novma(struct mm_stru + unsigned long end, const struct mm_walk_ops *ops, + pgd_t *pgd, + void *private); ++int walk_page_range_vma(struct vm_area_struct *vma, unsigned long start, ++ unsigned long end, const struct mm_walk_ops *ops, ++ void *private); + int walk_page_vma(struct vm_area_struct *vma, const struct mm_walk_ops *ops, + void *private); + int walk_page_mapping(struct address_space *mapping, pgoff_t first_index, +--- a/mm/pagewalk.c ++++ b/mm/pagewalk.c +@@ -509,6 +509,26 @@ int walk_page_range_novma(struct mm_stru + return walk_pgd_range(start, end, &walk); + } + ++int walk_page_range_vma(struct vm_area_struct *vma, unsigned long start, ++ unsigned long end, const struct mm_walk_ops *ops, ++ void *private) ++{ ++ struct mm_walk walk = { ++ .ops = ops, ++ .mm = vma->vm_mm, ++ .vma = vma, ++ .private = private, ++ }; ++ ++ if (start >= end || !walk.mm) ++ return -EINVAL; ++ if (start < vma->vm_start || end > vma->vm_end) ++ return -EINVAL; ++ ++ mmap_assert_locked(walk.mm); ++ return __walk_page_range(start, end, &walk); ++} ++ + int walk_page_vma(struct vm_area_struct *vma, const struct mm_walk_ops *ops, + void *private) + { diff --git a/queue-5.15/net-add-locking-to-protect-skb-dev-access-in-ip_output.patch b/queue-5.15/net-add-locking-to-protect-skb-dev-access-in-ip_output.patch new file mode 100644 index 0000000000..d61543c179 --- /dev/null +++ b/queue-5.15/net-add-locking-to-protect-skb-dev-access-in-ip_output.patch @@ -0,0 +1,116 @@ +From 1dbf1d590d10a6d1978e8184f8dfe20af22d680a Mon Sep 17 00:00:00 2001 +From: Sharath Chandra Vurukala +Date: Wed, 30 Jul 2025 16:21:18 +0530 +Subject: net: Add locking to protect skb->dev access in ip_output + +From: Sharath Chandra Vurukala + +commit 1dbf1d590d10a6d1978e8184f8dfe20af22d680a upstream. + +In ip_output() skb->dev is updated from the skb_dst(skb)->dev +this can become invalid when the interface is unregistered and freed, + +Introduced new skb_dst_dev_rcu() function to be used instead of +skb_dst_dev() within rcu_locks in ip_output.This will ensure that +all the skb's associated with the dev being deregistered will +be transnmitted out first, before freeing the dev. + +Given that ip_output() is called within an rcu_read_lock() +critical section or from a bottom-half context, it is safe to introduce +an RCU read-side critical section within it. + +Multiple panic call stacks were observed when UL traffic was run +in concurrency with device deregistration from different functions, +pasting one sample for reference. + +[496733.627565][T13385] Call trace: +[496733.627570][T13385] bpf_prog_ce7c9180c3b128ea_cgroupskb_egres+0x24c/0x7f0 +[496733.627581][T13385] __cgroup_bpf_run_filter_skb+0x128/0x498 +[496733.627595][T13385] ip_finish_output+0xa4/0xf4 +[496733.627605][T13385] ip_output+0x100/0x1a0 +[496733.627613][T13385] ip_send_skb+0x68/0x100 +[496733.627618][T13385] udp_send_skb+0x1c4/0x384 +[496733.627625][T13385] udp_sendmsg+0x7b0/0x898 +[496733.627631][T13385] inet_sendmsg+0x5c/0x7c +[496733.627639][T13385] __sys_sendto+0x174/0x1e4 +[496733.627647][T13385] __arm64_sys_sendto+0x28/0x3c +[496733.627653][T13385] invoke_syscall+0x58/0x11c +[496733.627662][T13385] el0_svc_common+0x88/0xf4 +[496733.627669][T13385] do_el0_svc+0x2c/0xb0 +[496733.627676][T13385] el0_svc+0x2c/0xa4 +[496733.627683][T13385] el0t_64_sync_handler+0x68/0xb4 +[496733.627689][T13385] el0t_64_sync+0x1a4/0x1a8 + +Changes in v3: +- Replaced WARN_ON() with WARN_ON_ONCE(), as suggested by Willem de Bruijn. +- Dropped legacy lines mistakenly pulled in from an outdated branch. + +Changes in v2: +- Addressed review comments from Eric Dumazet +- Used READ_ONCE() to prevent potential load/store tearing +- Added skb_dst_dev_rcu() and used along with rcu_read_lock() in ip_output + +Signed-off-by: Sharath Chandra Vurukala +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20250730105118.GA26100@hu-sharathv-hyd.qualcomm.com +Signed-off-by: Jakub Kicinski +[ Keerthana: Backported the patch to v5.15-v6.1 ] +Signed-off-by: Keerthana K +Signed-off-by: Greg Kroah-Hartman +--- + include/net/dst.h | 12 ++++++++++++ + net/ipv4/ip_output.c | 16 +++++++++++----- + 2 files changed, 23 insertions(+), 5 deletions(-) + +--- a/include/net/dst.h ++++ b/include/net/dst.h +@@ -554,6 +554,18 @@ static inline void skb_dst_update_pmtu_n + dst->ops->update_pmtu(dst, NULL, skb, mtu, false); + } + ++static inline struct net_device *dst_dev_rcu(const struct dst_entry *dst) ++{ ++ /* In the future, use rcu_dereference(dst->dev) */ ++ WARN_ON_ONCE(!rcu_read_lock_held()); ++ return READ_ONCE(dst->dev); ++} ++ ++static inline struct net_device *skb_dst_dev_rcu(const struct sk_buff *skb) ++{ ++ return dst_dev_rcu(skb_dst(skb)); ++} ++ + struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie); + void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk, + struct sk_buff *skb, u32 mtu, bool confirm_neigh); +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -420,17 +420,23 @@ int ip_mc_output(struct net *net, struct + + int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb) + { +- struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev; ++ struct net_device *dev, *indev = skb->dev; ++ int ret_val; ++ ++ rcu_read_lock(); ++ dev = skb_dst_dev_rcu(skb); + + IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len); + + skb->dev = dev; + skb->protocol = htons(ETH_P_IP); + +- return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, +- net, sk, skb, indev, dev, +- ip_finish_output, +- !(IPCB(skb)->flags & IPSKB_REROUTED)); ++ ret_val = NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, ++ net, sk, skb, indev, dev, ++ ip_finish_output, ++ !(IPCB(skb)->flags & IPSKB_REROUTED)); ++ rcu_read_unlock(); ++ return ret_val; + } + EXPORT_SYMBOL(ip_output); + diff --git a/queue-5.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-configuring-est.patch b/queue-5.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-configuring-est.patch new file mode 100644 index 0000000000..6a37f35309 --- /dev/null +++ b/queue-5.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-configuring-est.patch @@ -0,0 +1,62 @@ +From stable+bounces-212844-greg=kroah.com@vger.kernel.org Fri Jan 30 07:55:07 2026 +From: Rahul Sharma +Date: Fri, 30 Jan 2026 14:54:23 +0800 +Subject: net: stmmac: make sure that ptp_rate is not 0 before configuring EST +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, "Alexis Lothoré" , "Maxime Chevallier" , "Jakub Kicinski" , "Rahul Sharma" +Message-ID: <20260130065423.3362339-1-black.hawk@163.com> + +From: Alexis Lothoré + +[ Upstream commit cbefe2ffa7784525ec5d008ba87c7add19ec631a ] + +If the ptp_rate recorded earlier in the driver happens to be 0, this +bogus value will propagate up to EST configuration, where it will +trigger a division by 0. + +Prevent this division by 0 by adding the corresponding check and error +code. + +Suggested-by: Maxime Chevallier +Signed-off-by: Alexis Lothoré +Fixes: 8572aec3d0dc ("net: stmmac: Add basic EST support for XGMAC") +Link: https://patch.msgid.link/20250529-stmmac_tstamp_div-v4-2-d73340a794d5@bootlin.com +Signed-off-by: Jakub Kicinski +[ The context change is due to the commit c3f3b97238f6 +("net: stmmac: Refactor EST implementation") +and the proper adoption is done. ] +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 5 +++++ + drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 5 +++++ + 2 files changed, 10 insertions(+) + +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c +@@ -597,6 +597,11 @@ int dwmac5_est_configure(void __iomem *i + int i, ret = 0x0; + u32 ctrl; + ++ if (!ptp_rate) { ++ pr_warn("Dwmac5: Invalid PTP rate"); ++ return -EINVAL; ++ } ++ + ret |= dwmac5_est_write(ioaddr, BTR_LOW, cfg->btr[0], false); + ret |= dwmac5_est_write(ioaddr, BTR_HIGH, cfg->btr[1], false); + ret |= dwmac5_est_write(ioaddr, TER, cfg->ter, false); +--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +@@ -1494,6 +1494,11 @@ static int dwxgmac3_est_configure(void _ + int i, ret = 0x0; + u32 ctrl; + ++ if (!ptp_rate) { ++ pr_warn("Dwxgmac2: Invalid PTP rate"); ++ return -EINVAL; ++ } ++ + ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_LOW, cfg->btr[0], false); + ret |= dwxgmac3_est_write(ioaddr, XGMAC_BTR_HIGH, cfg->btr[1], false); + ret |= dwxgmac3_est_write(ioaddr, XGMAC_TER, cfg->ter, false); diff --git a/queue-5.15/nfsd-fix-race-between-nfsd-registration-and-exports_proc.patch b/queue-5.15/nfsd-fix-race-between-nfsd-registration-and-exports_proc.patch new file mode 100644 index 0000000000..316b7e8ce5 --- /dev/null +++ b/queue-5.15/nfsd-fix-race-between-nfsd-registration-and-exports_proc.patch @@ -0,0 +1,169 @@ +From stable+bounces-212725-greg=kroah.com@vger.kernel.org Thu Jan 29 03:24:25 2026 +From: Rahul Sharma +Date: Thu, 29 Jan 2026 10:23:04 +0800 +Subject: NFSD: fix race between nfsd registration and exports_proc +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, Maninder Singh , Shubham Rana , Jeff Layton , Chuck Lever , Rahul Sharma +Message-ID: <20260129022304.1232425-1-black.hawk@163.com> + +From: Maninder Singh + +[ Upstream commit f7fb730cac9aafda8b9813b55d04e28a9664d17c ] + +As of now nfsd calls create_proc_exports_entry() at start of init_nfsd +and cleanup by remove_proc_entry() at last of exit_nfsd. + +Which causes kernel OOPs if there is race between below 2 operations: +(i) exportfs -r +(ii) mount -t nfsd none /proc/fs/nfsd + +for 5.4 kernel ARM64: + +CPU 1: +el1_irq+0xbc/0x180 +arch_counter_get_cntvct+0x14/0x18 +running_clock+0xc/0x18 +preempt_count_add+0x88/0x110 +prep_new_page+0xb0/0x220 +get_page_from_freelist+0x2d8/0x1778 +__alloc_pages_nodemask+0x15c/0xef0 +__vmalloc_node_range+0x28c/0x478 +__vmalloc_node_flags_caller+0x8c/0xb0 +kvmalloc_node+0x88/0xe0 +nfsd_init_net+0x6c/0x108 [nfsd] +ops_init+0x44/0x170 +register_pernet_operations+0x114/0x270 +register_pernet_subsys+0x34/0x50 +init_nfsd+0xa8/0x718 [nfsd] +do_one_initcall+0x54/0x2e0 + +CPU 2 : +Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 + +PC is at : exports_net_open+0x50/0x68 [nfsd] + +Call trace: +exports_net_open+0x50/0x68 [nfsd] +exports_proc_open+0x2c/0x38 [nfsd] +proc_reg_open+0xb8/0x198 +do_dentry_open+0x1c4/0x418 +vfs_open+0x38/0x48 +path_openat+0x28c/0xf18 +do_filp_open+0x70/0xe8 +do_sys_open+0x154/0x248 + +Sometimes it crashes at exports_net_open() and sometimes cache_seq_next_rcu(). + +and same is happening on latest 6.14 kernel as well: + +[ 0.000000] Linux version 6.14.0-rc5-next-20250304-dirty +... +[ 285.455918] Unable to handle kernel paging request at virtual address 00001f4800001f48 +... +[ 285.464902] pc : cache_seq_next_rcu+0x78/0xa4 +... +[ 285.469695] Call trace: +[ 285.470083] cache_seq_next_rcu+0x78/0xa4 (P) +[ 285.470488] seq_read+0xe0/0x11c +[ 285.470675] proc_reg_read+0x9c/0xf0 +[ 285.470874] vfs_read+0xc4/0x2fc +[ 285.471057] ksys_read+0x6c/0xf4 +[ 285.471231] __arm64_sys_read+0x1c/0x28 +[ 285.471428] invoke_syscall+0x44/0x100 +[ 285.471633] el0_svc_common.constprop.0+0x40/0xe0 +[ 285.471870] do_el0_svc_compat+0x1c/0x34 +[ 285.472073] el0_svc_compat+0x2c/0x80 +[ 285.472265] el0t_32_sync_handler+0x90/0x140 +[ 285.472473] el0t_32_sync+0x19c/0x1a0 +[ 285.472887] Code: f9400885 93407c23 937d7c27 11000421 (f86378a3) +[ 285.473422] ---[ end trace 0000000000000000 ]--- + +It reproduced simply with below script: +while [ 1 ] +do +/exportfs -r +done & + +while [ 1 ] +do +insmod /nfsd.ko +mount -t nfsd none /proc/fs/nfsd +umount /proc/fs/nfsd +rmmod nfsd +done & + +So exporting interfaces to user space shall be done at last and +cleanup at first place. + +With change there is no Kernel OOPs. + +Co-developed-by: Shubham Rana +Signed-off-by: Shubham Rana +Signed-off-by: Maninder Singh +Reviewed-by: Jeff Layton +Cc: stable@vger.kernel.org +Signed-off-by: Chuck Lever +[ The context change is due to the commit bd9d6a3efa97 +("NFSD: add rpc_status netlink support") in v6.7 +and the proper adoption is done. ] +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfsctl.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -1511,12 +1511,9 @@ static int __init init_nfsd(void) + if (retval) + goto out_free_pnfs; + nfsd_lockd_init(); /* lockd->nfsd callbacks */ +- retval = create_proc_exports_entry(); +- if (retval) +- goto out_free_lockd; + retval = register_pernet_subsys(&nfsd_net_ops); + if (retval < 0) +- goto out_free_exports; ++ goto out_free_lockd; + retval = register_cld_notifier(); + if (retval) + goto out_free_subsys; +@@ -1525,17 +1522,19 @@ static int __init init_nfsd(void) + goto out_free_cld; + retval = register_filesystem(&nfsd_fs_type); + if (retval) ++ goto out_free_nfsd4; ++ retval = create_proc_exports_entry(); ++ if (retval) + goto out_free_all; + return 0; + out_free_all: ++ unregister_filesystem(&nfsd_fs_type); ++out_free_nfsd4: + nfsd4_destroy_laundry_wq(); + out_free_cld: + unregister_cld_notifier(); + out_free_subsys: + unregister_pernet_subsys(&nfsd_net_ops); +-out_free_exports: +- remove_proc_entry("fs/nfs/exports", NULL); +- remove_proc_entry("fs/nfs", NULL); + out_free_lockd: + nfsd_lockd_shutdown(); + nfsd_drc_slab_free(); +@@ -1548,13 +1547,13 @@ out_free_slabs: + + static void __exit exit_nfsd(void) + { ++ remove_proc_entry("fs/nfs/exports", NULL); ++ remove_proc_entry("fs/nfs", NULL); + unregister_filesystem(&nfsd_fs_type); + nfsd4_destroy_laundry_wq(); + unregister_cld_notifier(); + unregister_pernet_subsys(&nfsd_net_ops); + nfsd_drc_slab_free(); +- remove_proc_entry("fs/nfs/exports", NULL); +- remove_proc_entry("fs/nfs", NULL); + nfsd_lockd_shutdown(); + nfsd4_free_slabs(); + nfsd4_exit_pnfs(); diff --git a/queue-5.15/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch b/queue-5.15/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch new file mode 100644 index 0000000000..6439759307 --- /dev/null +++ b/queue-5.15/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch @@ -0,0 +1,47 @@ +From stable+bounces-210666-greg=kroah.com@vger.kernel.org Wed Jan 21 04:02:48 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 22:02:36 -0500 +Subject: nvme-fc: rename free_ctrl callback to match name pattern +To: stable@vger.kernel.org +Cc: Daniel Wagner , Christoph Hellwig , Sagi Grimberg , Hannes Reinecke , Keith Busch , Sasha Levin +Message-ID: <20260121030238.1163180-1-sashal@kernel.org> + +From: Daniel Wagner + +[ Upstream commit 205fb5fa6fde1b5b426015eb1ff69f2ff25ef5bb ] + +Rename nvme_fc_nvme_ctrl_freed to nvme_fc_free_ctrl to match the name +pattern for the callback. + +Reviewed-by: Christoph Hellwig +Reviewed-by: Sagi Grimberg +Reviewed-by: Hannes Reinecke +Signed-off-by: Daniel Wagner +Signed-off-by: Keith Busch +Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/fc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -2410,7 +2410,7 @@ nvme_fc_ctrl_get(struct nvme_fc_ctrl *ct + * controller. Called after last nvme_put_ctrl() call + */ + static void +-nvme_fc_nvme_ctrl_freed(struct nvme_ctrl *nctrl) ++nvme_fc_free_ctrl(struct nvme_ctrl *nctrl) + { + struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl); + +@@ -3361,7 +3361,7 @@ static const struct nvme_ctrl_ops nvme_f + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, +- .free_ctrl = nvme_fc_nvme_ctrl_freed, ++ .free_ctrl = nvme_fc_free_ctrl, + .submit_async_event = nvme_fc_submit_async_event, + .delete_ctrl = nvme_fc_delete_ctrl, + .get_address = nvmf_get_address, diff --git a/queue-5.15/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch b/queue-5.15/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch new file mode 100644 index 0000000000..e3ecefa9f8 --- /dev/null +++ b/queue-5.15/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch @@ -0,0 +1,58 @@ +From stable+bounces-210668-greg=kroah.com@vger.kernel.org Wed Jan 21 04:02:53 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 22:02:38 -0500 +Subject: nvme: fix PCIe subsystem reset controller state transition +To: stable@vger.kernel.org +Cc: Nilay Shroff , Daniel Wagner , Keith Busch , Sasha Levin +Message-ID: <20260121030238.1163180-3-sashal@kernel.org> + +From: Nilay Shroff + +[ Upstream commit 0edb475ac0a7d153318a24d4dca175a270a5cc4f ] + +The commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING +state”) disallows controller state transitions directly from RESETTING +to LIVE. However, the NVMe PCIe subsystem reset path relies on this +transition to recover the controller on PowerPC (PPC) systems. + +On PPC systems, issuing a subsystem reset causes a temporary loss of +communication with the NVMe adapter. A subsequent PCIe MMIO read then +triggers EEH recovery, which restores the PCIe link and brings the +controller back online. For EEH recovery to proceed correctly, the +controller must transition back to the LIVE state. + +Due to the changes introduced by commit d2fe192348f9 (“nvme: only allow +entering LIVE from CONNECTING state”), the controller can no longer +transition directly from RESETTING to LIVE. As a result, EEH recovery +exits prematurely, leaving the controller stuck in the RESETTING state. + +Fix this by explicitly transitioning the controller state from RESETTING +to CONNECTING and then to LIVE. This satisfies the updated state +transition rules and allows the controller to be successfully recovered +on PPC systems following a PCIe subsystem reset. + +Cc: stable@vger.kernel.org +Fixes: d2fe192348f9 ("nvme: only allow entering LIVE from CONNECTING state") +Reviewed-by: Daniel Wagner +Signed-off-by: Nilay Shroff +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/pci.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1144,7 +1144,10 @@ static int nvme_pci_subsystem_reset(stru + } + + writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR); +- nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE); ++ ++ if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) || ++ !nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE)) ++ goto unlock; + + /* + * Read controller status to flush the previous write and trigger a diff --git a/queue-5.15/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch b/queue-5.15/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch new file mode 100644 index 0000000000..c32b39465f --- /dev/null +++ b/queue-5.15/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch @@ -0,0 +1,205 @@ +From stable+bounces-210667-greg=kroah.com@vger.kernel.org Wed Jan 21 04:02:48 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 22:02:37 -0500 +Subject: nvme-pci: do not directly handle subsys reset fallout +To: stable@vger.kernel.org +Cc: Keith Busch , Nilay Shroff , Christoph Hellwig , Sasha Levin +Message-ID: <20260121030238.1163180-2-sashal@kernel.org> + +From: Keith Busch + +[ Upstream commit 210b1f6576e8b367907e7ff51ef425062e1468e4 ] + +Scheduling reset_work after a nvme subsystem reset is expected to fail +on pcie, but this also prevents potential handling the platform's pcie +services may provide that might successfully recovering the link without +re-enumeration. Such examples include AER, DPC, and power's EEH. + +Provide a pci specific operation that safely initiates a subsystem +reset, and instead of scheduling reset work, read back the status +register to trigger a pcie read error. + +Since this only affects pci, the other fabrics drivers subscribe to a +generic nvmf subsystem reset that is exactly the same as before. The +loop fabric doesn't use it because nvmet doesn't support setting that +property anyway. + +And since we're using the magic NSSR value in two places now, provide a +symbolic define for it. + +Reported-by: Nilay Shroff +Reviewed-by: Christoph Hellwig +Signed-off-by: Keith Busch +Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/fabrics.c | 15 +++++++++++++++ + drivers/nvme/host/fabrics.h | 1 + + drivers/nvme/host/fc.c | 1 + + drivers/nvme/host/nvme.h | 14 +++----------- + drivers/nvme/host/pci.c | 36 ++++++++++++++++++++++++++++++++++++ + drivers/nvme/host/rdma.c | 1 + + drivers/nvme/host/tcp.c | 1 + + include/linux/nvme.h | 3 +++ + 8 files changed, 61 insertions(+), 11 deletions(-) + +--- a/drivers/nvme/host/fabrics.c ++++ b/drivers/nvme/host/fabrics.c +@@ -254,6 +254,21 @@ int nvmf_reg_write32(struct nvme_ctrl *c + } + EXPORT_SYMBOL_GPL(nvmf_reg_write32); + ++int nvmf_subsystem_reset(struct nvme_ctrl *ctrl) ++{ ++ int ret; ++ ++ if (!nvme_wait_reset(ctrl)) ++ return -EBUSY; ++ ++ ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, NVME_SUBSYS_RESET); ++ if (ret) ++ return ret; ++ ++ return nvme_try_sched_reset(ctrl); ++} ++EXPORT_SYMBOL_GPL(nvmf_subsystem_reset); ++ + /** + * nvmf_log_connect_error() - Error-parsing-diagnostic print out function for + * connect() errors. +--- a/drivers/nvme/host/fabrics.h ++++ b/drivers/nvme/host/fabrics.h +@@ -182,6 +182,7 @@ nvmf_ctlr_matches_baseopts(struct nvme_c + int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val); + int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val); + int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val); ++int nvmf_subsystem_reset(struct nvme_ctrl *ctrl); + int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl); + int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid); + int nvmf_register_transport(struct nvmf_transport_ops *ops); +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -3361,6 +3361,7 @@ static const struct nvme_ctrl_ops nvme_f + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, ++ .subsystem_reset = nvmf_subsystem_reset, + .free_ctrl = nvme_fc_free_ctrl, + .submit_async_event = nvme_fc_submit_async_event, + .delete_ctrl = nvme_fc_delete_ctrl, +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -514,6 +514,7 @@ struct nvme_ctrl_ops { + int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val); + void (*free_ctrl)(struct nvme_ctrl *ctrl); + void (*submit_async_event)(struct nvme_ctrl *ctrl); ++ int (*subsystem_reset)(struct nvme_ctrl *ctrl); + void (*delete_ctrl)(struct nvme_ctrl *ctrl); + void (*stop_ctrl)(struct nvme_ctrl *ctrl); + int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); +@@ -583,18 +584,9 @@ int nvme_try_sched_reset(struct nvme_ctr + + static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl) + { +- int ret; +- +- if (!ctrl->subsystem) ++ if (!ctrl->subsystem || !ctrl->ops->subsystem_reset) + return -ENOTTY; +- if (!nvme_wait_reset(ctrl)) +- return -EBUSY; +- +- ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); +- if (ret) +- return ret; +- +- return nvme_try_sched_reset(ctrl); ++ return ctrl->ops->subsystem_reset(ctrl); + } + + /* +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1121,6 +1121,41 @@ static void nvme_pci_submit_async_event( + spin_unlock(&nvmeq->sq_lock); + } + ++static int nvme_pci_subsystem_reset(struct nvme_ctrl *ctrl) ++{ ++ struct nvme_dev *dev = to_nvme_dev(ctrl); ++ int ret = 0; ++ ++ /* ++ * Taking the shutdown_lock ensures the BAR mapping is not being ++ * altered by reset_work. Holding this lock before the RESETTING state ++ * change, if successful, also ensures nvme_remove won't be able to ++ * proceed to iounmap until we're done. ++ */ ++ mutex_lock(&dev->shutdown_lock); ++ if (!dev->bar_mapped_size) { ++ ret = -ENODEV; ++ goto unlock; ++ } ++ ++ if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) { ++ ret = -EBUSY; ++ goto unlock; ++ } ++ ++ writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR); ++ nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE); ++ ++ /* ++ * Read controller status to flush the previous write and trigger a ++ * pcie read error. ++ */ ++ readl(dev->bar + NVME_REG_CSTS); ++unlock: ++ mutex_unlock(&dev->shutdown_lock); ++ return ret; ++} ++ + static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id) + { + struct nvme_command c = { }; +@@ -2905,6 +2940,7 @@ static const struct nvme_ctrl_ops nvme_p + .reg_read64 = nvme_pci_reg_read64, + .free_ctrl = nvme_pci_free_ctrl, + .submit_async_event = nvme_pci_submit_async_event, ++ .subsystem_reset = nvme_pci_subsystem_reset, + .get_address = nvme_pci_get_address, + }; + +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -2287,6 +2287,7 @@ static const struct nvme_ctrl_ops nvme_r + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, ++ .subsystem_reset = nvmf_subsystem_reset, + .free_ctrl = nvme_rdma_free_ctrl, + .submit_async_event = nvme_rdma_submit_async_event, + .delete_ctrl = nvme_rdma_delete_ctrl, +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -2559,6 +2559,7 @@ static const struct nvme_ctrl_ops nvme_t + .reg_read32 = nvmf_reg_read32, + .reg_read64 = nvmf_reg_read64, + .reg_write32 = nvmf_reg_write32, ++ .subsystem_reset = nvmf_subsystem_reset, + .free_ctrl = nvme_tcp_free_ctrl, + .submit_async_event = nvme_tcp_submit_async_event, + .delete_ctrl = nvme_tcp_delete_ctrl, +--- a/include/linux/nvme.h ++++ b/include/linux/nvme.h +@@ -27,6 +27,9 @@ + + #define NVME_NSID_ALL 0xffffffff + ++/* Special NSSR value, 'NVMe' */ ++#define NVME_SUBSYS_RESET 0x4E564D65 ++ + enum nvme_subsys_type { + NVME_NQN_DISC = 1, /* Discovery type target subsystem */ + NVME_NQN_NVME = 2, /* NVME type target subsystem */ diff --git a/queue-5.15/of-platform-use-default-match-table-for-firmware.patch b/queue-5.15/of-platform-use-default-match-table-for-firmware.patch new file mode 100644 index 0000000000..2d1f9d65d5 --- /dev/null +++ b/queue-5.15/of-platform-use-default-match-table-for-firmware.patch @@ -0,0 +1,40 @@ +From 48e6a9c4a20870e09f85ff1a3628275d6bce31c0 Mon Sep 17 00:00:00 2001 +From: "Rob Herring (Arm)" +Date: Tue, 13 Jan 2026 19:51:58 -0600 +Subject: of: platform: Use default match table for /firmware + +From: Rob Herring (Arm) + +commit 48e6a9c4a20870e09f85ff1a3628275d6bce31c0 upstream. + +Calling of_platform_populate() without a match table will only populate +the immediate child nodes under /firmware. This is usually fine, but in +the case of something like a "simple-mfd" node such as +"raspberrypi,bcm2835-firmware", those child nodes will not be populated. +And subsequent calls won't work either because the /firmware node is +marked as processed already. + +Switch the call to of_platform_default_populate() to solve this problem. +It should be a nop for existing cases. + +Fixes: 3aa0582fdb82 ("of: platform: populate /firmware/ node from of_platform_default_populate_init()") +Cc: stable@vger.kernel.org +Reviewed-by: Sudeep Holla +Link: https://patch.msgid.link/20260114015158.692170-2-robh@kernel.org +Signed-off-by: Rob Herring (Arm) +Signed-off-by: Greg Kroah-Hartman +--- + drivers/of/platform.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/of/platform.c ++++ b/drivers/of/platform.c +@@ -533,7 +533,7 @@ static int __init of_platform_default_po + + node = of_find_node_by_path("/firmware"); + if (node) { +- of_platform_populate(node, NULL, NULL, NULL); ++ of_platform_default_populate(node, NULL, NULL); + of_node_put(node); + } + diff --git a/queue-5.15/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch b/queue-5.15/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch new file mode 100644 index 0000000000..5828f99660 --- /dev/null +++ b/queue-5.15/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch @@ -0,0 +1,40 @@ +From stable+bounces-211667-greg=kroah.com@vger.kernel.org Mon Jan 26 18:42:22 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 12:42:12 -0500 +Subject: scsi: xen: scsiback: Fix potential memory leak in scsiback_remove() +To: stable@vger.kernel.org +Cc: Abdun Nihaal , Juergen Gross , "Martin K. Petersen" , Sasha Levin +Message-ID: <20260126174212.3433842-1-sashal@kernel.org> + +From: Abdun Nihaal + +[ Upstream commit 901a5f309daba412e2a30364d7ec1492fa11c32c ] + +Memory allocated for struct vscsiblk_info in scsiback_probe() is not +freed in scsiback_remove() leading to potential memory leaks on remove, +as well as in the scsiback_probe() error paths. Fix that by freeing it +in scsiback_remove(). + +Cc: stable@vger.kernel.org +Fixes: d9d660f6e562 ("xen-scsiback: Add Xen PV SCSI backend driver") +Signed-off-by: Abdun Nihaal +Reviewed-by: Juergen Gross +Link: https://patch.msgid.link/20251223063012.119035-1-nihaal@cse.iitm.ac.in +Signed-off-by: Martin K. Petersen +[ adapted void scsiback_remove() to int return type with return 0 statement ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/xen/xen-scsiback.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/xen/xen-scsiback.c ++++ b/drivers/xen/xen-scsiback.c +@@ -1197,6 +1197,7 @@ static int scsiback_remove(struct xenbus + gnttab_page_cache_shrink(&info->free_pages, 0); + + dev_set_drvdata(&dev->dev, NULL); ++ kfree(info); + + return 0; + } diff --git a/queue-5.15/series b/queue-5.15/series index d3a91d4e23..b2a60c83b3 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -152,3 +152,41 @@ asoc-fsl-imx-card-do-not-force-slot-width-to-sample-width.patch scsi-be2iscsi-fix-a-memory-leak-in-beiscsi_boot_get_sinfo.patch scsi-qla2xxx-edif-fix-dma_free_coherent-size.patch mptcp-only-reset-subflow-errors-when-propagated.patch +net-add-locking-to-protect-skb-dev-access-in-ip_output.patch +tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch +comedi-fix-getting-range-information-for-subdevices-16-to-255.patch +of-platform-use-default-match-table-for-firmware.patch +iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch +scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch +arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch +w1-w1_therm-use-swap-to-make-code-cleaner.patch +w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch +dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch +dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch +xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch +nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch +nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch +nvme-fix-pcie-subsystem-reset-controller-state-transition.patch +alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch +mei-trace-treat-reg-parameter-as-string.patch +ksmbd-smbd-fix-dma_unmap_sg-nents.patch +mm-pagewalk-add-walk_page_range_vma.patch +ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch +drm-ttm-fix-undefined-behavior-in-bit-shift-for-ttm_tt_flag_priv_populated.patch +ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-under-concurrency.patch +fs-ntfs3-initialize-allocated-memory-before-use.patch +blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-blkcg_reset_stats.patch +espintcp-fix-skb-leaks.patch +ext4-fix-memory-leaks-in-ext4_fname_-setup_filename-prepare_lookup.patch +nfsd-fix-race-between-nfsd-registration-and-exports_proc.patch +usbnet-fix-using-smp_processor_id-in-preemptible-code-warnings.patch +net-stmmac-make-sure-that-ptp_rate-is-not-0-before-configuring-est.patch +bluetooth-fix-hci_suspend_sync-crash.patch +wifi-cfg80211-add-a-work-abstraction-with-special-semantics.patch +wifi-mac80211-use-wiphy-work-for-sdata-work.patch +wifi-mac80211-move-tdls-work-to-wiphy-work.patch +hid-uclogic-correct-devm-device-reference-for-hidinput-input_dev-name.patch +hid-uclogic-add-null-check-in-uclogic_input_configured.patch +genirq-irq_sim-initialize-work-context-pointers-properly.patch +can-esd_usb-esd_usb_read_bulk_callback-fix-urb-memory-leak.patch +drm-amdkfd-fix-a-memory-leak-in-device_queue_manager_init.patch diff --git a/queue-5.15/tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch b/queue-5.15/tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch new file mode 100644 index 0000000000..9260c148da --- /dev/null +++ b/queue-5.15/tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch @@ -0,0 +1,62 @@ +From c65f27b9c3be2269918e1cbad6d8884741f835c5 Mon Sep 17 00:00:00 2001 +From: Kuniyuki Iwashima +Date: Tue, 16 Sep 2025 21:47:23 +0000 +Subject: tls: Use __sk_dst_get() and dst_dev_rcu() in get_netdev_for_sock(). + +From: Kuniyuki Iwashima + +commit c65f27b9c3be2269918e1cbad6d8884741f835c5 upstream. + +get_netdev_for_sock() is called during setsockopt(), +so not under RCU. + +Using sk_dst_get(sk)->dev could trigger UAF. + +Let's use __sk_dst_get() and dst_dev_rcu(). + +Note that the only ->ndo_sk_get_lower_dev() user is +bond_sk_get_lower_dev(), which uses RCU. + +Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure") +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Eric Dumazet +Reviewed-by: Sabrina Dubroca +Link: https://patch.msgid.link/20250916214758.650211-6-kuniyu@google.com +Signed-off-by: Jakub Kicinski +[ Keerthana: Backport to v5.15-v6.1 ] +Signed-off-by: Keerthana K +Signed-off-by: Greg Kroah-Hartman +--- + net/tls/tls_device.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/net/tls/tls_device.c ++++ b/net/tls/tls_device.c +@@ -110,17 +110,19 @@ static void tls_device_queue_ctx_destruc + /* We assume that the socket is already connected */ + static struct net_device *get_netdev_for_sock(struct sock *sk) + { +- struct dst_entry *dst = sk_dst_get(sk); +- struct net_device *netdev = NULL; ++ struct net_device *dev, *lowest_dev = NULL; ++ struct dst_entry *dst; + +- if (likely(dst)) { +- netdev = netdev_sk_get_lowest_dev(dst->dev, sk); +- dev_hold(netdev); ++ rcu_read_lock(); ++ dst = __sk_dst_get(sk); ++ dev = dst ? dst_dev_rcu(dst) : NULL; ++ if (likely(dev)) { ++ lowest_dev = netdev_sk_get_lowest_dev(dev, sk); ++ dev_hold(lowest_dev); + } ++ rcu_read_unlock(); + +- dst_release(dst); +- +- return netdev; ++ return lowest_dev; + } + + static void destroy_record(struct tls_record_info *record) diff --git a/queue-5.15/usbnet-fix-using-smp_processor_id-in-preemptible-code-warnings.patch b/queue-5.15/usbnet-fix-using-smp_processor_id-in-preemptible-code-warnings.patch new file mode 100644 index 0000000000..fe2bd60b00 --- /dev/null +++ b/queue-5.15/usbnet-fix-using-smp_processor_id-in-preemptible-code-warnings.patch @@ -0,0 +1,78 @@ +From stable+bounces-212825-greg=kroah.com@vger.kernel.org Fri Jan 30 02:09:12 2026 +From: Rahul Sharma +Date: Fri, 30 Jan 2026 09:07:51 +0800 +Subject: usbnet: Fix using smp_processor_id() in preemptible code warnings +To: gregkh@linuxfoundation.org, stable@vger.kernel.org +Cc: linux-kernel@vger.kernel.org, Zqiang , Jakub Kicinski , Paolo Abeni , Rahul Sharma +Message-ID: <20260130010751.2982401-1-black.hawk@163.com> + +From: Zqiang + +[ Upstream commit 327cd4b68b4398b6c24f10eb2b2533ffbfc10185 ] + +Syzbot reported the following warning: + +BUG: using smp_processor_id() in preemptible [00000000] code: dhcpcd/2879 +caller is usbnet_skb_return+0x74/0x490 drivers/net/usb/usbnet.c:331 +CPU: 1 UID: 0 PID: 2879 Comm: dhcpcd Not tainted 6.15.0-rc4-syzkaller-00098-g615dca38c2ea #0 PREEMPT(voluntary) +Call Trace: + + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120 + check_preemption_disabled+0xd0/0xe0 lib/smp_processor_id.c:49 + usbnet_skb_return+0x74/0x490 drivers/net/usb/usbnet.c:331 + usbnet_resume_rx+0x4b/0x170 drivers/net/usb/usbnet.c:708 + usbnet_change_mtu+0x1be/0x220 drivers/net/usb/usbnet.c:417 + __dev_set_mtu net/core/dev.c:9443 [inline] + netif_set_mtu_ext+0x369/0x5c0 net/core/dev.c:9496 + netif_set_mtu+0xb0/0x160 net/core/dev.c:9520 + dev_set_mtu+0xae/0x170 net/core/dev_api.c:247 + dev_ifsioc+0xa31/0x18d0 net/core/dev_ioctl.c:572 + dev_ioctl+0x223/0x10e0 net/core/dev_ioctl.c:821 + sock_do_ioctl+0x19d/0x280 net/socket.c:1204 + sock_ioctl+0x42f/0x6a0 net/socket.c:1311 + vfs_ioctl fs/ioctl.c:51 [inline] + __do_sys_ioctl fs/ioctl.c:906 [inline] + __se_sys_ioctl fs/ioctl.c:892 [inline] + __x64_sys_ioctl+0x190/0x200 fs/ioctl.c:892 + do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] + do_syscall_64+0xcd/0x260 arch/x86/entry/syscall_64.c:94 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +For historical and portability reasons, the netif_rx() is usually +run in the softirq or interrupt context, this commit therefore add +local_bh_disable/enable() protection in the usbnet_resume_rx(). + +Fixes: 43daa96b166c ("usbnet: Stop RX Q on MTU change") +Link: https://syzkaller.appspot.com/bug?id=81f55dfa587ee544baaaa5a359a060512228c1e1 +Suggested-by: Jakub Kicinski +Signed-off-by: Zqiang +Link: https://patch.msgid.link/20251011070518.7095-1-qiang.zhang@linux.dev +Signed-off-by: Paolo Abeni +[ The context change is due to the commit 2c04d279e857 +("net: usb: Convert tasklet API to new bottom half workqueue mechanism") +in v6.17 which is irrelevant to the logic of this patch.] +Signed-off-by: Rahul Sharma +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/usbnet.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -707,6 +707,7 @@ void usbnet_resume_rx(struct usbnet *dev + struct sk_buff *skb; + int num = 0; + ++ local_bh_disable(); + clear_bit(EVENT_RX_PAUSED, &dev->flags); + + while ((skb = skb_dequeue(&dev->rxq_pause)) != NULL) { +@@ -715,6 +716,7 @@ void usbnet_resume_rx(struct usbnet *dev + } + + tasklet_schedule(&dev->bh); ++ local_bh_enable(); + + netif_dbg(dev, rx_status, dev->net, + "paused rx queue disabled, %d skbs requeued\n", num); diff --git a/queue-5.15/w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch b/queue-5.15/w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch new file mode 100644 index 0000000000..d46043a3b6 --- /dev/null +++ b/queue-5.15/w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch @@ -0,0 +1,136 @@ +From stable+bounces-211640-greg=kroah.com@vger.kernel.org Mon Jan 26 16:51:36 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 10:50:57 -0500 +Subject: w1: therm: Fix off-by-one buffer overflow in alarms_store +To: stable@vger.kernel.org +Cc: Thorsten Blum , Krzysztof Kozlowski , Sasha Levin +Message-ID: <20260126155057.3322542-2-sashal@kernel.org> + +From: Thorsten Blum + +[ Upstream commit 761fcf46a1bd797bd32d23f3ea0141ffd437668a ] + +The sysfs buffer passed to alarms_store() is allocated with 'size + 1' +bytes and a NUL terminator is appended. However, the 'size' argument +does not account for this extra byte. The original code then allocated +'size' bytes and used strcpy() to copy 'buf', which always writes one +byte past the allocated buffer since strcpy() copies until the NUL +terminator at index 'size'. + +Fix this by parsing the 'buf' parameter directly using simple_strtoll() +without allocating any intermediate memory or string copying. This +removes the overflow while simplifying the code. + +Cc: stable@vger.kernel.org +Fixes: e2c94d6f5720 ("w1_therm: adding alarm sysfs entry") +Signed-off-by: Thorsten Blum +Link: https://patch.msgid.link/20251216145007.44328-2-thorsten.blum@linux.dev +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_therm.c | 60 +++++++++++++------------------------------ + 1 file changed, 19 insertions(+), 41 deletions(-) + +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -1780,53 +1780,35 @@ static ssize_t alarms_store(struct devic + struct w1_slave *sl = dev_to_w1_slave(device); + struct therm_info info; + u8 new_config_register[3]; /* array of data to be written */ +- int temp, ret; +- char *token = NULL; ++ long long temp; ++ int ret = 0; + s8 tl, th; /* 1 byte per value + temp ring order */ +- char *p_args, *orig; ++ const char *p = buf; ++ char *endp; + +- p_args = orig = kmalloc(size, GFP_KERNEL); +- /* Safe string copys as buf is const */ +- if (!p_args) { +- dev_warn(device, +- "%s: error unable to allocate memory %d\n", +- __func__, -ENOMEM); +- return size; +- } +- strcpy(p_args, buf); +- +- /* Split string using space char */ +- token = strsep(&p_args, " "); +- +- if (!token) { +- dev_info(device, +- "%s: error parsing args %d\n", __func__, -EINVAL); +- goto free_m; +- } +- +- /* Convert 1st entry to int */ +- ret = kstrtoint (token, 10, &temp); ++ temp = simple_strtoll(p, &endp, 10); ++ if (p == endp || *endp != ' ') ++ ret = -EINVAL; ++ else if (temp < INT_MIN || temp > INT_MAX) ++ ret = -ERANGE; + if (ret) { + dev_info(device, + "%s: error parsing args %d\n", __func__, ret); +- goto free_m; ++ return size; + } + + tl = int_to_short(temp); + +- /* Split string using space char */ +- token = strsep(&p_args, " "); +- if (!token) { +- dev_info(device, +- "%s: error parsing args %d\n", __func__, -EINVAL); +- goto free_m; +- } +- /* Convert 2nd entry to int */ +- ret = kstrtoint (token, 10, &temp); ++ p = endp + 1; ++ temp = simple_strtoll(p, &endp, 10); ++ if (p == endp) ++ ret = -EINVAL; ++ else if (temp < INT_MIN || temp > INT_MAX) ++ ret = -ERANGE; + if (ret) { + dev_info(device, + "%s: error parsing args %d\n", __func__, ret); +- goto free_m; ++ return size; + } + + /* Prepare to cast to short by eliminating out of range values */ +@@ -1849,7 +1831,7 @@ static ssize_t alarms_store(struct devic + dev_info(device, + "%s: error reading from the slave device %d\n", + __func__, ret); +- goto free_m; ++ return size; + } + + /* Write data in the device RAM */ +@@ -1857,7 +1839,7 @@ static ssize_t alarms_store(struct devic + dev_info(device, + "%s: Device not supported by the driver %d\n", + __func__, -ENODEV); +- goto free_m; ++ return size; + } + + ret = SLAVE_SPECIFIC_FUNC(sl)->write_data(sl, new_config_register); +@@ -1866,10 +1848,6 @@ static ssize_t alarms_store(struct devic + "%s: error writing to the slave device %d\n", + __func__, ret); + +-free_m: +- /* free allocated memory */ +- kfree(orig); +- + return size; + } + diff --git a/queue-5.15/w1-w1_therm-use-swap-to-make-code-cleaner.patch b/queue-5.15/w1-w1_therm-use-swap-to-make-code-cleaner.patch new file mode 100644 index 0000000000..b63eadb420 --- /dev/null +++ b/queue-5.15/w1-w1_therm-use-swap-to-make-code-cleaner.patch @@ -0,0 +1,50 @@ +From stable+bounces-211639-greg=kroah.com@vger.kernel.org Mon Jan 26 16:51:33 2026 +From: Sasha Levin +Date: Mon, 26 Jan 2026 10:50:56 -0500 +Subject: w1: w1_therm: use swap() to make code cleaner +To: stable@vger.kernel.org +Cc: Yang Guang , Zeal Robot , David Yang , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20260126155057.3322542-1-sashal@kernel.org> + +From: Yang Guang + +[ Upstream commit e233897b1f7a859092bd20b10bfd412013381a10 ] + +Use the macro 'swap()' defined in 'include/linux/minmax.h' to avoid +opencoding it. + +Reported-by: Zeal Robot +Signed-off-by: David Yang +Signed-off-by: Yang Guang +Link: https://lore.kernel.org/r/cb14f9e6e86cf8494ed2ddce6eec8ebd988908d9.1640077704.git.yang.guang5@zte.com.cn +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 761fcf46a1bd ("w1: therm: Fix off-by-one buffer overflow in alarms_store") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/w1/slaves/w1_therm.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/w1/slaves/w1_therm.c ++++ b/drivers/w1/slaves/w1_therm.c +@@ -1782,7 +1782,7 @@ static ssize_t alarms_store(struct devic + u8 new_config_register[3]; /* array of data to be written */ + int temp, ret; + char *token = NULL; +- s8 tl, th, tt; /* 1 byte per value + temp ring order */ ++ s8 tl, th; /* 1 byte per value + temp ring order */ + char *p_args, *orig; + + p_args = orig = kmalloc(size, GFP_KERNEL); +@@ -1833,9 +1833,8 @@ static ssize_t alarms_store(struct devic + th = int_to_short(temp); + + /* Reorder if required th and tl */ +- if (tl > th) { +- tt = tl; tl = th; th = tt; +- } ++ if (tl > th) ++ swap(tl, th); + + /* + * Read the scratchpad to change only the required bits diff --git a/queue-5.15/wifi-cfg80211-add-a-work-abstraction-with-special-semantics.patch b/queue-5.15/wifi-cfg80211-add-a-work-abstraction-with-special-semantics.patch new file mode 100644 index 0000000000..780d30aee1 --- /dev/null +++ b/queue-5.15/wifi-cfg80211-add-a-work-abstraction-with-special-semantics.patch @@ -0,0 +1,368 @@ +From stable+bounces-213088-greg=kroah.com@vger.kernel.org Mon Feb 2 17:54:58 2026 +From: "Hanne-Lotta Mäenpää" +Date: Mon, 2 Feb 2026 18:50:36 +0200 +Subject: wifi: cfg80211: add a work abstraction with special semantics +To: stable@vger.kernel.org +Cc: johannes@sipsolutions.net, linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, "Johannes Berg" , "Hanne-Lotta Mäenpää" +Message-ID: <20260202165038.215693-1-hannelotta@gmail.com> + +From: Johannes Berg + +[ Upstream commit a3ee4dc84c4e9d14cb34dad095fd678127aca5b6 ] + +Add a work abstraction at the cfg80211 level that will always +hold the wiphy_lock() for any work executed and therefore also +can be canceled safely (without waiting) while holding that. +This improves on what we do now as with the new wiphy works we +don't have to worry about locking while cancelling them safely. + +Also, don't let such works run while the device is suspended, +since they'll likely need to interact with the device. Flush +them before suspend though. + +Signed-off-by: Johannes Berg +Signed-off-by: Hanne-Lotta Mäenpää +Signed-off-by: Greg Kroah-Hartman +--- + include/net/cfg80211.h | 95 ++++++++++++++++++++++++++++++++++++-- + net/wireless/core.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++ + net/wireless/core.h | 7 ++ + net/wireless/sysfs.c | 8 ++- + 4 files changed, 226 insertions(+), 5 deletions(-) + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -5301,12 +5301,17 @@ struct cfg80211_cqm_config; + * wiphy_lock - lock the wiphy + * @wiphy: the wiphy to lock + * +- * This is mostly exposed so it can be done around registering and +- * unregistering netdevs that aren't created through cfg80211 calls, +- * since that requires locking in cfg80211 when the notifiers is +- * called, but that cannot differentiate which way it's called. ++ * This is needed around registering and unregistering netdevs that ++ * aren't created through cfg80211 calls, since that requires locking ++ * in cfg80211 when the notifiers is called, but that cannot ++ * differentiate which way it's called. ++ * ++ * It can also be used by drivers for their own purposes. + * + * When cfg80211 ops are called, the wiphy is already locked. ++ * ++ * Note that this makes sure that no workers that have been queued ++ * with wiphy_queue_work() are running. + */ + static inline void wiphy_lock(struct wiphy *wiphy) + __acquires(&wiphy->mtx) +@@ -5326,6 +5331,88 @@ static inline void wiphy_unlock(struct w + mutex_unlock(&wiphy->mtx); + } + ++struct wiphy_work; ++typedef void (*wiphy_work_func_t)(struct wiphy *, struct wiphy_work *); ++ ++struct wiphy_work { ++ struct list_head entry; ++ wiphy_work_func_t func; ++}; ++ ++static inline void wiphy_work_init(struct wiphy_work *work, ++ wiphy_work_func_t func) ++{ ++ INIT_LIST_HEAD(&work->entry); ++ work->func = func; ++} ++ ++/** ++ * wiphy_work_queue - queue work for the wiphy ++ * @wiphy: the wiphy to queue for ++ * @work: the work item ++ * ++ * This is useful for work that must be done asynchronously, and work ++ * queued here has the special property that the wiphy mutex will be ++ * held as if wiphy_lock() was called, and that it cannot be running ++ * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can ++ * use just cancel_work() instead of cancel_work_sync(), it requires ++ * being in a section protected by wiphy_lock(). ++ */ ++void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work); ++ ++/** ++ * wiphy_work_cancel - cancel previously queued work ++ * @wiphy: the wiphy, for debug purposes ++ * @work: the work to cancel ++ * ++ * Cancel the work *without* waiting for it, this assumes being ++ * called under the wiphy mutex acquired by wiphy_lock(). ++ */ ++void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work); ++ ++struct wiphy_delayed_work { ++ struct wiphy_work work; ++ struct wiphy *wiphy; ++ struct timer_list timer; ++}; ++ ++void wiphy_delayed_work_timer(struct timer_list *t); ++ ++static inline void wiphy_delayed_work_init(struct wiphy_delayed_work *dwork, ++ wiphy_work_func_t func) ++{ ++ timer_setup(&dwork->timer, wiphy_delayed_work_timer, 0); ++ wiphy_work_init(&dwork->work, func); ++} ++ ++/** ++ * wiphy_delayed_work_queue - queue delayed work for the wiphy ++ * @wiphy: the wiphy to queue for ++ * @dwork: the delayable worker ++ * @delay: number of jiffies to wait before queueing ++ * ++ * This is useful for work that must be done asynchronously, and work ++ * queued here has the special property that the wiphy mutex will be ++ * held as if wiphy_lock() was called, and that it cannot be running ++ * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can ++ * use just cancel_work() instead of cancel_work_sync(), it requires ++ * being in a section protected by wiphy_lock(). ++ */ ++void wiphy_delayed_work_queue(struct wiphy *wiphy, ++ struct wiphy_delayed_work *dwork, ++ unsigned long delay); ++ ++/** ++ * wiphy_delayed_work_cancel - cancel previously queued delayed work ++ * @wiphy: the wiphy, for debug purposes ++ * @dwork: the delayed work to cancel ++ * ++ * Cancel the work *without* waiting for it, this assumes being ++ * called under the wiphy mutex acquired by wiphy_lock(). ++ */ ++void wiphy_delayed_work_cancel(struct wiphy *wiphy, ++ struct wiphy_delayed_work *dwork); ++ + /** + * struct wireless_dev - wireless device state + * +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -410,6 +410,34 @@ static void cfg80211_propagate_cac_done_ + rtnl_unlock(); + } + ++static void cfg80211_wiphy_work(struct work_struct *work) ++{ ++ struct cfg80211_registered_device *rdev; ++ struct wiphy_work *wk; ++ ++ rdev = container_of(work, struct cfg80211_registered_device, wiphy_work); ++ ++ wiphy_lock(&rdev->wiphy); ++ if (rdev->suspended) ++ goto out; ++ ++ spin_lock_irq(&rdev->wiphy_work_lock); ++ wk = list_first_entry_or_null(&rdev->wiphy_work_list, ++ struct wiphy_work, entry); ++ if (wk) { ++ list_del_init(&wk->entry); ++ if (!list_empty(&rdev->wiphy_work_list)) ++ schedule_work(work); ++ spin_unlock_irq(&rdev->wiphy_work_lock); ++ ++ wk->func(&rdev->wiphy, wk); ++ } else { ++ spin_unlock_irq(&rdev->wiphy_work_lock); ++ } ++out: ++ wiphy_unlock(&rdev->wiphy); ++} ++ + /* exported functions */ + + struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, +@@ -535,6 +563,9 @@ use_default_name: + return NULL; + } + ++ INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work); ++ INIT_LIST_HEAD(&rdev->wiphy_work_list); ++ spin_lock_init(&rdev->wiphy_work_lock); + INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); + INIT_WORK(&rdev->conn_work, cfg80211_conn_work); + INIT_WORK(&rdev->event_work, cfg80211_event_work); +@@ -1002,6 +1033,31 @@ void wiphy_rfkill_start_polling(struct w + } + EXPORT_SYMBOL(wiphy_rfkill_start_polling); + ++void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev) ++{ ++ unsigned int runaway_limit = 100; ++ unsigned long flags; ++ ++ lockdep_assert_held(&rdev->wiphy.mtx); ++ ++ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); ++ while (!list_empty(&rdev->wiphy_work_list)) { ++ struct wiphy_work *wk; ++ ++ wk = list_first_entry(&rdev->wiphy_work_list, ++ struct wiphy_work, entry); ++ list_del_init(&wk->entry); ++ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); ++ ++ wk->func(&rdev->wiphy, wk); ++ ++ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); ++ if (WARN_ON(--runaway_limit == 0)) ++ INIT_LIST_HEAD(&rdev->wiphy_work_list); ++ } ++ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); ++} ++ + void wiphy_unregister(struct wiphy *wiphy) + { + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); +@@ -1040,9 +1096,14 @@ void wiphy_unregister(struct wiphy *wiph + cfg80211_rdev_list_generation++; + device_del(&rdev->wiphy.dev); + ++ /* surely nothing is reachable now, clean up work */ ++ cfg80211_process_wiphy_works(rdev); + wiphy_unlock(&rdev->wiphy); + rtnl_unlock(); + ++ /* this has nothing to do now but make sure it's gone */ ++ cancel_work_sync(&rdev->wiphy_work); ++ + flush_work(&rdev->scan_done_wk); + cancel_work_sync(&rdev->conn_work); + flush_work(&rdev->event_work); +@@ -1522,6 +1583,66 @@ static struct pernet_operations cfg80211 + .exit = cfg80211_pernet_exit, + }; + ++void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work) ++{ ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); ++ if (list_empty(&work->entry)) ++ list_add_tail(&work->entry, &rdev->wiphy_work_list); ++ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); ++ ++ schedule_work(&rdev->wiphy_work); ++} ++EXPORT_SYMBOL_GPL(wiphy_work_queue); ++ ++void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work) ++{ ++ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); ++ unsigned long flags; ++ ++ lockdep_assert_held(&wiphy->mtx); ++ ++ spin_lock_irqsave(&rdev->wiphy_work_lock, flags); ++ if (!list_empty(&work->entry)) ++ list_del_init(&work->entry); ++ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); ++} ++EXPORT_SYMBOL_GPL(wiphy_work_cancel); ++ ++void wiphy_delayed_work_timer(struct timer_list *t) ++{ ++ struct wiphy_delayed_work *dwork = from_timer(dwork, t, timer); ++ ++ wiphy_work_queue(dwork->wiphy, &dwork->work); ++} ++EXPORT_SYMBOL(wiphy_delayed_work_timer); ++ ++void wiphy_delayed_work_queue(struct wiphy *wiphy, ++ struct wiphy_delayed_work *dwork, ++ unsigned long delay) ++{ ++ if (!delay) { ++ wiphy_work_queue(wiphy, &dwork->work); ++ return; ++ } ++ ++ dwork->wiphy = wiphy; ++ mod_timer(&dwork->timer, jiffies + delay); ++} ++EXPORT_SYMBOL_GPL(wiphy_delayed_work_queue); ++ ++void wiphy_delayed_work_cancel(struct wiphy *wiphy, ++ struct wiphy_delayed_work *dwork) ++{ ++ lockdep_assert_held(&wiphy->mtx); ++ ++ del_timer_sync(&dwork->timer); ++ wiphy_work_cancel(wiphy, &dwork->work); ++} ++EXPORT_SYMBOL_GPL(wiphy_delayed_work_cancel); ++ + static int __init cfg80211_init(void) + { + int err; +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -103,6 +103,12 @@ struct cfg80211_registered_device { + /* lock for all wdev lists */ + spinlock_t mgmt_registrations_lock; + ++ struct work_struct wiphy_work; ++ struct list_head wiphy_work_list; ++ /* protects the list above */ ++ spinlock_t wiphy_work_lock; ++ bool suspended; ++ + /* must be last because of the way we do wiphy_priv(), + * and it should at least be aligned to NETDEV_ALIGN */ + struct wiphy wiphy __aligned(NETDEV_ALIGN); +@@ -457,6 +463,7 @@ int cfg80211_change_iface(struct cfg8021 + struct net_device *dev, enum nl80211_iftype ntype, + struct vif_params *params); + void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); ++void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev); + void cfg80211_process_wdev_events(struct wireless_dev *wdev); + + bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, +--- a/net/wireless/sysfs.c ++++ b/net/wireless/sysfs.c +@@ -5,7 +5,7 @@ + * + * Copyright 2005-2006 Jiri Benc + * Copyright 2006 Johannes Berg +- * Copyright (C) 2020-2021 Intel Corporation ++ * Copyright (C) 2020-2021, 2023 Intel Corporation + */ + + #include +@@ -105,14 +105,18 @@ static int wiphy_suspend(struct device * + cfg80211_leave_all(rdev); + cfg80211_process_rdev_events(rdev); + } ++ cfg80211_process_wiphy_works(rdev); + if (rdev->ops->suspend) + ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config); + if (ret == 1) { + /* Driver refuse to configure wowlan */ + cfg80211_leave_all(rdev); + cfg80211_process_rdev_events(rdev); ++ cfg80211_process_wiphy_works(rdev); + ret = rdev_suspend(rdev, NULL); + } ++ if (ret == 0) ++ rdev->suspended = true; + } + wiphy_unlock(&rdev->wiphy); + rtnl_unlock(); +@@ -132,6 +136,8 @@ static int wiphy_resume(struct device *d + wiphy_lock(&rdev->wiphy); + if (rdev->wiphy.registered && rdev->ops->resume) + ret = rdev_resume(rdev); ++ rdev->suspended = false; ++ schedule_work(&rdev->wiphy_work); + wiphy_unlock(&rdev->wiphy); + + if (ret) diff --git a/queue-5.15/wifi-mac80211-move-tdls-work-to-wiphy-work.patch b/queue-5.15/wifi-mac80211-move-tdls-work-to-wiphy-work.patch new file mode 100644 index 0000000000..a957e45ec5 --- /dev/null +++ b/queue-5.15/wifi-mac80211-move-tdls-work-to-wiphy-work.patch @@ -0,0 +1,104 @@ +From stable+bounces-213090-greg=kroah.com@vger.kernel.org Mon Feb 2 17:52:04 2026 +From: "Hanne-Lotta Mäenpää" +Date: Mon, 2 Feb 2026 18:50:38 +0200 +Subject: wifi: mac80211: move TDLS work to wiphy work +To: stable@vger.kernel.org +Cc: johannes@sipsolutions.net, linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, "Johannes Berg" , "Emmanuel Grumbach" , "Hanne-Lotta Mäenpää" +Message-ID: <20260202165038.215693-3-hannelotta@gmail.com> + +From: Johannes Berg + +[ Upstream commit 777b26002b73127e81643d9286fadf3d41e0e477 ] + +Again, to have the wiphy locked for it. + +Reviewed-by: Emmanuel Grumbach +Signed-off-by: Johannes Berg +[ Summary of conflict resolutions: + - In mlme.c, move only tdls_peer_del_work + to wiphy work, and none the other works ] +Signed-off-by: Hanne-Lotta Mäenpää +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/ieee80211_i.h | 4 ++-- + net/mac80211/mlme.c | 7 ++++--- + net/mac80211/tdls.c | 11 ++++++----- + 3 files changed, 12 insertions(+), 10 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -542,7 +542,7 @@ struct ieee80211_if_managed { + + /* TDLS support */ + u8 tdls_peer[ETH_ALEN] __aligned(2); +- struct delayed_work tdls_peer_del_work; ++ struct wiphy_delayed_work tdls_peer_del_work; + struct sk_buff *orig_teardown_skb; /* The original teardown skb */ + struct sk_buff *teardown_skb; /* A copy to send through the AP */ + spinlock_t teardown_lock; /* To lock changing teardown_skb */ +@@ -2494,7 +2494,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wi + size_t extra_ies_len); + int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, + const u8 *peer, enum nl80211_tdls_operation oper); +-void ieee80211_tdls_peer_del_work(struct work_struct *wk); ++void ieee80211_tdls_peer_del_work(struct wiphy *wiphy, struct wiphy_work *wk); + int ieee80211_tdls_channel_switch(struct wiphy *wiphy, struct net_device *dev, + const u8 *addr, u8 oper_class, + struct cfg80211_chan_def *chandef); +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -4890,8 +4890,8 @@ void ieee80211_sta_setup_sdata(struct ie + INIT_WORK(&ifmgd->csa_connection_drop_work, + ieee80211_csa_connection_drop_work); + INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_mgd_work); +- INIT_DELAYED_WORK(&ifmgd->tdls_peer_del_work, +- ieee80211_tdls_peer_del_work); ++ wiphy_delayed_work_init(&ifmgd->tdls_peer_del_work, ++ ieee80211_tdls_peer_del_work); + timer_setup(&ifmgd->timer, ieee80211_sta_timer, 0); + timer_setup(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, 0); + timer_setup(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, 0); +@@ -6010,7 +6010,8 @@ void ieee80211_mgd_stop(struct ieee80211 + cancel_work_sync(&ifmgd->request_smps_work); + cancel_work_sync(&ifmgd->csa_connection_drop_work); + cancel_work_sync(&ifmgd->chswitch_work); +- cancel_delayed_work_sync(&ifmgd->tdls_peer_del_work); ++ wiphy_delayed_work_cancel(sdata->local->hw.wiphy, ++ &ifmgd->tdls_peer_del_work); + + sdata_lock(sdata); + if (ifmgd->assoc_data) { +--- a/net/mac80211/tdls.c ++++ b/net/mac80211/tdls.c +@@ -21,7 +21,7 @@ + /* give usermode some time for retries in setting up the TDLS session */ + #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ) + +-void ieee80211_tdls_peer_del_work(struct work_struct *wk) ++void ieee80211_tdls_peer_del_work(struct wiphy *wiphy, struct wiphy_work *wk) + { + struct ieee80211_sub_if_data *sdata; + struct ieee80211_local *local; +@@ -1126,9 +1126,9 @@ ieee80211_tdls_mgmt_setup(struct wiphy * + return ret; + } + +- ieee80211_queue_delayed_work(&sdata->local->hw, +- &sdata->u.mgd.tdls_peer_del_work, +- TDLS_PEER_SETUP_TIMEOUT); ++ wiphy_delayed_work_queue(sdata->local->hw.wiphy, ++ &sdata->u.mgd.tdls_peer_del_work, ++ TDLS_PEER_SETUP_TIMEOUT); + return 0; + + out_unlock: +@@ -1425,7 +1425,8 @@ int ieee80211_tdls_oper(struct wiphy *wi + } + + if (ret == 0 && ether_addr_equal(sdata->u.mgd.tdls_peer, peer)) { +- cancel_delayed_work(&sdata->u.mgd.tdls_peer_del_work); ++ wiphy_delayed_work_cancel(sdata->local->hw.wiphy, ++ &sdata->u.mgd.tdls_peer_del_work); + eth_zero_addr(sdata->u.mgd.tdls_peer); + } + diff --git a/queue-5.15/wifi-mac80211-use-wiphy-work-for-sdata-work.patch b/queue-5.15/wifi-mac80211-use-wiphy-work-for-sdata-work.patch new file mode 100644 index 0000000000..e713193073 --- /dev/null +++ b/queue-5.15/wifi-mac80211-use-wiphy-work-for-sdata-work.patch @@ -0,0 +1,315 @@ +From stable+bounces-213089-greg=kroah.com@vger.kernel.org Mon Feb 2 17:55:29 2026 +From: "Hanne-Lotta Mäenpää" +Date: Mon, 2 Feb 2026 18:50:37 +0200 +Subject: wifi: mac80211: use wiphy work for sdata->work +To: stable@vger.kernel.org +Cc: johannes@sipsolutions.net, linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, "Johannes Berg" , "Hanne-Lotta Mäenpää" +Message-ID: <20260202165038.215693-2-hannelotta@gmail.com> + +From: Johannes Berg + +[ Upstream commit 16114496d684a3df4ce09f7c6b7557a8b2922795 ] + +We'll need this later to convert other works that might +be cancelled from here, so convert this one first. + +Signed-off-by: Johannes Berg +Signed-off-by: Hanne-Lotta Mäenpää +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/ibss.c | 8 ++++---- + net/mac80211/ieee80211_i.h | 2 +- + net/mac80211/iface.c | 10 +++++----- + net/mac80211/mesh.c | 10 +++++----- + net/mac80211/mesh_hwmp.c | 6 +++--- + net/mac80211/mlme.c | 6 +++--- + net/mac80211/ocb.c | 6 +++--- + net/mac80211/rx.c | 2 +- + net/mac80211/scan.c | 2 +- + net/mac80211/status.c | 5 +++-- + net/mac80211/util.c | 2 +- + 11 files changed, 30 insertions(+), 29 deletions(-) + +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -746,7 +746,7 @@ static void ieee80211_csa_connection_dro + skb_queue_purge(&sdata->skb_queue); + + /* trigger a scan to find another IBSS network to join */ +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + + sdata_unlock(sdata); + } +@@ -1245,7 +1245,7 @@ void ieee80211_ibss_rx_no_sta(struct iee + spin_lock(&ifibss->incomplete_lock); + list_add(&sta->list, &ifibss->incomplete_stations); + spin_unlock(&ifibss->incomplete_lock); +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata) +@@ -1726,7 +1726,7 @@ static void ieee80211_ibss_timer(struct + struct ieee80211_sub_if_data *sdata = + from_timer(sdata, t, u.ibss.timer); + +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata) +@@ -1861,7 +1861,7 @@ int ieee80211_ibss_join(struct ieee80211 + sdata->needed_rx_chains = local->rx_chains; + sdata->control_port_over_nl80211 = params->control_port_over_nl80211; + +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + + return 0; + } +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -966,7 +966,7 @@ struct ieee80211_sub_if_data { + /* used to reconfigure hardware SM PS */ + struct work_struct recalc_smps; + +- struct work_struct work; ++ struct wiphy_work work; + struct sk_buff_head skb_queue; + struct sk_buff_head status_queue; + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -43,7 +43,7 @@ + * by either the RTNL, the iflist_mtx or RCU. + */ + +-static void ieee80211_iface_work(struct work_struct *work); ++static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work); + + bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) + { +@@ -539,7 +539,7 @@ static void ieee80211_do_stop(struct iee + RCU_INIT_POINTER(local->p2p_sdata, NULL); + fallthrough; + default: +- cancel_work_sync(&sdata->work); ++ wiphy_work_cancel(sdata->local->hw.wiphy, &sdata->work); + /* + * When we get here, the interface is marked down. + * Free the remaining keys, if there are any +@@ -1005,7 +1005,7 @@ int ieee80211_add_virtual_monitor(struct + + skb_queue_head_init(&sdata->skb_queue); + skb_queue_head_init(&sdata->status_queue); +- INIT_WORK(&sdata->work, ieee80211_iface_work); ++ wiphy_work_init(&sdata->work, ieee80211_iface_work); + + return 0; + } +@@ -1487,7 +1487,7 @@ static void ieee80211_iface_process_stat + } + } + +-static void ieee80211_iface_work(struct work_struct *work) ++static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work) + { + struct ieee80211_sub_if_data *sdata = + container_of(work, struct ieee80211_sub_if_data, work); +@@ -1590,7 +1590,7 @@ static void ieee80211_setup_sdata(struct + + skb_queue_head_init(&sdata->skb_queue); + skb_queue_head_init(&sdata->status_queue); +- INIT_WORK(&sdata->work, ieee80211_iface_work); ++ wiphy_work_init(&sdata->work, ieee80211_iface_work); + INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work); + INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work); + INIT_WORK(&sdata->color_change_finalize_work, ieee80211_color_change_finalize_work); +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -44,7 +44,7 @@ static void ieee80211_mesh_housekeeping_ + + set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); + +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + /** +@@ -642,7 +642,7 @@ static void ieee80211_mesh_path_timer(st + struct ieee80211_sub_if_data *sdata = + from_timer(sdata, t, u.mesh.mesh_path_timer); + +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + static void ieee80211_mesh_path_root_timer(struct timer_list *t) +@@ -653,7 +653,7 @@ static void ieee80211_mesh_path_root_tim + + set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); + +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) +@@ -1018,7 +1018,7 @@ void ieee80211_mbss_info_change_notify(s + for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE) + set_bit(bit, &ifmsh->mbss_changed); + set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags); +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) +@@ -1043,7 +1043,7 @@ int ieee80211_start_mesh(struct ieee8021 + ifmsh->sync_offset_clockdrift_max = 0; + set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); + ieee80211_mesh_root_setup(ifmsh); +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + sdata->vif.bss_conf.ht_operation_mode = + ifmsh->mshcfg.ht_opmode; + sdata->vif.bss_conf.enable_beacon = true; +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (c) 2008, 2009 open80211s Ltd. +- * Copyright (C) 2019, 2021 Intel Corporation ++ * Copyright (C) 2019, 2021-2023 Intel Corporation + * Author: Luis Carlos Cobo + */ + +@@ -1020,14 +1020,14 @@ static void mesh_queue_preq(struct mesh_ + spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); + + if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata))) +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + + else if (time_before(jiffies, ifmsh->last_preq)) { + /* avoid long wait if did not send preqs for a long time + * and jiffies wrapped around + */ + ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } else + mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq + + min_preq_int_jiff(sdata)); +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2509,7 +2509,7 @@ void ieee80211_sta_tx_notify(struct ieee + sdata->u.mgd.probe_send_count = 0; + else + sdata->u.mgd.nullfunc_failed = true; +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + static void ieee80211_mlme_send_probe_req(struct ieee80211_sub_if_data *sdata, +@@ -4415,7 +4415,7 @@ static void ieee80211_sta_timer(struct t + struct ieee80211_sub_if_data *sdata = + from_timer(sdata, t, u.mgd.timer); + +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, +@@ -4559,7 +4559,7 @@ void ieee80211_mgd_conn_tx_status(struct + sdata->u.mgd.status_acked = acked; + sdata->u.mgd.status_received = true; + +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) +--- a/net/mac80211/ocb.c ++++ b/net/mac80211/ocb.c +@@ -80,7 +80,7 @@ void ieee80211_ocb_rx_no_sta(struct ieee + spin_lock(&ifocb->incomplete_lock); + list_add(&sta->list, &ifocb->incomplete_stations); + spin_unlock(&ifocb->incomplete_lock); +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta) +@@ -156,7 +156,7 @@ static void ieee80211_ocb_housekeeping_t + + set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags); + +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata) +@@ -196,7 +196,7 @@ int ieee80211_ocb_join(struct ieee80211_ + ifocb->joined = true; + + set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags); +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + + netif_carrier_on(sdata->dev); + return 0; +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -219,7 +219,7 @@ static void __ieee80211_queue_skb_to_ifa + struct sk_buff *skb) + { + skb_queue_tail(&sdata->skb_queue, skb); +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + if (sta) + sta->rx_stats.packets++; + } +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -498,7 +498,7 @@ static void __ieee80211_scan_completed(s + */ + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (ieee80211_sdata_running(sdata)) +- ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++ wiphy_work_queue(sdata->local->hw.wiphy, &sdata->work); + } + + if (was_scanning) +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -5,6 +5,7 @@ + * Copyright 2006-2007 Jiri Benc + * Copyright 2008-2010 Johannes Berg + * Copyright 2013-2014 Intel Mobile Communications GmbH ++ * Copyright 2021-2023 Intel Corporation + */ + + #include +@@ -716,8 +717,8 @@ static void ieee80211_report_used_skb(st + if (qskb) { + skb_queue_tail(&sdata->status_queue, + qskb); +- ieee80211_queue_work(&local->hw, +- &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, ++ &sdata->work); + } + } + } else { +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -2679,7 +2679,7 @@ int ieee80211_reconfig(struct ieee80211_ + + /* Requeue all works */ + list_for_each_entry(sdata, &local->interfaces, list) +- ieee80211_queue_work(&local->hw, &sdata->work); ++ wiphy_work_queue(local->hw.wiphy, &sdata->work); + } + + ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, diff --git a/queue-5.15/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch b/queue-5.15/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch new file mode 100644 index 0000000000..14d246b172 --- /dev/null +++ b/queue-5.15/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch @@ -0,0 +1,85 @@ +From stable+bounces-210651-greg=kroah.com@vger.kernel.org Wed Jan 21 03:36:52 2026 +From: Sasha Levin +Date: Tue, 20 Jan 2026 21:35:45 -0500 +Subject: xfs: set max_agbno to allow sparse alloc of last full inode chunk +To: stable@vger.kernel.org +Cc: Brian Foster , "Darrick J. Wong" , Carlos Maiolino , Sasha Levin +Message-ID: <20260121023545.1132446-1-sashal@kernel.org> + +From: Brian Foster + +[ Upstream commit c360004c0160dbe345870f59f24595519008926f ] + +Sparse inode cluster allocation sets min/max agbno values to avoid +allocating an inode cluster that might map to an invalid inode +chunk. For example, we can't have an inode record mapped to agbno 0 +or that extends past the end of a runt AG of misaligned size. + +The initial calculation of max_agbno is unnecessarily conservative, +however. This has triggered a corner case allocation failure where a +small runt AG (i.e. 2063 blocks) is mostly full save for an extent +to the EOFS boundary: [2050,13]. max_agbno is set to 2048 in this +case, which happens to be the offset of the last possible valid +inode chunk in the AG. In practice, we should be able to allocate +the 4-block cluster at agbno 2052 to map to the parent inode record +at agbno 2048, but the max_agbno value precludes it. + +Note that this can result in filesystem shutdown via dirty trans +cancel on stable kernels prior to commit 9eb775968b68 ("xfs: walk +all AGs if TRYLOCK passed to xfs_alloc_vextent_iterate_ags") because +the tail AG selection by the allocator sets t_highest_agno on the +transaction. If the inode allocator spins around and finds an inode +chunk with free inodes in an earlier AG, the subsequent dir name +creation path may still fail to allocate due to the AG restriction +and cancel. + +To avoid this problem, update the max_agbno calculation to the agbno +prior to the last chunk aligned agbno in the AG. This is not +necessarily the last valid allocation target for a sparse chunk, but +since inode chunks (i.e. records) are chunk aligned and sparse +allocs are cluster sized/aligned, this allows the sb_spino_align +alignment restriction to take over and round down the max effective +agbno to within the last valid inode chunk in the AG. + +Note that even though the allocator improvements in the +aforementioned commit seem to avoid this particular dirty trans +cancel situation, the max_agbno logic improvement still applies as +we should be able to allocate from an AG that has been appropriately +selected. The more important target for this patch however are +older/stable kernels prior to this allocator rework/improvement. + +Cc: stable@vger.kernel.org # v4.2 +Fixes: 56d1115c9bc7 ("xfs: allocate sparse inode chunks on full chunk allocation failure") +Signed-off-by: Brian Foster +Reviewed-by: Darrick J. Wong +Signed-off-by: Carlos Maiolino +[ xfs_ag_block_count(args.mp, pag_agno(pag)) => args.mp->m_sb.sb_agblocks ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/libxfs/xfs_ialloc.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/fs/xfs/libxfs/xfs_ialloc.c ++++ b/fs/xfs/libxfs/xfs_ialloc.c +@@ -772,14 +772,15 @@ sparse_alloc: + * invalid inode records, such as records that start at agbno 0 + * or extend beyond the AG. + * +- * Set min agbno to the first aligned, non-zero agbno and max to +- * the last aligned agbno that is at least one full chunk from +- * the end of the AG. ++ * Set min agbno to the first chunk aligned, non-zero agbno and ++ * max to one less than the last chunk aligned agbno from the ++ * end of the AG. We subtract 1 from max so that the cluster ++ * allocation alignment takes over and allows allocation within ++ * the last full inode chunk in the AG. + */ + args.min_agbno = args.mp->m_sb.sb_inoalignmt; + args.max_agbno = round_down(args.mp->m_sb.sb_agblocks, +- args.mp->m_sb.sb_inoalignmt) - +- igeo->ialloc_blks; ++ args.mp->m_sb.sb_inoalignmt) - 1; + + error = xfs_alloc_vextent(&args); + if (error) -- 2.47.3