--- /dev/null
+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;
+ }
--- /dev/null
+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>;
+ };
--- /dev/null
+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];
--- /dev/null
+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;
+ }
+
--- /dev/null
+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);
+ }
--- /dev/null
+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)
--- /dev/null
+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);
+ }
+
--- /dev/null
+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);
+
--- /dev/null
+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);
--- /dev/null
+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
--- /dev/null
+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);
+
--- /dev/null
+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,
--- /dev/null
+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;
+
--- /dev/null
+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;
+
--- /dev/null
+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;
+ }
--- /dev/null
+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;
+ }
--- /dev/null
+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)
--- /dev/null
+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();
+ }
--- /dev/null
+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));
--- /dev/null
+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;
+ }
--- /dev/null
+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_ */
--- /dev/null
+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)
+ {
--- /dev/null
+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);
+
--- /dev/null
+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);
--- /dev/null
+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();
--- /dev/null
+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,
--- /dev/null
+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
--- /dev/null
+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 */
--- /dev/null
+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);
+ }
+
--- /dev/null
+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;
+ }
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
--- /dev/null
+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)
--- /dev/null
+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);
--- /dev/null
+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;
+ }
+
--- /dev/null
+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
--- /dev/null
+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)
--- /dev/null
+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);
+ }
+
--- /dev/null
+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,
--- /dev/null
+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)