]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Feb 2026 16:29:20 +0000 (17:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 3 Feb 2026 16:29:20 +0000 (17:29 +0100)
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

39 files changed:
queue-5.15/alsa-scarlett2-fix-buffer-overflow-in-config-retrieval.patch [new file with mode: 0644]
queue-5.15/arm64-dts-rockchip-remove-redundant-max-link-speed-from-nanopi-r4s.patch [new file with mode: 0644]
queue-5.15/blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-blkcg_reset_stats.patch [new file with mode: 0644]
queue-5.15/bluetooth-fix-hci_suspend_sync-crash.patch [new file with mode: 0644]
queue-5.15/can-esd_usb-esd_usb_read_bulk_callback-fix-urb-memory-leak.patch [new file with mode: 0644]
queue-5.15/comedi-fix-getting-range-information-for-subdevices-16-to-255.patch [new file with mode: 0644]
queue-5.15/dmaengine-stm32-dmamux-fix-device-leak-on-route-allocation.patch [new file with mode: 0644]
queue-5.15/dmaengine-stm32-dmamux-fix-of-node-leak-on-route-allocation-failure.patch [new file with mode: 0644]
queue-5.15/drm-amdkfd-fix-a-memory-leak-in-device_queue_manager_init.patch [new file with mode: 0644]
queue-5.15/drm-ttm-fix-undefined-behavior-in-bit-shift-for-ttm_tt_flag_priv_populated.patch [new file with mode: 0644]
queue-5.15/espintcp-fix-skb-leaks.patch [new file with mode: 0644]
queue-5.15/ext4-fix-memory-leaks-in-ext4_fname_-setup_filename-prepare_lookup.patch [new file with mode: 0644]
queue-5.15/fs-ntfs3-initialize-allocated-memory-before-use.patch [new file with mode: 0644]
queue-5.15/genirq-irq_sim-initialize-work-context-pointers-properly.patch [new file with mode: 0644]
queue-5.15/hid-uclogic-add-null-check-in-uclogic_input_configured.patch [new file with mode: 0644]
queue-5.15/hid-uclogic-correct-devm-device-reference-for-hidinput-input_dev-name.patch [new file with mode: 0644]
queue-5.15/iio-adc-exynos_adc-fix-of-populate-on-driver-rebind.patch [new file with mode: 0644]
queue-5.15/ksm-use-range-walk-function-to-jump-over-holes-in-scan_get_next_rmap_item.patch [new file with mode: 0644]
queue-5.15/ksmbd-fix-use-after-free-in-ksmbd_tree_connect_put-under-concurrency.patch [new file with mode: 0644]
queue-5.15/ksmbd-smbd-fix-dma_unmap_sg-nents.patch [new file with mode: 0644]
queue-5.15/mei-trace-treat-reg-parameter-as-string.patch [new file with mode: 0644]
queue-5.15/mm-pagewalk-add-walk_page_range_vma.patch [new file with mode: 0644]
queue-5.15/net-add-locking-to-protect-skb-dev-access-in-ip_output.patch [new file with mode: 0644]
queue-5.15/net-stmmac-make-sure-that-ptp_rate-is-not-0-before-configuring-est.patch [new file with mode: 0644]
queue-5.15/nfsd-fix-race-between-nfsd-registration-and-exports_proc.patch [new file with mode: 0644]
queue-5.15/nvme-fc-rename-free_ctrl-callback-to-match-name-pattern.patch [new file with mode: 0644]
queue-5.15/nvme-fix-pcie-subsystem-reset-controller-state-transition.patch [new file with mode: 0644]
queue-5.15/nvme-pci-do-not-directly-handle-subsys-reset-fallout.patch [new file with mode: 0644]
queue-5.15/of-platform-use-default-match-table-for-firmware.patch [new file with mode: 0644]
queue-5.15/scsi-xen-scsiback-fix-potential-memory-leak-in-scsiback_remove.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/tls-use-__sk_dst_get-and-dst_dev_rcu-in-get_netdev_for_sock.patch [new file with mode: 0644]
queue-5.15/usbnet-fix-using-smp_processor_id-in-preemptible-code-warnings.patch [new file with mode: 0644]
queue-5.15/w1-therm-fix-off-by-one-buffer-overflow-in-alarms_store.patch [new file with mode: 0644]
queue-5.15/w1-w1_therm-use-swap-to-make-code-cleaner.patch [new file with mode: 0644]
queue-5.15/wifi-cfg80211-add-a-work-abstraction-with-special-semantics.patch [new file with mode: 0644]
queue-5.15/wifi-mac80211-move-tdls-work-to-wiphy-work.patch [new file with mode: 0644]
queue-5.15/wifi-mac80211-use-wiphy-work-for-sdata-work.patch [new file with mode: 0644]
queue-5.15/xfs-set-max_agbno-to-allow-sparse-alloc-of-last-full-inode-chunk.patch [new file with mode: 0644]

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 (file)
index 0000000..9d9e168
--- /dev/null
@@ -0,0 +1,57 @@
+From stable+bounces-212648-greg=kroah.com@vger.kernel.org Wed Jan 28 18:46:33 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <samasth.norway.ananda@oracle.com>, Takashi Iwai <tiwai@suse.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260128174220.2597086-1-sashal@kernel.org>
+
+From: Samasth Norway Ananda <samasth.norway.ananda@oracle.com>
+
+[ 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 <samasth.norway.ananda@oracle.com>
+Link: https://patch.msgid.link/20260117012706.1715574-1-samasth.norway.ananda@oracle.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+[ add 32-bit handling block ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..49796bc
--- /dev/null
@@ -0,0 +1,40 @@
+From stable+bounces-211650-greg=kroah.com@vger.kernel.org Mon Jan 26 17:35:37 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <geraldogabriel@gmail.com>, Dragan Simic <dsimic@manjaro.org>, Shawn Lin <shawn.lin@rock-chips.com>, Heiko Stuebner <heiko@sntech.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260126163526.3391456-1-sashal@kernel.org>
+
+From: Geraldo Nascimento <geraldogabriel@gmail.com>
+
+[ 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 <dsimic@manjaro.org>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Signed-off-by: Geraldo Nascimento <geraldogabriel@gmail.com>
+Acked-by: Shawn Lin <shawn.lin@rock-chips.com>
+Link: https://patch.msgid.link/6694456a735844177c897581f785cc00c064c7d1.1763415706.git.geraldogabriel@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+[ adapted file path from rk3399-nanopi-r4s.dtsi to rk3399-nanopi-r4s.dts ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..012c83e
--- /dev/null
@@ -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 <longman@redhat.com>, Ming Lei <ming.lei@redhat.com>, Tejun Heo <tj@kernel.org>, Jens Axboe <axboe@kernel.dk>, Alva Lan <alvalan9@foxmail.com>
+Message-ID: <tencent_9C6AFE3E9A2583AC3971A061001BDA681309@qq.com>
+
+From: Waiman Long <longman@redhat.com>
+
+[ 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 <longman@redhat.com>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Link: https://lore.kernel.org/r/20230606180724.2455066-1-longman@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+[ 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 <alvalan9@foxmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..3793042
--- /dev/null
@@ -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 <yinghsu@chromium.org>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Wenshan Lan <jetlan9@163.com>
+Message-ID: <20260202104857.4134-1-jetlan9@163.com>
+
+From: Ying Hsu <yinghsu@chromium.org>
+
+[ 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 <yinghsu@chromium.org>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+[ Adjust context ]
+Signed-off-by: Wenshan Lan <jetlan9@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..454f705
--- /dev/null
@@ -0,0 +1,59 @@
+From 5a4391bdc6c8357242f62f22069c865b792406b3 Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+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 <mkl@pengutronix.de>
+
+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 <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..057d927
--- /dev/null
@@ -0,0 +1,100 @@
+From 10d28cffb3f6ec7ad67f0a4cd32c2afa92909452 Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Wed, 3 Dec 2025 16:24:38 +0000
+Subject: comedi: Fix getting range information for subdevices 16 to 255
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+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 <abbotti@mev.co.uk>
+Link: https://patch.msgid.link/20251203162438.176841-1-abbotti@mev.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..f4c8562
--- /dev/null
@@ -0,0 +1,91 @@
+From stable+bounces-210741-greg=kroah.com@vger.kernel.org Wed Jan 21 13:27:37 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <johan@kernel.org>, Pierre-Yves MORDRET <pierre-yves.mordret@foss.st.com>, Amelie Delaunay <amelie.delaunay@foss.st.com>, Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260121122442.1527792-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ 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 <pierre-yves.mordret@foss.st.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Reviewed-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
+Link: https://patch.msgid.link/20251117161258.10679-11-johan@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..ba59e97
--- /dev/null
@@ -0,0 +1,48 @@
+From stable+bounces-210744-greg=kroah.com@vger.kernel.org Wed Jan 21 13:34:54 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <johan@kernel.org>, Pierre-Yves MORDRET <pierre-yves.mordret@foss.st.com>, Amelie Delaunay <amelie.delaunay@foss.st.com>, Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260121122954.1531423-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ 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 <pierre-yves.mordret@foss.st.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Reviewed-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
+Link: https://patch.msgid.link/20251117161258.10679-12-johan@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..386b01a
--- /dev/null
@@ -0,0 +1,67 @@
+From 80614c509810fc051312d1a7ccac8d0012d6b8d0 Mon Sep 17 00:00:00 2001
+From: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
+Date: Thu, 8 Jan 2026 15:18:22 +0800
+Subject: drm/amdkfd: fix a memory leak in device_queue_manager_init()
+
+From: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
+
+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 <lihaoxiang@isrc.iscas.ac.cn>
+Signed-off-by: Felix Kuehling <felix.kuehling@amd.com>
+Reviewed-by: Oak Zeng <Oak.Zeng@amd.com>
+Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit b7cccc8286bb9919a0952c812872da1dcfe9d390)
+Cc: stable@vger.kernel.org
+Signed-off-by: Felix Kuehling <felix.kuehling@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..2da46bb
--- /dev/null
@@ -0,0 +1,100 @@
+From stable+bounces-209987-greg=kroah.com@vger.kernel.org Fri Jan 16 06:02:39 2026
+From: Rahul Sharma <black.hawk@163.com>
+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" <cuigaosheng1@huawei.com>, "Christian König" <christian.koenig@amd.com>, "Rahul Sharma" <black.hawk@163.com>
+Message-ID: <20260116050205.2296956-1-black.hawk@163.com>
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ 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:
+ <TASK>
+ 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
+ </TASK>
+
+Fixes: 3312be8f6fc8 ("drm/ttm: move populated state into page flags")
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221031113350.4180975-1-cuigaosheng1@huawei.com
+Signed-off-by: Christian König <christian.koenig@amd.com>
+[ 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 <black.hawk@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..3189d60
--- /dev/null
@@ -0,0 +1,69 @@
+From stable+bounces-211954-greg=kroah.com@vger.kernel.org Wed Jan 28 12:07:12 2026
+From: Bin Lan <lanbincn@139.com>
+Date: Wed, 28 Jan 2026 11:06:35 +0000
+Subject: espintcp: fix skb leaks
+To: stable@vger.kernel.org
+Cc: Sabrina Dubroca <sd@queasysnail.net>, Simon Horman <horms@kernel.org>, Steffen Klassert <steffen.klassert@secunet.com>, Bin Lan <lanbincn@139.com>
+Message-ID: <20260128110635.4109-1-lanbincn@139.com>
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+[ Upstream commit 63c1f19a3be3169e51a5812d22a6d0c879414076 ]
+
+A few error paths are missing a kfree_skb.
+
+Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+[ Minor context change fixed. ]
+Signed-off-by: Bin Lan <lanbincn@139.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..2dc8748
--- /dev/null
@@ -0,0 +1,99 @@
+From stable+bounces-211955-greg=kroah.com@vger.kernel.org Wed Jan 28 12:08:03 2026
+From: Bin Lan <lanbincn@139.com>
+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" <lhenriques@suse.de>, stable@kernel.org, "Eric Biggers" <ebiggers@google.com>, "Theodore Ts'o" <tytso@mit.edu>, "Bin Lan" <lanbincn@139.com>
+Message-ID: <20260128110720.4134-1-lanbincn@139.com>
+
+From: Luís Henriques <lhenriques@suse.de>
+
+[ 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 <lhenriques@suse.de>
+Reviewed-by: Eric Biggers <ebiggers@google.com>
+Link: https://lore.kernel.org/r/20230803091713.13239-1-lhenriques@suse.de
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[ 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 <lanbincn@139.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..dbf7fb4
--- /dev/null
@@ -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 <kubik.bartlomiej@gmail.com>
+
+[ 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 <khalid@kernel.org>
+Signed-off-by: Bartlomiej Kubik <kubik.bartlomiej@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..aa6ff95
--- /dev/null
@@ -0,0 +1,39 @@
+From black.hawk@163.com Tue Feb  3 03:07:43 2026
+From: Rahul Sharma <black.hawk@163.com>
+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 <gye976@gmail.com>, Thomas Gleixner <tglx@linutronix.de>, Rahul Sharma <black.hawk@163.com>
+Message-ID: <20260203020714.799655-1-black.hawk@163.com>
+
+From: Gyeyoung Baek <gye976@gmail.com>
+
+[ 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 <gye976@gmail.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+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 <black.hawk@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..c4d2b84
--- /dev/null
@@ -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 <bsdhenrymartin@gmail.com>, Jiri Kosina <jkosina@suse.com>, Wenshan Lan <jetlan9@163.com>
+Message-ID: <20260203012144.4215-2-jetlan9@163.com>
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ 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 <bsdhenrymartin@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+[ Adjust context ]
+Signed-off-by: Wenshan Lan <jetlan9@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..da1f8a3
--- /dev/null
@@ -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 <sergeantsagara@protonmail.com>, syzbot+3a0ebe8a52b89c63739d@syzkaller.appspotmail.com, Maxime Ripard <mripard@kernel.org>, Dmitry Torokhov <dmitry.torokhov@gmail.com>, Benjamin Tissoires <bentiss@kernel.org>, Wenshan Lan <jetlan9@163.com>
+Message-ID: <20260203012144.4215-1-jetlan9@163.com>
+
+From: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+
+[ 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 <mripard@kernel.org>
+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 <mripard@kernel.org>
+Suggested-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Rahul Rameshbabu <sergeantsagara@protonmail.com>
+Reviewed-by: Maxime Ripard <mripard@kernel.org>
+Link: https://lore.kernel.org/r/20230824061308.222021-2-sergeantsagara@protonmail.com
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+[ Adjust context ]
+Signed-off-by: Wenshan Lan <jetlan9@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..633b200
--- /dev/null
@@ -0,0 +1,69 @@
+From stable+bounces-211906-greg=kroah.com@vger.kernel.org Wed Jan 28 01:56:51 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <johan@kernel.org>, Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260128005645.2300956-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ 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 <johan@kernel.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+[ Adjust context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..4eef2bc
--- /dev/null
@@ -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 <pedrodemargomes@gmail.com>
+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 <pedrodemargomes@gmail.com>, David Hildenbrand <david@redhat.com>, craftfever <craftfever@airmail.cc>, Chengming Zhou <chengming.zhou@linux.dev>, xu xin <xu.xin16@zte.com.cn>, Andrew Morton <akpm@linux-foundation.org>
+Message-ID: <20260116171914.298018-2-pedrodemargomes@gmail.com>
+
+From: Pedro Demarchi Gomes <pedrodemargomes@gmail.com>
+
+[ 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 <pedrodemargomes@gmail.com>
+Co-developed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Reported-by: craftfever <craftfever@airmail.cc>
+Closes: https://lkml.kernel.org/r/020cf8de6e773bb78ba7614ef250129f11a63781@murena.io
+Suggested-by: David Hildenbrand <david@redhat.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Cc: Chengming Zhou <chengming.zhou@linux.dev>
+Cc: xu xin <xu.xin16@zte.com.cn>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ 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 <pedrodemargomes@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/ksm.c |  115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 105 insertions(+), 10 deletions(-)
+
+--- a/mm/ksm.c
++++ b/mm/ksm.c
+@@ -38,6 +38,7 @@
+ #include <linux/freezer.h>
+ #include <linux/oom.h>
+ #include <linux/numa.h>
++#include <linux/pagewalk.h>
+ #include <asm/tlbflush.h>
+ #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 (file)
index 0000000..bf24407
--- /dev/null
@@ -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 <linkinjeon@kernel.org>
+
+[ 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 <pioooooooooip@gmail.com>
+Reported-by: Zhitong Liu <liuzhitong1993@gmail.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Rajani Kantha <681739313@139.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..8150786
--- /dev/null
@@ -0,0 +1,72 @@
+From stable+bounces-212705-greg=kroah.com@vger.kernel.org Wed Jan 28 23:43:18 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <fourier.thomas@gmail.com>, Namjae Jeon <linkinjeon@kernel.org>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260128224022.2810098-1-sashal@kernel.org>
+
+From: Thomas Fourier <fourier.thomas@gmail.com>
+
+[ 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: <stable@vger.kernel.org>
+Signed-off-by: Thomas Fourier <fourier.thomas@gmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+[ Context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..cb0a4ec
--- /dev/null
@@ -0,0 +1,104 @@
+From stable+bounces-212704-greg=kroah.com@vger.kernel.org Wed Jan 28 23:43:15 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <alexander.usyskin@intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260128224019.2809980-1-sashal@kernel.org>
+
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+
+[ 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 <alexander.usyskin@intel.com>
+Link: https://patch.msgid.link/20260111145125.1754912-1-alexander.usyskin@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ adapted __assign_str() calls to use two arguments ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..996609a
--- /dev/null
@@ -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 <pedrodemargomes@gmail.com>
+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 <david@redhat.com>, Andrea Arcangeli <aarcange@redhat.com>, Hugh Dickins <hughd@google.com>, Jason Gunthorpe <jgg@nvidia.com>, John Hubbard <jhubbard@nvidia.com>, Matthew Wilcox <willy@infradead.org>, Peter Xu <peterx@redhat.com>, Shuah Khan <shuah@kernel.org>, Vlastimil Babka <vbabka@suse.cz>, Andrew Morton <akpm@linux-foundation.org>, Pedro Demarchi Gomes <pedrodemargomes@gmail.com>
+Message-ID: <20260116171914.298018-1-pedrodemargomes@gmail.com>
+
+From: David Hildenbrand <david@redhat.com>
+
+[ 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 <david@redhat.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Jason Gunthorpe <jgg@nvidia.com>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+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 <pedrodemargomes@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..d61543c
--- /dev/null
@@ -0,0 +1,116 @@
+From 1dbf1d590d10a6d1978e8184f8dfe20af22d680a Mon Sep 17 00:00:00 2001
+From: Sharath Chandra Vurukala <quic_sharathv@quicinc.com>
+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 <quic_sharathv@quicinc.com>
+
+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 <quic_sharathv@quicinc.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250730105118.GA26100@hu-sharathv-hyd.qualcomm.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Keerthana: Backported the patch to v5.15-v6.1 ]
+Signed-off-by: Keerthana K <keerthana.kalyanasundaram@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..6a37f35
--- /dev/null
@@ -0,0 +1,62 @@
+From stable+bounces-212844-greg=kroah.com@vger.kernel.org Fri Jan 30 07:55:07 2026
+From: Rahul Sharma <black.hawk@163.com>
+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é" <alexis.lothore@bootlin.com>, "Maxime Chevallier" <maxime.chevallier@bootlin.com>, "Jakub Kicinski" <kuba@kernel.org>, "Rahul Sharma" <black.hawk@163.com>
+Message-ID: <20260130065423.3362339-1-black.hawk@163.com>
+
+From: Alexis Lothoré <alexis.lothore@bootlin.com>
+
+[ 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 <maxime.chevallier@bootlin.com>
+Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
+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 <kuba@kernel.org>
+[ 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 <black.hawk@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..316b7e8
--- /dev/null
@@ -0,0 +1,169 @@
+From stable+bounces-212725-greg=kroah.com@vger.kernel.org Thu Jan 29 03:24:25 2026
+From: Rahul Sharma <black.hawk@163.com>
+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 <maninder1.s@samsung.com>, Shubham Rana <s9.rana@samsung.com>, Jeff Layton <jlayton@kernel.org>, Chuck Lever <chuck.lever@oracle.com>, Rahul Sharma <black.hawk@163.com>
+Message-ID: <20260129022304.1232425-1-black.hawk@163.com>
+
+From: Maninder Singh <maninder1.s@samsung.com>
+
+[ 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 <s9.rana@samsung.com>
+Signed-off-by: Shubham Rana <s9.rana@samsung.com>
+Signed-off-by: Maninder Singh <maninder1.s@samsung.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ 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 <black.hawk@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..6439759
--- /dev/null
@@ -0,0 +1,47 @@
+From stable+bounces-210666-greg=kroah.com@vger.kernel.org Wed Jan 21 04:02:48 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <dwagner@suse.de>, Christoph Hellwig <hch@lst.de>, Sagi Grimberg <sagi@grimberg.me>, Hannes Reinecke <hare@suse.de>, Keith Busch <kbusch@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260121030238.1163180-1-sashal@kernel.org>
+
+From: Daniel Wagner <dwagner@suse.de>
+
+[ 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 <hch@lst.de>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Daniel Wagner <dwagner@suse.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..e3ecefa
--- /dev/null
@@ -0,0 +1,58 @@
+From stable+bounces-210668-greg=kroah.com@vger.kernel.org Wed Jan 21 04:02:53 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <nilay@linux.ibm.com>, Daniel Wagner <dwagner@suse.de>, Keith Busch <kbusch@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260121030238.1163180-3-sashal@kernel.org>
+
+From: Nilay Shroff <nilay@linux.ibm.com>
+
+[ 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 <dwagner@suse.de>
+Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..c32b394
--- /dev/null
@@ -0,0 +1,205 @@
+From stable+bounces-210667-greg=kroah.com@vger.kernel.org Wed Jan 21 04:02:48 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <kbusch@kernel.org>, Nilay Shroff <nilay@linux.ibm.com>, Christoph Hellwig <hch@lst.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260121030238.1163180-2-sashal@kernel.org>
+
+From: Keith Busch <kbusch@kernel.org>
+
+[ 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 <nilay@linux.ibm.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..2d1f9d6
--- /dev/null
@@ -0,0 +1,40 @@
+From 48e6a9c4a20870e09f85ff1a3628275d6bce31c0 Mon Sep 17 00:00:00 2001
+From: "Rob Herring (Arm)" <robh@kernel.org>
+Date: Tue, 13 Jan 2026 19:51:58 -0600
+Subject: of: platform: Use default match table for /firmware
+
+From: Rob Herring (Arm) <robh@kernel.org>
+
+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 <sudeep.holla@arm.com>
+Link: https://patch.msgid.link/20260114015158.692170-2-robh@kernel.org
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..5828f99
--- /dev/null
@@ -0,0 +1,40 @@
+From stable+bounces-211667-greg=kroah.com@vger.kernel.org Mon Jan 26 18:42:22 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <nihaal@cse.iitm.ac.in>, Juergen Gross <jgross@suse.com>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260126174212.3433842-1-sashal@kernel.org>
+
+From: Abdun Nihaal <nihaal@cse.iitm.ac.in>
+
+[ 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 <nihaal@cse.iitm.ac.in>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://patch.msgid.link/20251223063012.119035-1-nihaal@cse.iitm.ac.in
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+[ adapted void scsiback_remove() to int return type with return 0 statement ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
index d3a91d4e23c51273b4123a66ce2cd6433829e832..b2a60c83b3d12439719d074c89165e1eefd03c7d 100644 (file)
@@ -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 (file)
index 0000000..9260c14
--- /dev/null
@@ -0,0 +1,62 @@
+From c65f27b9c3be2269918e1cbad6d8884741f835c5 Mon Sep 17 00:00:00 2001
+From: Kuniyuki Iwashima <kuniyu@google.com>
+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 <kuniyu@google.com>
+
+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 <kuniyu@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Link: https://patch.msgid.link/20250916214758.650211-6-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Keerthana: Backport to v5.15-v6.1 ]
+Signed-off-by: Keerthana K <keerthana.kalyanasundaram@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..fe2bd60
--- /dev/null
@@ -0,0 +1,78 @@
+From stable+bounces-212825-greg=kroah.com@vger.kernel.org Fri Jan 30 02:09:12 2026
+From: Rahul Sharma <black.hawk@163.com>
+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 <qiang.zhang@linux.dev>, Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Rahul Sharma <black.hawk@163.com>
+Message-ID: <20260130010751.2982401-1-black.hawk@163.com>
+
+From: Zqiang <qiang.zhang@linux.dev>
+
+[ 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:
+ <TASK>
+ __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 <kuba@kernel.org>
+Signed-off-by: Zqiang <qiang.zhang@linux.dev>
+Link: https://patch.msgid.link/20251011070518.7095-1-qiang.zhang@linux.dev
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+[ 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 <black.hawk@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..d46043a
--- /dev/null
@@ -0,0 +1,136 @@
+From stable+bounces-211640-greg=kroah.com@vger.kernel.org Mon Jan 26 16:51:36 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <thorsten.blum@linux.dev>, Krzysztof Kozlowski <krzk@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260126155057.3322542-2-sashal@kernel.org>
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ 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 <thorsten.blum@linux.dev>
+Link: https://patch.msgid.link/20251216145007.44328-2-thorsten.blum@linux.dev
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..b63eadb
--- /dev/null
@@ -0,0 +1,50 @@
+From stable+bounces-211639-greg=kroah.com@vger.kernel.org Mon Jan 26 16:51:33 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <yang.guang5@zte.com.cn>, Zeal Robot <zealci@zte.com.cn>, David Yang <davidcomponentone@gmail.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260126155057.3322542-1-sashal@kernel.org>
+
+From: Yang Guang <yang.guang5@zte.com.cn>
+
+[ Upstream commit e233897b1f7a859092bd20b10bfd412013381a10 ]
+
+Use the macro 'swap()' defined in 'include/linux/minmax.h' to avoid
+opencoding it.
+
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: David Yang <davidcomponentone@gmail.com>
+Signed-off-by: Yang Guang <yang.guang5@zte.com.cn>
+Link: https://lore.kernel.org/r/cb14f9e6e86cf8494ed2ddce6eec8ebd988908d9.1640077704.git.yang.guang5@zte.com.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 761fcf46a1bd ("w1: therm: Fix off-by-one buffer overflow in alarms_store")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..780d30a
--- /dev/null
@@ -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ää" <hannelotta@gmail.com>
+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" <johannes.berg@intel.com>, "Hanne-Lotta Mäenpää" <hannelotta@gmail.com>
+Message-ID: <20260202165038.215693-1-hannelotta@gmail.com>
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ 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 <johannes.berg@intel.com>
+Signed-off-by: Hanne-Lotta Mäenpää <hannelotta@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <jbenc@suse.cz>
+  * Copyright 2006     Johannes Berg <johannes@sipsolutions.net>
+- * Copyright (C) 2020-2021 Intel Corporation
++ * Copyright (C) 2020-2021, 2023 Intel Corporation
+  */
+ #include <linux/device.h>
+@@ -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 (file)
index 0000000..a957e45
--- /dev/null
@@ -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ää" <hannelotta@gmail.com>
+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" <johannes.berg@intel.com>, "Emmanuel Grumbach" <emmanuel.grumbach@intel.com>, "Hanne-Lotta Mäenpää" <hannelotta@gmail.com>
+Message-ID: <20260202165038.215693-3-hannelotta@gmail.com>
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 777b26002b73127e81643d9286fadf3d41e0e477 ]
+
+Again, to have the wiphy locked for it.
+
+Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[ 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ää <hannelotta@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..e713193
--- /dev/null
@@ -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ää" <hannelotta@gmail.com>
+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" <johannes.berg@intel.com>, "Hanne-Lotta Mäenpää" <hannelotta@gmail.com>
+Message-ID: <20260202165038.215693-2-hannelotta@gmail.com>
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ 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 <johannes.berg@intel.com>
+Signed-off-by: Hanne-Lotta Mäenpää <hannelotta@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <luisca@cozybit.com>
+  */
+@@ -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 <jbenc@suse.cz>
+  * Copyright 2008-2010        Johannes Berg <johannes@sipsolutions.net>
+  * Copyright 2013-2014  Intel Mobile Communications GmbH
++ * Copyright 2021-2023  Intel Corporation
+  */
+ #include <linux/export.h>
+@@ -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 (file)
index 0000000..14d246b
--- /dev/null
@@ -0,0 +1,85 @@
+From stable+bounces-210651-greg=kroah.com@vger.kernel.org Wed Jan 21 03:36:52 2026
+From: Sasha Levin <sashal@kernel.org>
+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 <bfoster@redhat.com>, "Darrick J. Wong" <djwong@kernel.org>, Carlos Maiolino <cem@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260121023545.1132446-1-sashal@kernel.org>
+
+From: Brian Foster <bfoster@redhat.com>
+
+[ 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 <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+[ xfs_ag_block_count(args.mp, pag_agno(pag)) => args.mp->m_sb.sb_agblocks ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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)