]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Apr 2026 14:30:57 +0000 (16:30 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Apr 2026 14:30:57 +0000 (16:30 +0200)
added patches:
bluetooth-l2cap-fix-accepting-multiple-l2cap_ecred_conn_req.patch
dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch
dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch
drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch
ext4-fix-the-might_sleep-warnings-in-kvfree.patch
ext4-fix-use-after-free-in-update_super_work-when-racing-with-umount.patch
ext4-publish-jinode-after-initialization.patch
i2c-cp2615-fix-serial-string-null-deref-at-probe.patch
i2c-cp2615-replace-deprecated-strncpy-with-strscpy.patch
ksmbd-fix-dangling-pointer-in-krb_authenticate.patch
ksmbd-fix-potencial-oob-in-get_file_all_info-for-compound-requests.patch
ksmbd-fix-refcount-leak-when-invalid-session-is-found-on-session-lookup.patch
ksmbd-replace-hardcoded-hdr2_len-with-offsetof-in-smb2_calc_max_out_buf_len.patch
kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch
mm-huge_memory-fix-folio-isn-t-locked-in-softleaf_to_folio.patch
net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch
net-rfkill-prevent-unlimited-numbers-of-rfkill-events-from-being-created.patch
revert-mptcp-add-needs_id-for-netlink-appending-addr.patch
scsi-target-tcm_loop-drain-commands-in-target_reset-handler.patch
seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch
tracing-fix-potential-deadlock-in-cpu-hotplug-with-osnoise.patch
usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch
usb-gadget-u_ether-fix-race-between-gether_disconnect-and-eth_stop.patch
usb-gadget-uvc-fix-null-pointer-dereference-during-unbind-race.patch
x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch
xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch

27 files changed:
queue-5.15/bluetooth-l2cap-fix-accepting-multiple-l2cap_ecred_conn_req.patch [new file with mode: 0644]
queue-5.15/dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch [new file with mode: 0644]
queue-5.15/dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch [new file with mode: 0644]
queue-5.15/drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch [new file with mode: 0644]
queue-5.15/ext4-fix-the-might_sleep-warnings-in-kvfree.patch [new file with mode: 0644]
queue-5.15/ext4-fix-use-after-free-in-update_super_work-when-racing-with-umount.patch [new file with mode: 0644]
queue-5.15/ext4-publish-jinode-after-initialization.patch [new file with mode: 0644]
queue-5.15/i2c-cp2615-fix-serial-string-null-deref-at-probe.patch [new file with mode: 0644]
queue-5.15/i2c-cp2615-replace-deprecated-strncpy-with-strscpy.patch [new file with mode: 0644]
queue-5.15/ksmbd-fix-dangling-pointer-in-krb_authenticate.patch [new file with mode: 0644]
queue-5.15/ksmbd-fix-potencial-oob-in-get_file_all_info-for-compound-requests.patch [new file with mode: 0644]
queue-5.15/ksmbd-fix-refcount-leak-when-invalid-session-is-found-on-session-lookup.patch [new file with mode: 0644]
queue-5.15/ksmbd-replace-hardcoded-hdr2_len-with-offsetof-in-smb2_calc_max_out_buf_len.patch [new file with mode: 0644]
queue-5.15/kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch [new file with mode: 0644]
queue-5.15/mm-huge_memory-fix-folio-isn-t-locked-in-softleaf_to_folio.patch [new file with mode: 0644]
queue-5.15/net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch [new file with mode: 0644]
queue-5.15/net-rfkill-prevent-unlimited-numbers-of-rfkill-events-from-being-created.patch [new file with mode: 0644]
queue-5.15/revert-mptcp-add-needs_id-for-netlink-appending-addr.patch [new file with mode: 0644]
queue-5.15/scsi-target-tcm_loop-drain-commands-in-target_reset-handler.patch [new file with mode: 0644]
queue-5.15/seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/tracing-fix-potential-deadlock-in-cpu-hotplug-with-osnoise.patch [new file with mode: 0644]
queue-5.15/usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch [new file with mode: 0644]
queue-5.15/usb-gadget-u_ether-fix-race-between-gether_disconnect-and-eth_stop.patch [new file with mode: 0644]
queue-5.15/usb-gadget-uvc-fix-null-pointer-dereference-during-unbind-race.patch [new file with mode: 0644]
queue-5.15/x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch [new file with mode: 0644]
queue-5.15/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch [new file with mode: 0644]

diff --git a/queue-5.15/bluetooth-l2cap-fix-accepting-multiple-l2cap_ecred_conn_req.patch b/queue-5.15/bluetooth-l2cap-fix-accepting-multiple-l2cap_ecred_conn_req.patch
new file mode 100644 (file)
index 0000000..a8660af
--- /dev/null
@@ -0,0 +1,64 @@
+From stable+bounces-227804-greg=kroah.com@vger.kernel.org Sun Mar 22 02:27:44 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 Mar 2026 21:27:39 -0400
+Subject: Bluetooth: L2CAP: Fix accepting multiple L2CAP_ECRED_CONN_REQ
+To: stable@vger.kernel.org
+Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Yiming Qian <yimingqian591@gmail.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260322012739.673067-1-sashal@kernel.org>
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 5b3e2052334f2ff6d5200e952f4aa66994d09899 ]
+
+Currently the code attempts to accept requests regardless of the
+command identifier which may cause multiple requests to be marked
+as pending (FLAG_DEFER_SETUP) which can cause more than
+L2CAP_ECRED_MAX_CID(5) to be allocated in l2cap_ecred_rsp_defer
+causing an overflow.
+
+The spec is quite clear that the same identifier shall not be used on
+subsequent requests:
+
+'Within each signaling channel a different Identifier shall be used
+for each successive request or indication.'
+https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-62/out/en/host/logical-link-control-and-adaptation-protocol-specification.html#UUID-32a25a06-4aa4-c6c7-77c5-dcfe3682355d
+
+So this attempts to check if there are any channels pending with the
+same identifier and rejects if any are found.
+
+Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
+Reported-by: Yiming Qian <yimingqian591@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+[ adapted variable names ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_core.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6043,7 +6043,7 @@ static inline int l2cap_ecred_conn_req(s
+       u16 mtu, mps;
+       __le16 psm;
+       u8 result, len = 0;
+-      int i, num_scid;
++      int i, num_scid = 0;
+       bool defer = false;
+       if (!enable_ecred)
+@@ -6053,6 +6053,14 @@ static inline int l2cap_ecred_conn_req(s
+               result = L2CAP_CR_LE_INVALID_PARAMS;
+               goto response;
+       }
++
++      /* Check if there are no pending channels with the same ident */
++      __l2cap_chan_list_id(conn, cmd->ident, l2cap_ecred_list_defer,
++                           &num_scid);
++      if (num_scid) {
++              result = L2CAP_CR_LE_INVALID_PARAMS;
++              goto response;
++      }
+       cmd_len -= sizeof(*req);
+       num_scid = cmd_len / sizeof(u16);
diff --git a/queue-5.15/dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch b/queue-5.15/dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch
new file mode 100644 (file)
index 0000000..3c5b72f
--- /dev/null
@@ -0,0 +1,79 @@
+From stable+bounces-232813-greg=kroah.com@vger.kernel.org Wed Apr  1 18:24:04 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed,  1 Apr 2026 12:16:58 -0400
+Subject: dmaengine: sh: rz-dmac: Move CHCTRL updates under spinlock
+To: stable@vger.kernel.org
+Cc: Claudiu Beznea <claudiu.beznea@tuxon.dev>, Biju Das <biju.das.jz@bp.renesas.com>, Frank Li <Frank.Li@nxp.com>, Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>, Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260401161658.115456-1-sashal@kernel.org>
+
+From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+
+[ Upstream commit 89a8567d84bde88cb7cdbbac2ab2299c4f991490 ]
+
+Both rz_dmac_disable_hw() and rz_dmac_irq_handle_channel() update the
+CHCTRL register. To avoid concurrency issues when configuring
+functionalities exposed by this registers, take the virtual channel lock.
+All other CHCTRL updates were already protected by the same lock.
+
+Previously, rz_dmac_disable_hw() disabled and re-enabled local IRQs, before
+accessing CHCTRL registers but this does not ensure race-free access.
+Remove the local IRQ disable/enable code as well.
+
+Fixes: 5000d37042a6 ("dmaengine: sh: Add DMAC driver for RZ/G2L SoC")
+Cc: stable@vger.kernel.org
+Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://patch.msgid.link/20260316133252.240348-3-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+[ replaced scoped_guard(spinlock_irqsave, ...) ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/sh/rz-dmac.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/dma/sh/rz-dmac.c
++++ b/drivers/dma/sh/rz-dmac.c
+@@ -283,13 +283,10 @@ static void rz_dmac_disable_hw(struct rz
+ {
+       struct dma_chan *chan = &channel->vc.chan;
+       struct rz_dmac *dmac = to_rz_dmac(chan->device);
+-      unsigned long flags;
+       dev_dbg(dmac->dev, "%s channel %d\n", __func__, channel->index);
+-      local_irq_save(flags);
+       rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);
+-      local_irq_restore(flags);
+ }
+ static void rz_dmac_set_dmars_register(struct rz_dmac *dmac, int nr, u32 dmars)
+@@ -536,8 +533,8 @@ static int rz_dmac_terminate_all(struct
+       unsigned int i;
+       LIST_HEAD(head);
+-      rz_dmac_disable_hw(channel);
+       spin_lock_irqsave(&channel->vc.lock, flags);
++      rz_dmac_disable_hw(channel);
+       for (i = 0; i < DMAC_NR_LMDESC; i++)
+               lmdesc[i].header = 0;
+@@ -646,13 +643,17 @@ static void rz_dmac_irq_handle_channel(s
+ {
+       struct dma_chan *chan = &channel->vc.chan;
+       struct rz_dmac *dmac = to_rz_dmac(chan->device);
++      unsigned long flags;
+       u32 chstat, chctrl;
+       chstat = rz_dmac_ch_readl(channel, CHSTAT, 1);
+       if (chstat & CHSTAT_ER) {
+               dev_err(dmac->dev, "DMAC err CHSTAT_%d = %08X\n",
+                       channel->index, chstat);
++
++              spin_lock_irqsave(&channel->vc.lock, flags);
+               rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1);
++              spin_unlock_irqrestore(&channel->vc.lock, flags);
+               goto done;
+       }
diff --git a/queue-5.15/dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch b/queue-5.15/dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch
new file mode 100644 (file)
index 0000000..749768a
--- /dev/null
@@ -0,0 +1,107 @@
+From stable+bounces-232632-greg=kroah.com@vger.kernel.org Wed Apr  1 02:47:53 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Mar 2026 20:45:24 -0400
+Subject: dmaengine: sh: rz-dmac: Protect the driver specific lists
+To: stable@vger.kernel.org
+Cc: Claudiu Beznea <claudiu.beznea@tuxon.dev>, Frank Li <Frank.Li@nxp.com>, Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>, Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260401004524.4038525-1-sashal@kernel.org>
+
+From: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+
+[ Upstream commit abb863e6213dc41a58ef8bb3289b7e77460dabf3 ]
+
+The driver lists (ld_free, ld_queue) are used in
+rz_dmac_free_chan_resources(), rz_dmac_terminate_all(),
+rz_dmac_issue_pending(), and rz_dmac_irq_handler_thread(), all under
+the virtual channel lock. Take the same lock in rz_dmac_prep_slave_sg()
+and rz_dmac_prep_dma_memcpy() as well to avoid concurrency issues, since
+these functions also check whether the lists are empty and update or
+remove list entries.
+
+Fixes: 5000d37042a6 ("dmaengine: sh: Add DMAC driver for RZ/G2L SoC")
+Cc: stable@vger.kernel.org
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://patch.msgid.link/20260316133252.240348-2-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+[ replaced scoped_guard(spinlock_irqsave) with explicit spin_lock_irqsave/spin_unlock_irqrestore calls ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/sh/rz-dmac.c |   24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+--- a/drivers/dma/sh/rz-dmac.c
++++ b/drivers/dma/sh/rz-dmac.c
+@@ -419,6 +419,7 @@ static int rz_dmac_alloc_chan_resources(
+               if (!desc)
+                       break;
++              /* No need to lock. This is called only for the 1st client. */
+               list_add_tail(&desc->node, &channel->ld_free);
+               channel->descs_allocated++;
+       }
+@@ -470,12 +471,17 @@ rz_dmac_prep_dma_memcpy(struct dma_chan
+       struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
+       struct rz_dmac *dmac = to_rz_dmac(chan->device);
+       struct rz_dmac_desc *desc;
++      unsigned long irqflags;
+       dev_dbg(dmac->dev, "%s channel: %d src=0x%pad dst=0x%pad len=%zu\n",
+               __func__, channel->index, &src, &dest, len);
+-      if (list_empty(&channel->ld_free))
++      spin_lock_irqsave(&channel->vc.lock, irqflags);
++
++      if (list_empty(&channel->ld_free)) {
++              spin_unlock_irqrestore(&channel->vc.lock, irqflags);
+               return NULL;
++      }
+       desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node);
+@@ -486,6 +492,9 @@ rz_dmac_prep_dma_memcpy(struct dma_chan
+       desc->direction = DMA_MEM_TO_MEM;
+       list_move_tail(channel->ld_free.next, &channel->ld_queue);
++
++      spin_unlock_irqrestore(&channel->vc.lock, irqflags);
++
+       return vchan_tx_prep(&channel->vc, &desc->vd, flags);
+ }
+@@ -498,17 +507,21 @@ rz_dmac_prep_slave_sg(struct dma_chan *c
+       struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
+       struct rz_dmac_desc *desc;
+       struct scatterlist *sg;
++      unsigned long irqflags;
+       int dma_length = 0;
+       int i = 0;
+-      if (list_empty(&channel->ld_free))
++      spin_lock_irqsave(&channel->vc.lock, irqflags);
++
++      if (list_empty(&channel->ld_free)) {
++              spin_unlock_irqrestore(&channel->vc.lock, irqflags);
+               return NULL;
++      }
+       desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node);
+-      for_each_sg(sgl, sg, sg_len, i) {
++      for_each_sg(sgl, sg, sg_len, i)
+               dma_length += sg_dma_len(sg);
+-      }
+       desc->type = RZ_DMAC_DESC_SLAVE_SG;
+       desc->sg = sgl;
+@@ -522,6 +535,9 @@ rz_dmac_prep_slave_sg(struct dma_chan *c
+               desc->dest = channel->dst_per_address;
+       list_move_tail(channel->ld_free.next, &channel->ld_queue);
++
++      spin_unlock_irqrestore(&channel->vc.lock, irqflags);
++
+       return vchan_tx_prep(&channel->vc, &desc->vd, flags);
+ }
diff --git a/queue-5.15/drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch b/queue-5.15/drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch
new file mode 100644 (file)
index 0000000..5435e7e
--- /dev/null
@@ -0,0 +1,237 @@
+From stable+bounces-227778-greg=kroah.com@vger.kernel.org Sat Mar 21 17:31:28 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 Mar 2026 12:31:22 -0400
+Subject: drm: Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug
+To: stable@vger.kernel.org
+Cc: "Maarten Lankhorst" <dev@lankhorst.se>, "Thomas Hellström" <thomas.hellstrom@linux.intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260321163122.490593-1-sashal@kernel.org>
+
+From: Maarten Lankhorst <dev@lankhorst.se>
+
+[ Upstream commit 6bee098b91417654703e17eb5c1822c6dfd0c01d ]
+
+When trying to do a rather aggressive test of igt's "xe_module_load
+--r reload" with a full desktop environment and game running I noticed
+a few OOPSes when dereferencing freed pointers, related to
+framebuffers and property blobs after the compositor exits.
+
+Solve this by guarding the freeing in drm_file with drm_dev_enter/exit,
+and immediately put the references from struct drm_file objects during
+drm_dev_unplug().
+
+Related warnings for framebuffers on the subtest:
+[  739.713076] ------------[ cut here ]------------
+               WARN_ON(!list_empty(&dev->mode_config.fb_list))
+[  739.713079] WARNING: drivers/gpu/drm/drm_mode_config.c:584 at drm_mode_config_cleanup+0x30b/0x320 [drm], CPU#12: xe_module_load/13145
+....
+[  739.713328] Call Trace:
+[  739.713330]  <TASK>
+[  739.713335]  ? intel_pmdemand_destroy_state+0x11/0x20 [xe]
+[  739.713574]  ? intel_atomic_global_obj_cleanup+0xe4/0x1a0 [xe]
+[  739.713794]  intel_display_driver_remove_noirq+0x51/0xb0 [xe]
+[  739.714041]  xe_display_fini_early+0x33/0x50 [xe]
+[  739.714284]  devm_action_release+0xf/0x20
+[  739.714294]  devres_release_all+0xad/0xf0
+[  739.714301]  device_unbind_cleanup+0x12/0xa0
+[  739.714305]  device_release_driver_internal+0x1b7/0x210
+[  739.714311]  device_driver_detach+0x14/0x20
+[  739.714315]  unbind_store+0xa6/0xb0
+[  739.714319]  drv_attr_store+0x21/0x30
+[  739.714322]  sysfs_kf_write+0x48/0x60
+[  739.714328]  kernfs_fop_write_iter+0x16b/0x240
+[  739.714333]  vfs_write+0x266/0x520
+[  739.714341]  ksys_write+0x72/0xe0
+[  739.714345]  __x64_sys_write+0x19/0x20
+[  739.714347]  x64_sys_call+0xa15/0xa30
+[  739.714355]  do_syscall_64+0xd8/0xab0
+[  739.714361]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+
+and
+
+[  739.714459] ------------[ cut here ]------------
+[  739.714461] xe 0000:67:00.0: [drm] drm_WARN_ON(!list_empty(&fb->filp_head))
+[  739.714464] WARNING: drivers/gpu/drm/drm_framebuffer.c:833 at drm_framebuffer_free+0x6c/0x90 [drm], CPU#12: xe_module_load/13145
+[  739.714715] RIP: 0010:drm_framebuffer_free+0x7a/0x90 [drm]
+...
+[  739.714869] Call Trace:
+[  739.714871]  <TASK>
+[  739.714876]  drm_mode_config_cleanup+0x26a/0x320 [drm]
+[  739.714998]  ? __drm_printfn_seq_file+0x20/0x20 [drm]
+[  739.715115]  ? drm_mode_config_cleanup+0x207/0x320 [drm]
+[  739.715235]  intel_display_driver_remove_noirq+0x51/0xb0 [xe]
+[  739.715576]  xe_display_fini_early+0x33/0x50 [xe]
+[  739.715821]  devm_action_release+0xf/0x20
+[  739.715828]  devres_release_all+0xad/0xf0
+[  739.715843]  device_unbind_cleanup+0x12/0xa0
+[  739.715850]  device_release_driver_internal+0x1b7/0x210
+[  739.715856]  device_driver_detach+0x14/0x20
+[  739.715860]  unbind_store+0xa6/0xb0
+[  739.715865]  drv_attr_store+0x21/0x30
+[  739.715868]  sysfs_kf_write+0x48/0x60
+[  739.715873]  kernfs_fop_write_iter+0x16b/0x240
+[  739.715878]  vfs_write+0x266/0x520
+[  739.715886]  ksys_write+0x72/0xe0
+[  739.715890]  __x64_sys_write+0x19/0x20
+[  739.715893]  x64_sys_call+0xa15/0xa30
+[  739.715900]  do_syscall_64+0xd8/0xab0
+[  739.715905]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+
+and then finally file close blows up:
+
+[  743.186530] Oops: general protection fault, probably for non-canonical address 0xdead000000000122: 0000 [#1] SMP
+[  743.186535] CPU: 3 UID: 1000 PID: 3453 Comm: kwin_wayland Tainted: G        W           7.0.0-rc1-valkyria+ #110 PREEMPT_{RT,(lazy)}
+[  743.186537] Tainted: [W]=WARN
+[  743.186538] Hardware name: Gigabyte Technology Co., Ltd. X299 AORUS Gaming 3/X299 AORUS Gaming 3-CF, BIOS F8n 12/06/2021
+[  743.186539] RIP: 0010:drm_framebuffer_cleanup+0x55/0xc0 [drm]
+[  743.186588] Code: d8 72 73 0f b6 42 05 ff c3 39 c3 72 e8 49 8d bd 50 07 00 00 31 f6 e8 3a 80 d3 e1 49 8b 44 24 10 49 8d 7c 24 08 49 8b 54 24 08 <48> 3b 38 0f 85 95 7f 02 00 48 3b 7a 08 0f 85 8b 7f 02 00 48 89 42
+[  743.186589] RSP: 0018:ffffc900085e3cf8 EFLAGS: 00010202
+[  743.186591] RAX: dead000000000122 RBX: 0000000000000001 RCX: ffffffff8217ed03
+[  743.186592] RDX: dead000000000100 RSI: 0000000000000000 RDI: ffff88814675ba08
+[  743.186593] RBP: ffffc900085e3d10 R08: 0000000000000000 R09: 0000000000000000
+[  743.186593] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88814675ba00
+[  743.186594] R13: ffff88810d778000 R14: ffff888119f6dca0 R15: ffff88810c660bb0
+[  743.186595] FS:  00007ff377d21280(0000) GS:ffff888cec3f8000(0000) knlGS:0000000000000000
+[  743.186596] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  743.186596] CR2: 000055690b55e000 CR3: 0000000113586003 CR4: 00000000003706f0
+[  743.186597] Call Trace:
+[  743.186598]  <TASK>
+[  743.186603]  intel_user_framebuffer_destroy+0x12/0x90 [xe]
+[  743.186722]  drm_framebuffer_free+0x3a/0x90 [drm]
+[  743.186750]  ? trace_hardirqs_on+0x5f/0x120
+[  743.186754]  drm_mode_object_put+0x51/0x70 [drm]
+[  743.186786]  drm_fb_release+0x105/0x190 [drm]
+[  743.186812]  ? rt_mutex_slowunlock+0x3aa/0x410
+[  743.186817]  ? rt_spin_lock+0xea/0x1b0
+[  743.186819]  drm_file_free+0x1e0/0x2c0 [drm]
+[  743.186843]  drm_release_noglobal+0x91/0xf0 [drm]
+[  743.186865]  __fput+0x100/0x2e0
+[  743.186869]  fput_close_sync+0x40/0xa0
+[  743.186870]  __x64_sys_close+0x3e/0x80
+[  743.186873]  x64_sys_call+0xa07/0xa30
+[  743.186879]  do_syscall_64+0xd8/0xab0
+[  743.186881]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[  743.186882] RIP: 0033:0x7ff37e567732
+[  743.186884] Code: 08 0f 85 a1 38 ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 55 bf 01 00
+[  743.186885] RSP: 002b:00007ffc818169a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000003
+[  743.186886] RAX: ffffffffffffffda RBX: 00007ffc81816a30 RCX: 00007ff37e567732
+[  743.186887] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000012
+[  743.186888] RBP: 00007ffc818169d0 R08: 0000000000000000 R09: 0000000000000000
+[  743.186889] R10: 0000000000000000 R11: 0000000000000246 R12: 000055d60a7996e0
+[  743.186889] R13: 00007ffc81816a90 R14: 00007ffc81816a90 R15: 000055d60a782a30
+[  743.186892]  </TASK>
+[  743.186893] Modules linked in: rfcomm snd_hrtimer xt_CHECKSUM xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp xt_addrtype nft_compat x_tables nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables overlay cfg80211 bnep mtd_intel_dg snd_hda_codec_intelhdmi mtd snd_hda_codec_hdmi nls_utf8 mxm_wmi intel_wmi_thunderbolt gigabyte_wmi wmi_bmof xe drm_gpuvm drm_gpusvm_helper i2c_algo_bit drm_buddy drm_ttm_helper ttm video drm_suballoc_helper gpu_sched drm_client_lib drm_exec drm_display_helper cec drm_kunit_helpers drm_kms_helper kunit x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_alc882 snd_hda_codec_realtek_lib snd_hda_codec_generic snd_hda_intel snd_soc_avs snd_soc_hda_codec snd_hda_ext_core snd_hda_codec snd_hwdep snd_hda_core snd_intel_dspcfg snd_soc_core snd_compress ac97_bus snd_pcm snd_seq snd_seq_device snd_timer i2c_i801 i2c_mux snd i2c_smbus btusb btrtl btbcm btmtk btintel bluetooth ecdh_generic rfkill ecc mei_me mei ioatdma dca wmi nfsd drm i2c_dev fuse nfnetlink
+[  743.186938] ---[ end trace 0000000000000000 ]---
+
+And for property blobs:
+
+void drm_mode_config_cleanup(struct drm_device *dev)
+{
+...
+       list_for_each_entry_safe(blob, bt, &dev->mode_config.property_blob_list,
+                                head_global) {
+               drm_property_blob_put(blob);
+       }
+
+Resulting in:
+
+[  371.072940] BUG: unable to handle page fault for address: 000001ffffffffff
+[  371.072944] #PF: supervisor read access in kernel mode
+[  371.072945] #PF: error_code(0x0000) - not-present page
+[  371.072947] PGD 0 P4D 0
+[  371.072950] Oops: Oops: 0000 [#1] SMP
+[  371.072953] CPU: 0 UID: 1000 PID: 3693 Comm: kwin_wayland Not tainted 7.0.0-rc1-valkyria+ #111 PREEMPT_{RT,(lazy)}
+[  371.072956] Hardware name: Gigabyte Technology Co., Ltd. X299 AORUS Gaming 3/X299 AORUS Gaming 3-CF, BIOS F8n 12/06/2021
+[  371.072957] RIP: 0010:drm_property_destroy_user_blobs+0x3b/0x90 [drm]
+[  371.073019] Code: 00 00 48 83 ec 10 48 8b 86 30 01 00 00 48 39 c3 74 59 48 89 c2 48 8d 48 c8 48 8b 00 4c 8d 60 c8 eb 04 4c 8d 60 c8 48 8b 71 40 <48> 39 16 0f 85 39 32 01 00 48 3b 50 08 0f 85 2f 32 01 00 48 89 70
+[  371.073021] RSP: 0018:ffffc90006a73de8 EFLAGS: 00010293
+[  371.073022] RAX: 000001ffffffffff RBX: ffff888118a1a930 RCX: ffff8881b92355c0
+[  371.073024] RDX: ffff8881b92355f8 RSI: 000001ffffffffff RDI: ffff888118be4000
+[  371.073025] RBP: ffffc90006a73e08 R08: ffff8881009b7300 R09: ffff888cecc5b000
+[  371.073026] R10: ffffc90006a73e90 R11: 0000000000000002 R12: 000001ffffffffc7
+[  371.073027] R13: ffff888118a1a980 R14: ffff88810b366d20 R15: ffff888118a1a970
+[  371.073028] FS:  00007f1faccbb280(0000) GS:ffff888cec2db000(0000) knlGS:0000000000000000
+[  371.073029] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  371.073030] CR2: 000001ffffffffff CR3: 000000010655c001 CR4: 00000000003706f0
+[  371.073031] Call Trace:
+[  371.073033]  <TASK>
+[  371.073036]  drm_file_free+0x1df/0x2a0 [drm]
+[  371.073077]  drm_release_noglobal+0x7a/0xe0 [drm]
+[  371.073113]  __fput+0xe2/0x2b0
+[  371.073118]  fput_close_sync+0x40/0xa0
+[  371.073119]  __x64_sys_close+0x3e/0x80
+[  371.073122]  x64_sys_call+0xa07/0xa30
+[  371.073126]  do_syscall_64+0xc0/0x840
+[  371.073130]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[  371.073132] RIP: 0033:0x7f1fb3501732
+[  371.073133] Code: 08 0f 85 a1 38 ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 55 bf 01 00
+[  371.073135] RSP: 002b:00007ffe8e6f0278 EFLAGS: 00000246 ORIG_RAX: 0000000000000003
+[  371.073136] RAX: ffffffffffffffda RBX: 00007ffe8e6f0300 RCX: 00007f1fb3501732
+[  371.073137] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000012
+[  371.073138] RBP: 00007ffe8e6f02a0 R08: 0000000000000000 R09: 0000000000000000
+[  371.073139] R10: 0000000000000000 R11: 0000000000000246 R12: 00005585ba46eea0
+[  371.073140] R13: 00007ffe8e6f0360 R14: 00007ffe8e6f0360 R15: 00005585ba458a30
+[  371.073143]  </TASK>
+[  371.073144] Modules linked in: rfcomm snd_hrtimer xt_addrtype xt_CHECKSUM xt_MASQUERADE xt_conntrack ipt_REJECT nf_reject_ipv4 xt_tcpudp nft_compat x_tables nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables overlay cfg80211 bnep snd_hda_codec_intelhdmi snd_hda_codec_hdmi mtd_intel_dg mtd nls_utf8 wmi_bmof mxm_wmi gigabyte_wmi intel_wmi_thunderbolt xe drm_gpuvm drm_gpusvm_helper i2c_algo_bit drm_buddy drm_ttm_helper ttm video drm_suballoc_helper gpu_sched drm_client_lib drm_exec drm_display_helper cec drm_kunit_helpers drm_kms_helper kunit x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_codec_alc882 snd_hda_codec_realtek_lib snd_hda_codec_generic snd_hda_intel snd_soc_avs snd_soc_hda_codec snd_hda_ext_core snd_hda_codec snd_hwdep snd_hda_core snd_intel_dspcfg snd_soc_core snd_compress ac97_bus snd_pcm snd_seq snd_seq_device snd_timer i2c_i801 btusb i2c_mux i2c_smbus btrtl snd btbcm btmtk btintel bluetooth ecdh_generic rfkill ecc mei_me mei ioatdma dca wmi nfsd drm i2c_dev fuse nfnetlink
+[  371.073198] CR2: 000001ffffffffff
+[  371.073199] ---[ end trace 0000000000000000 ]---
+
+Add a guard around file close, and ensure the warnings from drm_mode_config
+do not trigger. Fix those by allowing an open reference to the file descriptor
+and cleaning up the file linked list entry in drm_mode_config_cleanup().
+
+Cc: <stable@vger.kernel.org> # v4.18+
+Fixes: bee330f3d672 ("drm: Use srcu to protect drm_device.unplugged")
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Link: https://patch.msgid.link/20260313151728.14990-4-dev@lankhorst.se
+Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
+[ adapted drm_dbg_printer(dev, DRM_UT_KMS, ...) call to older drm_debug_printer(...) API ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/drm_file.c        |    5 ++++-
+ drivers/gpu/drm/drm_mode_config.c |    9 ++++++---
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/drm_file.c
++++ b/drivers/gpu/drm/drm_file.c
+@@ -244,6 +244,7 @@ static void drm_events_release(struct dr
+ void drm_file_free(struct drm_file *file)
+ {
+       struct drm_device *dev;
++      int idx;
+       if (!file)
+               return;
+@@ -269,9 +270,11 @@ void drm_file_free(struct drm_file *file
+       drm_events_release(file);
+-      if (drm_core_check_feature(dev, DRIVER_MODESET)) {
++      if (drm_core_check_feature(dev, DRIVER_MODESET) &&
++          drm_dev_enter(dev, &idx)) {
+               drm_fb_release(file);
+               drm_property_destroy_user_blobs(dev, file);
++              drm_dev_exit(idx);
+       }
+       if (drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+--- a/drivers/gpu/drm/drm_mode_config.c
++++ b/drivers/gpu/drm/drm_mode_config.c
+@@ -543,10 +543,13 @@ void drm_mode_config_cleanup(struct drm_
+        */
+       WARN_ON(!list_empty(&dev->mode_config.fb_list));
+       list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
+-              struct drm_printer p = drm_debug_printer("[leaked fb]");
++              if (list_empty(&fb->filp_head) || drm_framebuffer_read_refcount(fb) > 1) {
++                      struct drm_printer p = drm_debug_printer("[leaked fb]");
+-              drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
+-              drm_framebuffer_print_info(&p, 1, fb);
++                      drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
++                      drm_framebuffer_print_info(&p, 1, fb);
++              }
++              list_del_init(&fb->filp_head);
+               drm_framebuffer_free(&fb->base.refcount);
+       }
diff --git a/queue-5.15/ext4-fix-the-might_sleep-warnings-in-kvfree.patch b/queue-5.15/ext4-fix-the-might_sleep-warnings-in-kvfree.patch
new file mode 100644 (file)
index 0000000..f3e684b
--- /dev/null
@@ -0,0 +1,194 @@
+From stable+bounces-233078-greg=kroah.com@vger.kernel.org Thu Apr  2 19:21:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  2 Apr 2026 13:14:20 -0400
+Subject: ext4: fix the might_sleep() warnings in kvfree()
+To: stable@vger.kernel.org
+Cc: Zqiang <qiang.zhang@linux.dev>, Baokun Li <libaokun@linux.alibaba.com>, Theodore Ts'o <tytso@mit.edu>, stable@kernel.org, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260402171420.1528128-1-sashal@kernel.org>
+
+From: Zqiang <qiang.zhang@linux.dev>
+
+[ Upstream commit 496bb99b7e66f48b178126626f47e9ba79e2d0fa ]
+
+Use the kvfree() in the RCU read critical section can trigger
+the following warnings:
+
+EXT4-fs (vdb): unmounting filesystem cd983e5b-3c83-4f5a-a136-17b00eb9d018.
+
+WARNING: suspicious RCU usage
+
+./include/linux/rcupdate.h:409 Illegal context switch in RCU read-side critical section!
+
+other info that might help us debug this:
+
+rcu_scheduler_active = 2, debug_locks = 1
+
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xbb/0xd0
+ dump_stack+0x14/0x20
+ lockdep_rcu_suspicious+0x15a/0x1b0
+ __might_resched+0x375/0x4d0
+ ? put_object.part.0+0x2c/0x50
+ __might_sleep+0x108/0x160
+ vfree+0x58/0x910
+ ? ext4_group_desc_free+0x27/0x270
+ kvfree+0x23/0x40
+ ext4_group_desc_free+0x111/0x270
+ ext4_put_super+0x3c8/0xd40
+ generic_shutdown_super+0x14c/0x4a0
+ ? __pfx_shrinker_free+0x10/0x10
+ kill_block_super+0x40/0x90
+ ext4_kill_sb+0x6d/0xb0
+ deactivate_locked_super+0xb4/0x180
+ deactivate_super+0x7e/0xa0
+ cleanup_mnt+0x296/0x3e0
+ __cleanup_mnt+0x16/0x20
+ task_work_run+0x157/0x250
+ ? __pfx_task_work_run+0x10/0x10
+ ? exit_to_user_mode_loop+0x6a/0x550
+ exit_to_user_mode_loop+0x102/0x550
+ do_syscall_64+0x44a/0x500
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ </TASK>
+
+BUG: sleeping function called from invalid context at mm/vmalloc.c:3441
+in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 556, name: umount
+preempt_count: 1, expected: 0
+CPU: 3 UID: 0 PID: 556 Comm: umount
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xbb/0xd0
+ dump_stack+0x14/0x20
+ __might_resched+0x275/0x4d0
+ ? put_object.part.0+0x2c/0x50
+ __might_sleep+0x108/0x160
+ vfree+0x58/0x910
+ ? ext4_group_desc_free+0x27/0x270
+ kvfree+0x23/0x40
+ ext4_group_desc_free+0x111/0x270
+ ext4_put_super+0x3c8/0xd40
+ generic_shutdown_super+0x14c/0x4a0
+ ? __pfx_shrinker_free+0x10/0x10
+ kill_block_super+0x40/0x90
+ ext4_kill_sb+0x6d/0xb0
+ deactivate_locked_super+0xb4/0x180
+ deactivate_super+0x7e/0xa0
+ cleanup_mnt+0x296/0x3e0
+ __cleanup_mnt+0x16/0x20
+ task_work_run+0x157/0x250
+ ? __pfx_task_work_run+0x10/0x10
+ ? exit_to_user_mode_loop+0x6a/0x550
+ exit_to_user_mode_loop+0x102/0x550
+ do_syscall_64+0x44a/0x500
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+The above scenarios occur in initialization failures and teardown
+paths, there are no parallel operations on the resources released
+by kvfree(), this commit therefore remove rcu_read_lock/unlock() and
+use rcu_access_pointer() instead of rcu_dereference() operations.
+
+Fixes: 7c990728b99e ("ext4: fix potential race between s_flex_groups online resizing and access")
+Fixes: df3da4ea5a0f ("ext4: fix potential race between s_group_info online resizing and access")
+Signed-off-by: Zqiang <qiang.zhang@linux.dev>
+Reviewed-by: Baokun Li <libaokun@linux.alibaba.com>
+Link: https://patch.msgid.link/20260319094545.19291-1-qiang.zhang@linux.dev
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+[ adapted fix to inlined teardown code ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/mballoc.c |   10 +++-------
+ fs/ext4/super.c   |   14 ++++----------
+ 2 files changed, 7 insertions(+), 17 deletions(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -3353,9 +3353,7 @@ err_freebuddy:
+       rcu_read_unlock();
+       iput(sbi->s_buddy_cache);
+ err_freesgi:
+-      rcu_read_lock();
+-      kvfree(rcu_dereference(sbi->s_group_info));
+-      rcu_read_unlock();
++      kvfree(rcu_access_pointer(sbi->s_group_info));
+       return -ENOMEM;
+ }
+@@ -3634,7 +3632,8 @@ int ext4_mb_release(struct super_block *
+       flush_work(&sbi->s_discard_work);
+       WARN_ON_ONCE(!list_empty(&sbi->s_discard_list));
+-      if (sbi->s_group_info) {
++      group_info = rcu_access_pointer(sbi->s_group_info);
++      if (group_info) {
+               for (i = 0; i < ngroups; i++) {
+                       cond_resched();
+                       grinfo = ext4_get_group_info(sb, i);
+@@ -3652,12 +3651,9 @@ int ext4_mb_release(struct super_block *
+               num_meta_group_infos = (ngroups +
+                               EXT4_DESC_PER_BLOCK(sb) - 1) >>
+                       EXT4_DESC_PER_BLOCK_BITS(sb);
+-              rcu_read_lock();
+-              group_info = rcu_dereference(sbi->s_group_info);
+               for (i = 0; i < num_meta_group_infos; i++)
+                       kfree(group_info[i]);
+               kvfree(group_info);
+-              rcu_read_unlock();
+       }
+       kfree(sbi->s_mb_largest_free_orders);
+       kfree(sbi->s_mb_largest_free_orders_locks);
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1220,18 +1220,16 @@ static void ext4_put_super(struct super_
+       if (!sb_rdonly(sb))
+               ext4_commit_super(sb);
+-      rcu_read_lock();
+-      group_desc = rcu_dereference(sbi->s_group_desc);
++      group_desc = rcu_access_pointer(sbi->s_group_desc);
+       for (i = 0; i < sbi->s_gdb_count; i++)
+               brelse(group_desc[i]);
+       kvfree(group_desc);
+-      flex_groups = rcu_dereference(sbi->s_flex_groups);
++      flex_groups = rcu_access_pointer(sbi->s_flex_groups);
+       if (flex_groups) {
+               for (i = 0; i < sbi->s_flex_groups_allocated; i++)
+                       kvfree(flex_groups[i]);
+               kvfree(flex_groups);
+       }
+-      rcu_read_unlock();
+       percpu_counter_destroy(&sbi->s_freeclusters_counter);
+       percpu_counter_destroy(&sbi->s_freeinodes_counter);
+       percpu_counter_destroy(&sbi->s_dirs_counter);
+@@ -5075,14 +5073,12 @@ failed_mount7:
+       ext4_unregister_li_request(sb);
+ failed_mount6:
+       ext4_mb_release(sb);
+-      rcu_read_lock();
+-      flex_groups = rcu_dereference(sbi->s_flex_groups);
++      flex_groups = rcu_access_pointer(sbi->s_flex_groups);
+       if (flex_groups) {
+               for (i = 0; i < sbi->s_flex_groups_allocated; i++)
+                       kvfree(flex_groups[i]);
+               kvfree(flex_groups);
+       }
+-      rcu_read_unlock();
+       percpu_counter_destroy(&sbi->s_freeclusters_counter);
+       percpu_counter_destroy(&sbi->s_freeinodes_counter);
+       percpu_counter_destroy(&sbi->s_dirs_counter);
+@@ -5120,12 +5116,10 @@ failed_mount3:
+       ext4_stop_mmpd(sbi);
+       del_timer_sync(&sbi->s_err_report);
+ failed_mount2:
+-      rcu_read_lock();
+-      group_desc = rcu_dereference(sbi->s_group_desc);
++      group_desc = rcu_access_pointer(sbi->s_group_desc);
+       for (i = 0; i < db_count; i++)
+               brelse(group_desc[i]);
+       kvfree(group_desc);
+-      rcu_read_unlock();
+ failed_mount:
+       if (sbi->s_chksum_driver)
+               crypto_free_shash(sbi->s_chksum_driver);
diff --git a/queue-5.15/ext4-fix-use-after-free-in-update_super_work-when-racing-with-umount.patch b/queue-5.15/ext4-fix-use-after-free-in-update_super_work-when-racing-with-umount.patch
new file mode 100644 (file)
index 0000000..4c06a35
--- /dev/null
@@ -0,0 +1,118 @@
+From stable+bounces-233068-greg=kroah.com@vger.kernel.org Thu Apr  2 18:46:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  2 Apr 2026 12:37:40 -0400
+Subject: ext4: fix use-after-free in update_super_work when racing with umount
+To: stable@vger.kernel.org
+Cc: Jiayuan Chen <jiayuan.chen@shopee.com>, Jiayuan Chen <jiayuan.chen@linux.dev>, Jan Kara <jack@suse.cz>, "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>, Theodore Ts'o <tytso@mit.edu>, stable@kernel.org, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260402163740.1407640-1-sashal@kernel.org>
+
+From: Jiayuan Chen <jiayuan.chen@shopee.com>
+
+[ Upstream commit d15e4b0a418537aafa56b2cb80d44add83e83697 ]
+
+Commit b98535d09179 ("ext4: fix bug_on in start_this_handle during umount
+filesystem") moved ext4_unregister_sysfs() before flushing s_sb_upd_work
+to prevent new error work from being queued via /proc/fs/ext4/xx/mb_groups
+reads during unmount. However, this introduced a use-after-free because
+update_super_work calls ext4_notify_error_sysfs() -> sysfs_notify() which
+accesses the kobject's kernfs_node after it has been freed by kobject_del()
+in ext4_unregister_sysfs():
+
+  update_super_work                ext4_put_super
+  -----------------                --------------
+                                   ext4_unregister_sysfs(sb)
+                                     kobject_del(&sbi->s_kobj)
+                                       __kobject_del()
+                                         sysfs_remove_dir()
+                                           kobj->sd = NULL
+                                         sysfs_put(sd)
+                                           kernfs_put()  // RCU free
+  ext4_notify_error_sysfs(sbi)
+    sysfs_notify(&sbi->s_kobj)
+      kn = kobj->sd              // stale pointer
+      kernfs_get(kn)             // UAF on freed kernfs_node
+                                   ext4_journal_destroy()
+                                     flush_work(&sbi->s_sb_upd_work)
+
+Instead of reordering the teardown sequence, fix this by making
+ext4_notify_error_sysfs() detect that sysfs has already been torn down
+by checking s_kobj.state_in_sysfs, and skipping the sysfs_notify() call
+in that case. A dedicated mutex (s_error_notify_mutex) serializes
+ext4_notify_error_sysfs() against kobject_del() in ext4_unregister_sysfs()
+to prevent TOCTOU races where the kobject could be deleted between the
+state_in_sysfs check and the sysfs_notify() call.
+
+Fixes: b98535d09179 ("ext4: fix bug_on in start_this_handle during umount filesystem")
+Cc: Jiayuan Chen <jiayuan.chen@linux.dev>
+Suggested-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20260319120336.157873-1-jiayuan.chen@linux.dev
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+[ adapted mutex_init placement ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ext4.h  |    1 +
+ fs/ext4/super.c |    1 +
+ fs/ext4/sysfs.c |   10 +++++++++-
+ 3 files changed, 11 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1540,6 +1540,7 @@ struct ext4_sb_info {
+       struct proc_dir_entry *s_proc;
+       struct kobject s_kobj;
+       struct completion s_kobj_unregister;
++      struct mutex s_error_notify_mutex; /* protects sysfs_notify vs kobject_del */
+       struct super_block *s_sb;
+       struct buffer_head *s_mmp_bh;
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -4626,6 +4626,7 @@ static int ext4_fill_super(struct super_
+       timer_setup(&sbi->s_err_report, print_daily_error_info, 0);
+       spin_lock_init(&sbi->s_error_lock);
++      mutex_init(&sbi->s_error_notify_mutex);
+       INIT_WORK(&sbi->s_error_work, flush_stashed_error_work);
+       /* Register extent status tree shrinker */
+--- a/fs/ext4/sysfs.c
++++ b/fs/ext4/sysfs.c
+@@ -513,7 +513,10 @@ static struct kobj_type ext4_feat_ktype
+ void ext4_notify_error_sysfs(struct ext4_sb_info *sbi)
+ {
+-      sysfs_notify(&sbi->s_kobj, NULL, "errors_count");
++      mutex_lock(&sbi->s_error_notify_mutex);
++      if (sbi->s_kobj.state_in_sysfs)
++              sysfs_notify(&sbi->s_kobj, NULL, "errors_count");
++      mutex_unlock(&sbi->s_error_notify_mutex);
+ }
+ static struct kobject *ext4_root;
+@@ -526,8 +529,10 @@ int ext4_register_sysfs(struct super_blo
+       int err;
+       init_completion(&sbi->s_kobj_unregister);
++      mutex_lock(&sbi->s_error_notify_mutex);
+       err = kobject_init_and_add(&sbi->s_kobj, &ext4_sb_ktype, ext4_root,
+                                  "%s", sb->s_id);
++      mutex_unlock(&sbi->s_error_notify_mutex);
+       if (err) {
+               kobject_put(&sbi->s_kobj);
+               wait_for_completion(&sbi->s_kobj_unregister);
+@@ -560,7 +565,10 @@ void ext4_unregister_sysfs(struct super_
+       if (sbi->s_proc)
+               remove_proc_subtree(sb->s_id, ext4_proc_root);
++
++      mutex_lock(&sbi->s_error_notify_mutex);
+       kobject_del(&sbi->s_kobj);
++      mutex_unlock(&sbi->s_error_notify_mutex);
+ }
+ int __init ext4_init_sysfs(void)
diff --git a/queue-5.15/ext4-publish-jinode-after-initialization.patch b/queue-5.15/ext4-publish-jinode-after-initialization.patch
new file mode 100644 (file)
index 0000000..1227f93
--- /dev/null
@@ -0,0 +1,152 @@
+From stable+bounces-233127-greg=kroah.com@vger.kernel.org Fri Apr  3 02:43:37 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  2 Apr 2026 20:36:15 -0400
+Subject: ext4: publish jinode after initialization
+To: stable@vger.kernel.org
+Cc: Li Chen <me@linux.beauty>, Jan Kara <jack@suse.cz>, Theodore Ts'o <tytso@mit.edu>, stable@kernel.org, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260403003615.1839386-1-sashal@kernel.org>
+
+From: Li Chen <me@linux.beauty>
+
+[ Upstream commit 1aec30021edd410b986c156f195f3d23959a9d11 ]
+
+ext4_inode_attach_jinode() publishes ei->jinode to concurrent users.
+It used to set ei->jinode before jbd2_journal_init_jbd_inode(),
+allowing a reader to observe a non-NULL jinode with i_vfs_inode
+still unset.
+
+The fast commit flush path can then pass this jinode to
+jbd2_wait_inode_data(), which dereferences i_vfs_inode->i_mapping and
+may crash.
+
+Below is the crash I observe:
+```
+BUG: unable to handle page fault for address: 000000010beb47f4
+PGD 110e51067 P4D 110e51067 PUD 0
+Oops: Oops: 0000 [#1] SMP NOPTI
+CPU: 1 UID: 0 PID: 4850 Comm: fc_fsync_bench_ Not tainted 6.18.0-00764-g795a690c06a5 #1 PREEMPT(voluntary)
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.17.0-2-2 04/01/2014
+RIP: 0010:xas_find_marked+0x3d/0x2e0
+Code: e0 03 48 83 f8 02 0f 84 f0 01 00 00 48 8b 47 08 48 89 c3 48 39 c6 0f 82 fd 01 00 00 48 85 c9 74 3d 48 83 f9 03 77 63 4c 8b 0f <49> 8b 71 08 48 c7 47 18 00 00 00 00 48 89 f1 83 e1 03 48 83 f9 02
+RSP: 0018:ffffbbee806e7bf0 EFLAGS: 00010246
+RAX: 000000000010beb4 RBX: 000000000010beb4 RCX: 0000000000000003
+RDX: 0000000000000001 RSI: 0000002000300000 RDI: ffffbbee806e7c10
+RBP: 0000000000000001 R08: 0000002000300000 R09: 000000010beb47ec
+R10: ffff9ea494590090 R11: 0000000000000000 R12: 0000002000300000
+R13: ffffbbee806e7c90 R14: ffff9ea494513788 R15: ffffbbee806e7c88
+FS: 00007fc2f9e3e6c0(0000) GS:ffff9ea6b1444000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000010beb47f4 CR3: 0000000119ac5000 CR4: 0000000000750ef0
+PKRU: 55555554
+Call Trace:
+<TASK>
+filemap_get_folios_tag+0x87/0x2a0
+__filemap_fdatawait_range+0x5f/0xd0
+? srso_alias_return_thunk+0x5/0xfbef5
+? __schedule+0x3e7/0x10c0
+? srso_alias_return_thunk+0x5/0xfbef5
+? srso_alias_return_thunk+0x5/0xfbef5
+? srso_alias_return_thunk+0x5/0xfbef5
+? preempt_count_sub+0x5f/0x80
+? srso_alias_return_thunk+0x5/0xfbef5
+? cap_safe_nice+0x37/0x70
+? srso_alias_return_thunk+0x5/0xfbef5
+? preempt_count_sub+0x5f/0x80
+? srso_alias_return_thunk+0x5/0xfbef5
+filemap_fdatawait_range_keep_errors+0x12/0x40
+ext4_fc_commit+0x697/0x8b0
+? ext4_file_write_iter+0x64b/0x950
+? srso_alias_return_thunk+0x5/0xfbef5
+? preempt_count_sub+0x5f/0x80
+? srso_alias_return_thunk+0x5/0xfbef5
+? vfs_write+0x356/0x480
+? srso_alias_return_thunk+0x5/0xfbef5
+? preempt_count_sub+0x5f/0x80
+ext4_sync_file+0xf7/0x370
+do_fsync+0x3b/0x80
+? syscall_trace_enter+0x108/0x1d0
+__x64_sys_fdatasync+0x16/0x20
+do_syscall_64+0x62/0x2c0
+entry_SYSCALL_64_after_hwframe+0x76/0x7e
+...
+```
+
+Fix this by initializing the jbd2_inode first.
+Use smp_wmb() and WRITE_ONCE() to publish ei->jinode after
+initialization. Readers use READ_ONCE() to fetch the pointer.
+
+Fixes: a361293f5fede ("jbd2: Fix oops in jbd2_journal_file_inode()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Li Chen <me@linux.beauty>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20260225082617.147957-1-me@linux.beauty
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+[ adapted READ_ONCE(jinode) wrapping to split ext4_fc_submit_inode_data_all() and ext4_fc_wait_inode_data_all() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/fast_commit.c |    4 ++--
+ fs/ext4/inode.c       |   15 +++++++++++----
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -979,7 +979,7 @@ static int ext4_fc_submit_inode_data_all
+                       finish_wait(&ei->i_fc_wait, &wait);
+               }
+               spin_unlock(&sbi->s_fc_lock);
+-              ret = jbd2_submit_inode_data(ei->jinode);
++              ret = jbd2_submit_inode_data(READ_ONCE(ei->jinode));
+               if (ret)
+                       return ret;
+               spin_lock(&sbi->s_fc_lock);
+@@ -1004,7 +1004,7 @@ static int ext4_fc_wait_inode_data_all(j
+                       continue;
+               spin_unlock(&sbi->s_fc_lock);
+-              ret = jbd2_wait_inode_data(journal, pos->jinode);
++              ret = jbd2_wait_inode_data(journal, READ_ONCE(pos->jinode));
+               if (ret)
+                       return ret;
+               spin_lock(&sbi->s_fc_lock);
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -122,6 +122,8 @@ void ext4_inode_csum_set(struct inode *i
+ static inline int ext4_begin_ordered_truncate(struct inode *inode,
+                                             loff_t new_size)
+ {
++      struct jbd2_inode *jinode = READ_ONCE(EXT4_I(inode)->jinode);
++
+       trace_ext4_begin_ordered_truncate(inode, new_size);
+       /*
+        * If jinode is zero, then we never opened the file for
+@@ -129,10 +131,10 @@ static inline int ext4_begin_ordered_tru
+        * jbd2_journal_begin_ordered_truncate() since there's no
+        * outstanding writes we need to flush.
+        */
+-      if (!EXT4_I(inode)->jinode)
++      if (!jinode)
+               return 0;
+       return jbd2_journal_begin_ordered_truncate(EXT4_JOURNAL(inode),
+-                                                 EXT4_I(inode)->jinode,
++                                                 jinode,
+                                                  new_size);
+ }
+@@ -4145,8 +4147,13 @@ int ext4_inode_attach_jinode(struct inod
+                       spin_unlock(&inode->i_lock);
+                       return -ENOMEM;
+               }
+-              ei->jinode = jinode;
+-              jbd2_journal_init_jbd_inode(ei->jinode, inode);
++              jbd2_journal_init_jbd_inode(jinode, inode);
++              /*
++               * Publish ->jinode only after it is fully initialized so that
++               * readers never observe a partially initialized jbd2_inode.
++               */
++              smp_wmb();
++              WRITE_ONCE(ei->jinode, jinode);
+               jinode = NULL;
+       }
+       spin_unlock(&inode->i_lock);
diff --git a/queue-5.15/i2c-cp2615-fix-serial-string-null-deref-at-probe.patch b/queue-5.15/i2c-cp2615-fix-serial-string-null-deref-at-probe.patch
new file mode 100644 (file)
index 0000000..9f001ae
--- /dev/null
@@ -0,0 +1,43 @@
+From stable+bounces-227986-greg=kroah.com@vger.kernel.org Mon Mar 23 14:27:25 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Mar 2026 09:19:10 -0400
+Subject: i2c: cp2615: fix serial string NULL-deref at probe
+To: stable@vger.kernel.org
+Cc: "Johan Hovold" <johan@kernel.org>, "Bence Csókás" <bence98@sch.bme.hu>, "Andi Shyti" <andi.shyti@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260323131910.1715046-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit aa79f996eb41e95aed85a1bd7f56bcd6a3842008 ]
+
+The cp2615 driver uses the USB device serial string as the i2c adapter
+name but does not make sure that the string exists.
+
+Verify that the device has a serial number before accessing it to avoid
+triggering a NULL-pointer dereference (e.g. with malicious devices).
+
+Fixes: 4a7695429ead ("i2c: cp2615: add i2c driver for Silicon Labs' CP2615 Digital Audio Bridge")
+Cc: stable@vger.kernel.org     # 5.13
+Cc: Bence Csókás <bence98@sch.bme.hu>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Reviewed-by: Bence Csókás <bence98@sch.bme.hu>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20260309075016.25612-1-johan@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/busses/i2c-cp2615.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-cp2615.c
++++ b/drivers/i2c/busses/i2c-cp2615.c
+@@ -298,6 +298,9 @@ cp2615_i2c_probe(struct usb_interface *u
+       if (!adap)
+               return -ENOMEM;
++      if (!usbdev->serial)
++              return -EINVAL;
++
+       strscpy(adap->name, usbdev->serial, sizeof(adap->name));
+       adap->owner = THIS_MODULE;
+       adap->dev.parent = &usbif->dev;
diff --git a/queue-5.15/i2c-cp2615-replace-deprecated-strncpy-with-strscpy.patch b/queue-5.15/i2c-cp2615-replace-deprecated-strncpy-with-strscpy.patch
new file mode 100644 (file)
index 0000000..22badbd
--- /dev/null
@@ -0,0 +1,53 @@
+From stable+bounces-227985-greg=kroah.com@vger.kernel.org Mon Mar 23 14:26:27 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Mar 2026 09:19:09 -0400
+Subject: i2c: cp2615: replace deprecated strncpy with strscpy
+To: stable@vger.kernel.org
+Cc: Justin Stitt <justinstitt@google.com>, Kees Cook <keescook@chromium.org>, Wolfram Sang <wsa@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260323131910.1715046-1-sashal@kernel.org>
+
+From: Justin Stitt <justinstitt@google.com>
+
+[ Upstream commit e2def33f9ee1b1a8cda4ec5cde69840b5708f068 ]
+
+`strncpy` is deprecated for use on NUL-terminated destination strings [1].
+
+We should prefer more robust and less ambiguous string interfaces.
+
+We expect name to be NUL-terminated based on its numerous uses with
+functions that expect NUL-terminated strings.
+
+For example in i2c-core-base.c +1533:
+| dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
+
+NUL-padding is not required as `adap` is already zero-alloacted with:
+| adap = devm_kzalloc(&usbif->dev, sizeof(struct i2c_adapter), GFP_KERNEL);
+
+With the above in mind, a suitable replacement is `strscpy` [2] due to
+the fact that it guarantees NUL-termination on the destination buffer
+without unnecessarily NUL-padding.
+
+Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1]
+Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2]
+Link: https://github.com/KSPP/linux/issues/90
+Signed-off-by: Justin Stitt <justinstitt@google.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Stable-dep-of: aa79f996eb41 ("i2c: cp2615: fix serial string NULL-deref at probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/busses/i2c-cp2615.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/i2c/busses/i2c-cp2615.c
++++ b/drivers/i2c/busses/i2c-cp2615.c
+@@ -298,7 +298,7 @@ cp2615_i2c_probe(struct usb_interface *u
+       if (!adap)
+               return -ENOMEM;
+-      strncpy(adap->name, usbdev->serial, sizeof(adap->name) - 1);
++      strscpy(adap->name, usbdev->serial, sizeof(adap->name));
+       adap->owner = THIS_MODULE;
+       adap->dev.parent = &usbif->dev;
+       adap->dev.of_node = usbif->dev.of_node;
diff --git a/queue-5.15/ksmbd-fix-dangling-pointer-in-krb_authenticate.patch b/queue-5.15/ksmbd-fix-dangling-pointer-in-krb_authenticate.patch
new file mode 100644 (file)
index 0000000..761ede4
--- /dev/null
@@ -0,0 +1,41 @@
+From stable+bounces-222537-greg=kroah.com@vger.kernel.org Mon Mar  2 08:53:14 2026
+From: Leon Chen <leonchen.oss@139.com>
+Date: Mon,  2 Mar 2026 15:52:47 +0800
+Subject: ksmbd: Fix dangling pointer in krb_authenticate
+To: seanheelan@gmail.com, linkinjeon@kernel.org, stfrench@microsoft.com, stable@vger.kernel.org
+Message-ID: <20260302075247.3519-1-leonchen.oss@139.com>
+
+From: Sean Heelan <seanheelan@gmail.com>
+
+[ Upstream commit 1e440d5b25b7efccb3defe542a73c51005799a5f ]
+
+krb_authenticate frees sess->user and does not set the pointer
+to NULL. It calls ksmbd_krb5_authenticate to reinitialise
+sess->user but that function may return without doing so. If
+that happens then smb2_sess_setup, which calls krb_authenticate,
+will be accessing free'd memory when it later uses sess->user.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Sean Heelan <seanheelan@gmail.com>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Leon Chen <leonchen.oss@139.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ksmbd/smb2pdu.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -1619,8 +1619,10 @@ static int krb5_authenticate(struct ksmb
+       if (prev_sess_id && prev_sess_id != sess->id)
+               destroy_previous_session(conn, sess->user, prev_sess_id);
+-      if (sess->state == SMB2_SESSION_VALID)
++      if (sess->state == SMB2_SESSION_VALID) {
+               ksmbd_free_user(sess->user);
++              sess->user = NULL;
++      }
+       retval = ksmbd_krb5_authenticate(sess, in_blob, in_len,
+                                        out_blob, &out_len);
diff --git a/queue-5.15/ksmbd-fix-potencial-oob-in-get_file_all_info-for-compound-requests.patch b/queue-5.15/ksmbd-fix-potencial-oob-in-get_file_all_info-for-compound-requests.patch
new file mode 100644 (file)
index 0000000..30e8add
--- /dev/null
@@ -0,0 +1,76 @@
+From stable+bounces-231265-greg=kroah.com@vger.kernel.org Mon Mar 30 21:13:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Mar 2026 15:10:37 -0400
+Subject: ksmbd: fix potencial OOB in get_file_all_info() for compound requests
+To: stable@vger.kernel.org
+Cc: Namjae Jeon <linkinjeon@kernel.org>, Asim Viladi Oglu Manizada <manizada@pm.me>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260330191037.1035485-1-sashal@kernel.org>
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit beef2634f81f1c086208191f7228bce1d366493d ]
+
+When a compound request consists of QUERY_DIRECTORY + QUERY_INFO
+(FILE_ALL_INFORMATION) and the first command consumes nearly the entire
+max_trans_size, get_file_all_info() would blindly call smbConvertToUTF16()
+with PATH_MAX, causing out-of-bounds write beyond the response buffer.
+In get_file_all_info(), there was a missing validation check for
+the client-provided OutputBufferLength before copying the filename into
+FileName field of the smb2_file_all_info structure.
+If the filename length exceeds the available buffer space, it could lead to
+potential buffer overflows or memory corruption during smbConvertToUTF16
+conversion. This calculating the actual free buffer size using
+smb2_calc_max_out_buf_len() and returning -EINVAL if the buffer is
+insufficient and updating smbConvertToUTF16 to use the actual filename
+length (clamped by PATH_MAX) to ensure a safe copy operation.
+
+Cc: stable@vger.kernel.org
+Fixes: e2b76ab8b5c9 ("ksmbd: add support for read compound")
+Reported-by: Asim Viladi Oglu Manizada <manizada@pm.me>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+[ adapted variable declarations ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ksmbd/smb2pdu.c |   15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -4580,6 +4580,8 @@ static int get_file_all_info(struct ksmb
+       int conv_len;
+       char *filename;
+       u64 time;
++      int buf_free_len, filename_len;
++      struct smb2_query_info_req *req = ksmbd_req_buf_next(work);
+       if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
+               ksmbd_debug(SMB, "no right to read the attributes : 0x%x\n",
+@@ -4591,6 +4593,16 @@ static int get_file_all_info(struct ksmb
+       if (IS_ERR(filename))
+               return PTR_ERR(filename);
++      filename_len = strlen(filename);
++      buf_free_len = smb2_calc_max_out_buf_len(work,
++                      offsetof(struct smb2_query_info_rsp, Buffer) +
++                      offsetof(struct smb2_file_all_info, FileName),
++                      le32_to_cpu(req->OutputBufferLength));
++      if (buf_free_len < (filename_len + 1) * 2) {
++              kfree(filename);
++              return -EINVAL;
++      }
++
+       inode = file_inode(fp->filp);
+       generic_fillattr(file_mnt_user_ns(fp->filp), inode, &stat);
+@@ -4622,7 +4634,8 @@ static int get_file_all_info(struct ksmb
+       file_info->Mode = fp->coption;
+       file_info->AlignmentRequirement = 0;
+       conv_len = smbConvertToUTF16((__le16 *)file_info->FileName, filename,
+-                                   PATH_MAX, conn->local_nls, 0);
++                                   min(filename_len, PATH_MAX),
++                                   conn->local_nls, 0);
+       conv_len *= 2;
+       file_info->FileNameLength = cpu_to_le32(conv_len);
+       rsp->OutputBufferLength =
diff --git a/queue-5.15/ksmbd-fix-refcount-leak-when-invalid-session-is-found-on-session-lookup.patch b/queue-5.15/ksmbd-fix-refcount-leak-when-invalid-session-is-found-on-session-lookup.patch
new file mode 100644 (file)
index 0000000..c620156
--- /dev/null
@@ -0,0 +1,43 @@
+From stable+bounces-219895-greg=kroah.com@vger.kernel.org Fri Feb 27 04:16:14 2026
+From: Li hongliang <1468888505@139.com>
+Date: Fri, 27 Feb 2026 11:16:01 +0800
+Subject: ksmbd: Fix refcount leak when invalid session is found on session lookup
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org, linkinjeon@kernel.org
+Cc: patches@lists.linux.dev, linux-kernel@vger.kernel.org, roger.andersen@protonmail.com, spolu@dust.tt, stfrench@microsoft.com, senozhatsky@chromium.org, sfrench@samba.org, hyc.lee@gmail.com, sashal@kernel.org, linux-cifs@vger.kernel.org
+Message-ID: <20260227031601.1548925-1-1468888505@139.com>
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit cafb57f7bdd57abba87725eb4e82bbdca4959644 ]
+
+When a session is found but its state is not SMB2_SESSION_VALID, It
+indicates that no valid session was found, but it is missing to decrement
+the reference count acquired by the session lookup, which results in
+a reference count leak. This patch fixes the issue by explicitly calling
+ksmbd_user_session_put to release the reference to the session.
+
+Cc: stable@vger.kernel.org
+Reported-by: Alexandre <roger.andersen@protonmail.com>
+Reported-by: Stanislas Polu <spolu@dust.tt>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ksmbd/mgmt/user_session.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/ksmbd/mgmt/user_session.c
++++ b/fs/ksmbd/mgmt/user_session.c
+@@ -302,8 +302,10 @@ struct ksmbd_session *ksmbd_session_look
+       sess = ksmbd_session_lookup(conn, id);
+       if (!sess && conn->binding)
+               sess = ksmbd_session_lookup_slowpath(id);
+-      if (sess && sess->state != SMB2_SESSION_VALID)
++      if (sess && sess->state != SMB2_SESSION_VALID) {
++              ksmbd_user_session_put(sess);
+               sess = NULL;
++      }
+       return sess;
+ }
diff --git a/queue-5.15/ksmbd-replace-hardcoded-hdr2_len-with-offsetof-in-smb2_calc_max_out_buf_len.patch b/queue-5.15/ksmbd-replace-hardcoded-hdr2_len-with-offsetof-in-smb2_calc_max_out_buf_len.patch
new file mode 100644 (file)
index 0000000..e2724d9
--- /dev/null
@@ -0,0 +1,80 @@
+From stable+bounces-231242-greg=kroah.com@vger.kernel.org Mon Mar 30 16:53:40 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Mar 2026 10:40:42 -0400
+Subject: ksmbd: replace hardcoded hdr2_len with offsetof() in smb2_calc_max_out_buf_len()
+To: stable@vger.kernel.org
+Cc: Namjae Jeon <linkinjeon@kernel.org>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260330144043.880361-1-sashal@kernel.org>
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit 0e55f63dd08f09651d39e1b709a91705a8a0ddcb ]
+
+After this commit (e2b76ab8b5c9 "ksmbd: add support for read compound"),
+response buffer management was changed to use dynamic iov array.
+In the new design, smb2_calc_max_out_buf_len() expects the second
+argument (hdr2_len) to be the offset of ->Buffer field in the
+response structure, not a hardcoded magic number.
+Fix the remaining call sites to use the correct offsetof() value.
+
+Cc: stable@vger.kernel.org
+Fixes: e2b76ab8b5c9 ("ksmbd: add support for read compound")
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+[ adapted `req->CtlCode` field access to `req->CntCode` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ksmbd/smb2pdu.c |   20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -4123,8 +4123,9 @@ int smb2_query_dir(struct ksmbd_work *wo
+       d_info.wptr = (char *)rsp->Buffer;
+       d_info.rptr = (char *)rsp->Buffer;
+       d_info.out_buf_len =
+-              smb2_calc_max_out_buf_len(work, 8,
+-                                        le32_to_cpu(req->OutputBufferLength));
++              smb2_calc_max_out_buf_len(work,
++                              offsetof(struct smb2_query_directory_rsp, Buffer),
++                              le32_to_cpu(req->OutputBufferLength));
+       if (d_info.out_buf_len < 0) {
+               rc = -EINVAL;
+               goto err_out;
+@@ -4374,8 +4375,9 @@ static int smb2_get_ea(struct ksmbd_work
+       }
+       buf_free_len =
+-              smb2_calc_max_out_buf_len(work, 8,
+-                                        le32_to_cpu(req->OutputBufferLength));
++              smb2_calc_max_out_buf_len(work,
++                              offsetof(struct smb2_query_info_rsp, Buffer),
++                              le32_to_cpu(req->OutputBufferLength));
+       if (buf_free_len < 0)
+               return -EINVAL;
+@@ -4685,8 +4687,9 @@ static void get_file_stream_info(struct
+       file_info = (struct smb2_file_stream_info *)rsp->Buffer;
+       buf_free_len =
+-              smb2_calc_max_out_buf_len(work, 8,
+-                                        le32_to_cpu(req->OutputBufferLength));
++              smb2_calc_max_out_buf_len(work,
++                              offsetof(struct smb2_query_info_rsp, Buffer),
++                              le32_to_cpu(req->OutputBufferLength));
+       if (buf_free_len < 0)
+               goto out;
+@@ -7726,8 +7729,9 @@ int smb2_ioctl(struct ksmbd_work *work)
+       buffer = (char *)req + le32_to_cpu(req->InputOffset);
+       cnt_code = le32_to_cpu(req->CntCode);
+-      ret = smb2_calc_max_out_buf_len(work, 48,
+-                                      le32_to_cpu(req->MaxOutputResponse));
++      ret = smb2_calc_max_out_buf_len(work,
++                      offsetof(struct smb2_ioctl_rsp, Buffer),
++                      le32_to_cpu(req->MaxOutputResponse));
+       if (ret < 0) {
+               rsp->hdr.Status = STATUS_INVALID_PARAMETER;
+               goto out;
diff --git a/queue-5.15/kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch b/queue-5.15/kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch
new file mode 100644 (file)
index 0000000..e4322ca
--- /dev/null
@@ -0,0 +1,87 @@
+From stable+bounces-232616-greg=kroah.com@vger.kernel.org Wed Apr  1 02:22:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Mar 2026 20:19:21 -0400
+Subject: KVM: x86/mmu: Drop/zap existing present SPTE even when creating an MMIO SPTE
+To: stable@vger.kernel.org
+Cc: Sean Christopherson <seanjc@google.com>, Alexander Bulekov <bkov@amazon.com>, Fred Griffoul <fgriffo@amazon.co.uk>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260401001921.3983428-1-sashal@kernel.org>
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit aad885e774966e97b675dfe928da164214a71605 ]
+
+When installing an emulated MMIO SPTE, do so *after* dropping/zapping the
+existing SPTE (if it's shadow-present).  While commit a54aa15c6bda3 was
+right about it being impossible to convert a shadow-present SPTE to an
+MMIO SPTE due to a _guest_ write, it failed to account for writes to guest
+memory that are outside the scope of KVM.
+
+E.g. if host userspace modifies a shadowed gPTE to switch from a memslot
+to emulted MMIO and then the guest hits a relevant page fault, KVM will
+install the MMIO SPTE without first zapping the shadow-present SPTE.
+
+  ------------[ cut here ]------------
+  is_shadow_present_pte(*sptep)
+  WARNING: arch/x86/kvm/mmu/mmu.c:484 at mark_mmio_spte+0xb2/0xc0 [kvm], CPU#0: vmx_ept_stale_r/4292
+  Modules linked in: kvm_intel kvm irqbypass
+  CPU: 0 UID: 1000 PID: 4292 Comm: vmx_ept_stale_r Not tainted 7.0.0-rc2-eafebd2d2ab0-sink-vm #319 PREEMPT
+  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
+  RIP: 0010:mark_mmio_spte+0xb2/0xc0 [kvm]
+  Call Trace:
+   <TASK>
+   mmu_set_spte+0x237/0x440 [kvm]
+   ept_page_fault+0x535/0x7f0 [kvm]
+   kvm_mmu_do_page_fault+0xee/0x1f0 [kvm]
+   kvm_mmu_page_fault+0x8d/0x620 [kvm]
+   vmx_handle_exit+0x18c/0x5a0 [kvm_intel]
+   kvm_arch_vcpu_ioctl_run+0xc55/0x1c20 [kvm]
+   kvm_vcpu_ioctl+0x2d5/0x980 [kvm]
+   __x64_sys_ioctl+0x8a/0xd0
+   do_syscall_64+0xb5/0x730
+   entry_SYSCALL_64_after_hwframe+0x4b/0x53
+  RIP: 0033:0x47fa3f
+   </TASK>
+  ---[ end trace 0000000000000000 ]---
+
+Reported-by: Alexander Bulekov <bkov@amazon.com>
+Debugged-by: Alexander Bulekov <bkov@amazon.com>
+Suggested-by: Fred Griffoul <fgriffo@amazon.co.uk>
+Fixes: a54aa15c6bda3 ("KVM: x86/mmu: Handle MMIO SPTEs directly in mmu_set_spte()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+[ replaced `kvm_flush_remote_tlbs_gfn()` with `kvm_flush_remote_tlbs_with_address()` and omitted `pf_mmio_spte_created` stat counter ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/mmu/mmu.c |   13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -2717,11 +2717,6 @@ static int mmu_set_spte(struct kvm_vcpu
+       pgprintk("%s: spte %llx write_fault %d gfn %llx\n", __func__,
+                *sptep, write_fault, gfn);
+-      if (unlikely(is_noslot_pfn(pfn))) {
+-              mark_mmio_spte(vcpu, sptep, gfn, pte_access);
+-              return RET_PF_EMULATE;
+-      }
+-
+       if (is_shadow_present_pte(*sptep)) {
+               /*
+                * If we overwrite a PTE page pointer with a 2MB PMD, unlink
+@@ -2743,6 +2738,14 @@ static int mmu_set_spte(struct kvm_vcpu
+                       was_rmapped = 1;
+       }
++      if (unlikely(is_noslot_pfn(pfn))) {
++              mark_mmio_spte(vcpu, sptep, gfn, pte_access);
++              if (flush)
++                      kvm_flush_remote_tlbs_with_address(vcpu->kvm, gfn,
++                                      KVM_PAGES_PER_HPAGE(level));
++              return RET_PF_EMULATE;
++      }
++
+       set_spte_ret = set_spte(vcpu, sptep, pte_access, level, gfn, pfn,
+                               speculative, true, host_writable);
+       if (set_spte_ret & SET_SPTE_WRITE_PROTECTED_PT) {
diff --git a/queue-5.15/mm-huge_memory-fix-folio-isn-t-locked-in-softleaf_to_folio.patch b/queue-5.15/mm-huge_memory-fix-folio-isn-t-locked-in-softleaf_to_folio.patch
new file mode 100644 (file)
index 0000000..e464c4c
--- /dev/null
@@ -0,0 +1,101 @@
+From stable+bounces-231432-greg=kroah.com@vger.kernel.org Tue Mar 31 16:28:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Mar 2026 10:25:47 -0400
+Subject: mm/huge_memory: fix folio isn't locked in softleaf_to_folio()
+To: stable@vger.kernel.org
+Cc: Jinjiang Tu <tujinjiang@huawei.com>, "David Hildenbrand (Arm)" <david@kernel.org>, "Lorenzo Stoakes (Oracle)" <ljs@kernel.org>, Barry Song <baohua@kernel.org>, Kefeng Wang <wangkefeng.wang@huawei.com>, Liam Howlett <liam.howlett@oracle.com>, Michal Hocko <mhocko@suse.com>, Mike Rapoport <rppt@kernel.org>, Nanyong Sun <sunnanyong@huawei.com>, Ryan Roberts <ryan.roberts@arm.com>, Suren Baghdasaryan <surenb@google.com>, Vlastimil Babka <vbabka@kernel.org>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260331142547.2463775-1-sashal@kernel.org>
+
+From: Jinjiang Tu <tujinjiang@huawei.com>
+
+[ Upstream commit 4c5e7f0fcd592801c9cc18f29f80fbee84eb8669 ]
+
+On arm64 server, we found folio that get from migration entry isn't locked
+in softleaf_to_folio().  This issue triggers when mTHP splitting and
+zap_nonpresent_ptes() races, and the root cause is lack of memory barrier
+in softleaf_to_folio().  The race is as follows:
+
+       CPU0                                             CPU1
+
+deferred_split_scan()                              zap_nonpresent_ptes()
+  lock folio
+  split_folio()
+    unmap_folio()
+      change ptes to migration entries
+    __split_folio_to_order()                         softleaf_to_folio()
+      set flags(including PG_locked) for tail pages    folio = pfn_folio(softleaf_to_pfn(entry))
+      smp_wmb()                                        VM_WARN_ON_ONCE(!folio_test_locked(folio))
+      prep_compound_page() for tail pages
+
+In __split_folio_to_order(), smp_wmb() guarantees page flags of tail pages
+are visible before the tail page becomes non-compound.  smp_wmb() should
+be paired with smp_rmb() in softleaf_to_folio(), which is missed.  As a
+result, if zap_nonpresent_ptes() accesses migration entry that stores tail
+pfn, softleaf_to_folio() may see the updated compound_head of tail page
+before page->flags.
+
+This issue will trigger VM_WARN_ON_ONCE() in pfn_swap_entry_folio()
+because of the race between folio split and zap_nonpresent_ptes()
+leading to a folio incorrectly undergoing modification without a folio
+lock being held.
+
+This is a BUG_ON() before commit 93976a20345b ("mm: eliminate further
+swapops predicates"), which in merged in v6.19-rc1.
+
+To fix it, add missing smp_rmb() if the softleaf entry is migration entry
+in softleaf_to_folio() and softleaf_to_page().
+
+[tujinjiang@huawei.com: update function name and comments]
+  Link: https://lkml.kernel.org/r/20260321075214.3305564-1-tujinjiang@huawei.com
+Link: https://lkml.kernel.org/r/20260319012541.4158561-1-tujinjiang@huawei.com
+Fixes: e9b61f19858a ("thp: reintroduce split_huge_page()")
+Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
+Acked-by: David Hildenbrand (Arm) <david@kernel.org>
+Reviewed-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Barry Song <baohua@kernel.org>
+Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Nanyong Sun <sunnanyong@huawei.com>
+Cc: Ryan Roberts <ryan.roberts@arm.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ adapted fix from leafops.h softleaf_to_page()/softleaf_to_folio() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/swapops.h |   20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+--- a/include/linux/swapops.h
++++ b/include/linux/swapops.h
+@@ -251,11 +251,21 @@ static inline struct page *pfn_swap_entr
+ {
+       struct page *p = pfn_to_page(swp_offset(entry));
+-      /*
+-       * Any use of migration entries may only occur while the
+-       * corresponding page is locked
+-       */
+-      BUG_ON(is_migration_entry(entry) && !PageLocked(p));
++      if (is_migration_entry(entry)) {
++              /*
++               * Ensure we do not race with split, which might alter tail
++               * pages into new folios and thus result in observing an
++               * unlocked folio.
++               * This matches the write barrier in __split_folio_to_order().
++               */
++              smp_rmb();
++
++              /*
++               * Any use of migration entries may only occur while the
++               * corresponding page is locked
++               */
++              BUG_ON(!PageLocked(p));
++      }
+       return p;
+ }
diff --git a/queue-5.15/net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch b/queue-5.15/net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch
new file mode 100644 (file)
index 0000000..6808eba
--- /dev/null
@@ -0,0 +1,147 @@
+From stable+bounces-232613-greg=kroah.com@vger.kernel.org Wed Apr  1 02:02:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Mar 2026 20:02:38 -0400
+Subject: net: macb: Move devm_{free,request}_irq() out of spin lock area
+To: stable@vger.kernel.org
+Cc: "Kevin Hao" <haokexin@gmail.com>, "Théo Lebrun" <theo.lebrun@bootlin.com>, "Jakub Kicinski" <kuba@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260401000238.3954205-1-sashal@kernel.org>
+
+From: Kevin Hao <haokexin@gmail.com>
+
+[ Upstream commit 317e49358ebbf6390fa439ef3c142f9239dd25fb ]
+
+The devm_free_irq() and devm_request_irq() functions should not be
+executed in an atomic context.
+
+During device suspend, all userspace processes and most kernel threads
+are frozen. Additionally, we flush all tx/rx status, disable all macb
+interrupts, and halt rx operations. Therefore, it is safe to split the
+region protected by bp->lock into two independent sections, allowing
+devm_free_irq() and devm_request_irq() to run in a non-atomic context.
+This modification resolves the following lockdep warning:
+  BUG: sleeping function called from invalid context at kernel/locking/mutex.c:591
+  in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 501, name: rtcwake
+  preempt_count: 1, expected: 0
+  RCU nest depth: 1, expected: 0
+  7 locks held by rtcwake/501:
+   #0: ffff0008038c3408 (sb_writers#5){.+.+}-{0:0}, at: vfs_write+0xf8/0x368
+   #1: ffff0008049a5e88 (&of->mutex#2){+.+.}-{4:4}, at: kernfs_fop_write_iter+0xbc/0x1c8
+   #2: ffff00080098d588 (kn->active#70){.+.+}-{0:0}, at: kernfs_fop_write_iter+0xcc/0x1c8
+   #3: ffff800081c84888 (system_transition_mutex){+.+.}-{4:4}, at: pm_suspend+0x1ec/0x290
+   #4: ffff0008009ba0f8 (&dev->mutex){....}-{4:4}, at: device_suspend+0x118/0x4f0
+   #5: ffff800081d00458 (rcu_read_lock){....}-{1:3}, at: rcu_lock_acquire+0x4/0x48
+   #6: ffff0008031fb9e0 (&bp->lock){-.-.}-{3:3}, at: macb_suspend+0x144/0x558
+  irq event stamp: 8682
+  hardirqs last  enabled at (8681): [<ffff8000813c7d7c>] _raw_spin_unlock_irqrestore+0x44/0x88
+  hardirqs last disabled at (8682): [<ffff8000813c7b58>] _raw_spin_lock_irqsave+0x38/0x98
+  softirqs last  enabled at (7322): [<ffff8000800f1b4c>] handle_softirqs+0x52c/0x588
+  softirqs last disabled at (7317): [<ffff800080010310>] __do_softirq+0x20/0x2c
+  CPU: 1 UID: 0 PID: 501 Comm: rtcwake Not tainted 7.0.0-rc3-next-20260310-yocto-standard+ #125 PREEMPT
+  Hardware name: ZynqMP ZCU102 Rev1.1 (DT)
+  Call trace:
+   show_stack+0x24/0x38 (C)
+   __dump_stack+0x28/0x38
+   dump_stack_lvl+0x64/0x88
+   dump_stack+0x18/0x24
+   __might_resched+0x200/0x218
+   __might_sleep+0x38/0x98
+   __mutex_lock_common+0x7c/0x1378
+   mutex_lock_nested+0x38/0x50
+   free_irq+0x68/0x2b0
+   devm_irq_release+0x24/0x38
+   devres_release+0x40/0x80
+   devm_free_irq+0x48/0x88
+   macb_suspend+0x298/0x558
+   device_suspend+0x218/0x4f0
+   dpm_suspend+0x244/0x3a0
+   dpm_suspend_start+0x50/0x78
+   suspend_devices_and_enter+0xec/0x560
+   pm_suspend+0x194/0x290
+   state_store+0x110/0x158
+   kobj_attr_store+0x1c/0x30
+   sysfs_kf_write+0xa8/0xd0
+   kernfs_fop_write_iter+0x11c/0x1c8
+   vfs_write+0x248/0x368
+   ksys_write+0x7c/0xf8
+   __arm64_sys_write+0x28/0x40
+   invoke_syscall+0x4c/0xe8
+   el0_svc_common+0x98/0xf0
+   do_el0_svc+0x28/0x40
+   el0_svc+0x54/0x1e0
+   el0t_64_sync_handler+0x84/0x130
+   el0t_64_sync+0x198/0x1a0
+
+Fixes: 558e35ccfe95 ("net: macb: WoL support for GEM type of Ethernet controller")
+Cc: stable@vger.kernel.org
+Reviewed-by: Théo Lebrun <theo.lebrun@bootlin.com>
+Signed-off-by: Kevin Hao <haokexin@gmail.com>
+Link: https://patch.msgid.link/20260318-macb-irq-v2-1-f1179768ab24@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ adapted WoL register writes to use MACB_BIT(MAG) instead of tmp variable ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c |   13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -4961,6 +4961,8 @@ static int __maybe_unused macb_suspend(s
+                       if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                               queue_writel(queue, ISR, -1);
+               }
++              spin_unlock_irqrestore(&bp->lock, flags);
++
+               /* Change interrupt handler and
+                * Enable WoL IRQ on queue 0
+                */
+@@ -4972,11 +4974,12 @@ static int __maybe_unused macb_suspend(s
+                               dev_err(dev,
+                                       "Unable to request IRQ %d (error %d)\n",
+                                       bp->queues[0].irq, err);
+-                              spin_unlock_irqrestore(&bp->lock, flags);
+                               return err;
+                       }
++                      spin_lock_irqsave(&bp->lock, flags);
+                       queue_writel(bp->queues, IER, GEM_BIT(WOL));
+                       gem_writel(bp, WOL, MACB_BIT(MAG));
++                      spin_unlock_irqrestore(&bp->lock, flags);
+               } else {
+                       err = devm_request_irq(dev, bp->queues[0].irq, macb_wol_interrupt,
+                                              IRQF_SHARED, netdev->name, bp->queues);
+@@ -4984,13 +4987,13 @@ static int __maybe_unused macb_suspend(s
+                               dev_err(dev,
+                                       "Unable to request IRQ %d (error %d)\n",
+                                       bp->queues[0].irq, err);
+-                              spin_unlock_irqrestore(&bp->lock, flags);
+                               return err;
+                       }
++                      spin_lock_irqsave(&bp->lock, flags);
+                       queue_writel(bp->queues, IER, MACB_BIT(WOL));
+                       macb_writel(bp, WOL, MACB_BIT(MAG));
++                      spin_unlock_irqrestore(&bp->lock, flags);
+               }
+-              spin_unlock_irqrestore(&bp->lock, flags);
+               enable_irq_wake(bp->queues[0].irq);
+       }
+@@ -5052,6 +5055,8 @@ static int __maybe_unused macb_resume(st
+               queue_readl(bp->queues, ISR);
+               if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
+                       queue_writel(bp->queues, ISR, -1);
++              spin_unlock_irqrestore(&bp->lock, flags);
++
+               /* Replace interrupt handler on queue 0 */
+               devm_free_irq(dev, bp->queues[0].irq, bp->queues);
+               err = devm_request_irq(dev, bp->queues[0].irq, macb_interrupt,
+@@ -5060,10 +5065,8 @@ static int __maybe_unused macb_resume(st
+                       dev_err(dev,
+                               "Unable to request IRQ %d (error %d)\n",
+                               bp->queues[0].irq, err);
+-                      spin_unlock_irqrestore(&bp->lock, flags);
+                       return err;
+               }
+-              spin_unlock_irqrestore(&bp->lock, flags);
+               disable_irq_wake(bp->queues[0].irq);
diff --git a/queue-5.15/net-rfkill-prevent-unlimited-numbers-of-rfkill-events-from-being-created.patch b/queue-5.15/net-rfkill-prevent-unlimited-numbers-of-rfkill-events-from-being-created.patch
new file mode 100644 (file)
index 0000000..b9bd735
--- /dev/null
@@ -0,0 +1,137 @@
+From stable+bounces-235831-greg=kroah.com@vger.kernel.org Sun Apr 12 18:57:53 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Apr 2026 12:57:46 -0400
+Subject: net: rfkill: prevent unlimited numbers of rfkill events from being created
+To: stable@vger.kernel.org
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Johannes Berg <johannes@sipsolutions.net>, Yuan Tan <yuantan098@gmail.com>, Yifan Wu <yifanwucs@gmail.com>, Juefei Pu <tomapufckgml@gmail.com>, Xin Liu <bird@lzu.edu.cn>, stable <stable@kernel.org>, Johannes Berg <johannes.berg@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260412165746.2348467-1-sashal@kernel.org>
+
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+[ Upstream commit ea245d78dec594372e27d8c79616baf49e98a4a1 ]
+
+Userspace can create an unlimited number of rfkill events if the system
+is so configured, while not consuming them from the rfkill file
+descriptor, causing a potential out of memory situation.  Prevent this
+from bounding the number of pending rfkill events at a "large" number
+(i.e. 1000) to prevent abuses like this.
+
+Cc: Johannes Berg <johannes@sipsolutions.net>
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://patch.msgid.link/2026033013-disfigure-scroll-e25e@gregkh
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[ replaced `scoped_guard()` with explicit `mutex_lock()`/`mutex_unlock()` calls ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rfkill/core.c |   37 +++++++++++++++++++++++++------------
+ 1 file changed, 25 insertions(+), 12 deletions(-)
+
+--- a/net/rfkill/core.c
++++ b/net/rfkill/core.c
+@@ -72,11 +72,14 @@ struct rfkill_int_event {
+       struct rfkill_event_ext ev;
+ };
++/* Max rfkill events that can be "in-flight" for one data source */
++#define MAX_RFKILL_EVENT      1000
+ struct rfkill_data {
+       struct list_head        list;
+       struct list_head        events;
+       struct mutex            mtx;
+       wait_queue_head_t       read_wait;
++      u32                     event_count;
+       bool                    input_handler;
+       u8                      max_size;
+ };
+@@ -254,10 +257,12 @@ static void rfkill_global_led_trigger_un
+ }
+ #endif /* CONFIG_RFKILL_LEDS */
+-static void rfkill_fill_event(struct rfkill_event_ext *ev,
+-                            struct rfkill *rfkill,
+-                            enum rfkill_operation op)
++static int rfkill_fill_event(struct rfkill_int_event *int_ev,
++                           struct rfkill *rfkill,
++                           struct rfkill_data *data,
++                           enum rfkill_operation op)
+ {
++      struct rfkill_event_ext *ev = &int_ev->ev;
+       unsigned long flags;
+       ev->idx = rfkill->idx;
+@@ -270,6 +275,16 @@ static void rfkill_fill_event(struct rfk
+                                       RFKILL_BLOCK_SW_PREV));
+       ev->hard_block_reasons = rfkill->hard_block_reasons;
+       spin_unlock_irqrestore(&rfkill->lock, flags);
++
++      mutex_lock(&data->mtx);
++      if (data->event_count++ > MAX_RFKILL_EVENT) {
++              data->event_count--;
++              mutex_unlock(&data->mtx);
++              return -ENOSPC;
++      }
++      list_add_tail(&int_ev->list, &data->events);
++      mutex_unlock(&data->mtx);
++      return 0;
+ }
+ static void rfkill_send_events(struct rfkill *rfkill, enum rfkill_operation op)
+@@ -281,10 +296,10 @@ static void rfkill_send_events(struct rf
+               ev = kzalloc(sizeof(*ev), GFP_KERNEL);
+               if (!ev)
+                       continue;
+-              rfkill_fill_event(&ev->ev, rfkill, op);
+-              mutex_lock(&data->mtx);
+-              list_add_tail(&ev->list, &data->events);
+-              mutex_unlock(&data->mtx);
++              if (rfkill_fill_event(ev, rfkill, data, op)) {
++                      kfree(ev);
++                      continue;
++              }
+               wake_up_interruptible(&data->read_wait);
+       }
+ }
+@@ -1149,7 +1164,6 @@ static int rfkill_fop_open(struct inode
+       init_waitqueue_head(&data->read_wait);
+       mutex_lock(&rfkill_global_mutex);
+-      mutex_lock(&data->mtx);
+       /*
+        * start getting events from elsewhere but hold mtx to get
+        * startup events added first
+@@ -1159,11 +1173,10 @@ static int rfkill_fop_open(struct inode
+               ev = kzalloc(sizeof(*ev), GFP_KERNEL);
+               if (!ev)
+                       goto free;
+-              rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD);
+-              list_add_tail(&ev->list, &data->events);
++              if (rfkill_fill_event(ev, rfkill, data, RFKILL_OP_ADD))
++                      kfree(ev);
+       }
+       list_add(&data->list, &rfkill_fds);
+-      mutex_unlock(&data->mtx);
+       mutex_unlock(&rfkill_global_mutex);
+       file->private_data = data;
+@@ -1171,7 +1184,6 @@ static int rfkill_fop_open(struct inode
+       return stream_open(inode, file);
+  free:
+-      mutex_unlock(&data->mtx);
+       mutex_unlock(&rfkill_global_mutex);
+       mutex_destroy(&data->mtx);
+       list_for_each_entry_safe(ev, tmp, &data->events, list)
+@@ -1232,6 +1244,7 @@ static ssize_t rfkill_fop_read(struct fi
+               ret = -EFAULT;
+       list_del(&ev->list);
++      data->event_count--;
+       kfree(ev);
+  out:
+       mutex_unlock(&data->mtx);
diff --git a/queue-5.15/revert-mptcp-add-needs_id-for-netlink-appending-addr.patch b/queue-5.15/revert-mptcp-add-needs_id-for-netlink-appending-addr.patch
new file mode 100644 (file)
index 0000000..de91ecb
--- /dev/null
@@ -0,0 +1,109 @@
+From stable+bounces-235866-greg=kroah.com@vger.kernel.org Mon Apr 13 00:56:25 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Apr 2026 18:52:06 -0400
+Subject: Revert "mptcp: add needs_id for netlink appending addr"
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Geliang Tang <geliang@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260412225206.2462132-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 8e2760eaab778494fc1fa257031e0e1799647f46 ]
+
+This commit was originally adding the ability to add MPTCP endpoints
+with ID 0 by accident. The in-kernel PM, handling MPTCP endpoints at the
+net namespace level, is not supposed to handle endpoints with such ID,
+because this ID 0 is reserved to the initial subflow, as mentioned in
+the MPTCPv1 protocol [1], a per-connection setting.
+
+Note that 'ip mptcp endpoint add id 0' stops early with an error, but
+other tools might still request the in-kernel PM to create MPTCP
+endpoints with this restricted ID 0.
+
+In other words, it was wrong to call the mptcp_pm_has_addr_attr_id
+helper to check whether the address ID attribute is set: if it was set
+to 0, a new MPTCP endpoint would be created with ID 0, which is not
+expected, and might cause various issues later.
+
+Fixes: 584f38942626 ("mptcp: add needs_id for netlink appending addr")
+Cc: stable@vger.kernel.org
+Link: https://datatracker.ietf.org/doc/html/rfc8684#section-3.2-9 [1]
+Reviewed-by: Geliang Tang <geliang@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260407-net-mptcp-revert-pm-needs-id-v2-1-7a25cbc324f8@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ adapted changes from pm_kernel.c to pm_netlink.c ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |   24 +++++-------------------
+ 1 file changed, 5 insertions(+), 19 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -972,8 +972,7 @@ static bool address_use_port(struct mptc
+ }
+ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
+-                                           struct mptcp_pm_addr_entry *entry,
+-                                           bool needs_id)
++                                           struct mptcp_pm_addr_entry *entry)
+ {
+       struct mptcp_pm_addr_entry *cur;
+       unsigned int addr_max;
+@@ -1000,7 +999,7 @@ static int mptcp_pm_nl_append_new_local_
+                       goto out;
+       }
+-      if (!entry->addr.id && needs_id) {
++      if (!entry->addr.id) {
+ find_next:
+               entry->addr.id = find_next_zero_bit(pernet->id_bitmap,
+                                                   MAX_ADDR_ID + 1,
+@@ -1011,7 +1010,7 @@ find_next:
+               }
+       }
+-      if (!entry->addr.id && needs_id)
++      if (!entry->addr.id)
+               goto out;
+       __set_bit(entry->addr.id, pernet->id_bitmap);
+@@ -1152,7 +1151,7 @@ int mptcp_pm_nl_get_local_id(struct mptc
+       entry->ifindex = 0;
+       entry->flags = 0;
+       entry->lsk = NULL;
+-      ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true);
++      ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
+       if (ret < 0)
+               kfree(entry);
+@@ -1374,18 +1373,6 @@ next:
+       return 0;
+ }
+-static bool mptcp_pm_has_addr_attr_id(const struct nlattr *attr,
+-                                    struct genl_info *info)
+-{
+-      struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
+-
+-      if (!nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr,
+-                                       mptcp_pm_addr_policy, info->extack) &&
+-          tb[MPTCP_PM_ADDR_ATTR_ID])
+-              return true;
+-      return false;
+-}
+-
+ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
+ {
+       struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
+@@ -1412,8 +1399,7 @@ static int mptcp_nl_cmd_add_addr(struct
+                       return ret;
+               }
+       }
+-      ret = mptcp_pm_nl_append_new_local_addr(pernet, entry,
+-                                              !mptcp_pm_has_addr_attr_id(attr, info));
++      ret = mptcp_pm_nl_append_new_local_addr(pernet, entry);
+       if (ret < 0) {
+               GENL_SET_ERR_MSG(info, "too many addresses or duplicate one");
+               if (entry->lsk)
diff --git a/queue-5.15/scsi-target-tcm_loop-drain-commands-in-target_reset-handler.patch b/queue-5.15/scsi-target-tcm_loop-drain-commands-in-target_reset-handler.patch
new file mode 100644 (file)
index 0000000..e6202f3
--- /dev/null
@@ -0,0 +1,148 @@
+From stable+bounces-232539-greg=kroah.com@vger.kernel.org Tue Mar 31 19:49:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Mar 2026 13:10:00 -0400
+Subject: scsi: target: tcm_loop: Drain commands in target_reset handler
+To: stable@vger.kernel.org
+Cc: Josef Bacik <josef@toxicpanda.com>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260331171000.2814732-1-sashal@kernel.org>
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 1333eee56cdf3f0cf67c6ab4114c2c9e0a952026 ]
+
+tcm_loop_target_reset() violates the SCSI EH contract: it returns SUCCESS
+without draining any in-flight commands.  The SCSI EH documentation
+(scsi_eh.rst) requires that when a reset handler returns SUCCESS the driver
+has made lower layers "forget about timed out scmds" and is ready for new
+commands.  Every other SCSI LLD (virtio_scsi, mpt3sas, ipr, scsi_debug,
+mpi3mr) enforces this by draining or completing outstanding commands before
+returning SUCCESS.
+
+Because tcm_loop_target_reset() doesn't drain, the SCSI EH reuses in-flight
+scsi_cmnd structures for recovery commands (e.g. TUR) while the target core
+still has async completion work queued for the old se_cmd.  The memset in
+queuecommand zeroes se_lun and lun_ref_active, causing
+transport_lun_remove_cmd() to skip its percpu_ref_put().  The leaked LUN
+reference prevents transport_clear_lun_ref() from completing, hanging
+configfs LUN unlink forever in D-state:
+
+  INFO: task rm:264 blocked for more than 122 seconds.
+  rm              D    0   264    258 0x00004000
+  Call Trace:
+   __schedule+0x3d0/0x8e0
+   schedule+0x36/0xf0
+   transport_clear_lun_ref+0x78/0x90 [target_core_mod]
+   core_tpg_remove_lun+0x28/0xb0 [target_core_mod]
+   target_fabric_port_unlink+0x50/0x60 [target_core_mod]
+   configfs_unlink+0x156/0x1f0 [configfs]
+   vfs_unlink+0x109/0x290
+   do_unlinkat+0x1d5/0x2d0
+
+Fix this by making tcm_loop_target_reset() actually drain commands:
+
+ 1. Issue TMR_LUN_RESET via tcm_loop_issue_tmr() to drain all commands that
+    the target core knows about (those not yet CMD_T_COMPLETE).
+
+ 2. Use blk_mq_tagset_busy_iter() to iterate all started requests and
+    flush_work() on each se_cmd â€” this drains any deferred completion work
+    for commands that already had CMD_T_COMPLETE set before the TMR (which
+    the TMR skips via __target_check_io_state()).  This is the same pattern
+    used by mpi3mr, scsi_debug, and libsas to drain outstanding commands
+    during reset.
+
+Fixes: e0eb5d38b732 ("scsi: target: tcm_loop: Use block cmd allocator for se_cmds")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-6
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Link: https://patch.msgid.link/27011aa34c8f6b1b94d2e3cf5655b6d037f53428.1773706803.git.josef@toxicpanda.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+[ added `bool reserved` parameter to `tcm_loop_flush_work_iter()` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/loopback/tcm_loop.c |   52 ++++++++++++++++++++++++++++++++-----
+ 1 file changed, 46 insertions(+), 6 deletions(-)
+
+--- a/drivers/target/loopback/tcm_loop.c
++++ b/drivers/target/loopback/tcm_loop.c
+@@ -26,6 +26,7 @@
+ #include <linux/slab.h>
+ #include <linux/types.h>
+ #include <linux/configfs.h>
++#include <linux/blk-mq.h>
+ #include <scsi/scsi.h>
+ #include <scsi/scsi_tcq.h>
+ #include <scsi/scsi_host.h>
+@@ -274,15 +275,27 @@ static int tcm_loop_device_reset(struct
+       return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
+ }
++static bool tcm_loop_flush_work_iter(struct request *rq, void *data, bool reserved)
++{
++      struct scsi_cmnd *sc = blk_mq_rq_to_pdu(rq);
++      struct tcm_loop_cmd *tl_cmd = scsi_cmd_priv(sc);
++      struct se_cmd *se_cmd = &tl_cmd->tl_se_cmd;
++
++      flush_work(&se_cmd->work);
++      return true;
++}
++
+ static int tcm_loop_target_reset(struct scsi_cmnd *sc)
+ {
+       struct tcm_loop_hba *tl_hba;
+       struct tcm_loop_tpg *tl_tpg;
++      struct Scsi_Host *sh = sc->device->host;
++      int ret;
+       /*
+        * Locate the tcm_loop_hba_t pointer
+        */
+-      tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
++      tl_hba = *(struct tcm_loop_hba **)shost_priv(sh);
+       if (!tl_hba) {
+               pr_err("Unable to perform device reset without active I_T Nexus\n");
+               return FAILED;
+@@ -291,11 +304,38 @@ static int tcm_loop_target_reset(struct
+        * Locate the tl_tpg pointer from TargetID in sc->device->id
+        */
+       tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
+-      if (tl_tpg) {
+-              tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE;
+-              return SUCCESS;
+-      }
+-      return FAILED;
++      if (!tl_tpg)
++              return FAILED;
++
++      /*
++       * Issue a LUN_RESET to drain all commands that the target core
++       * knows about.  This handles commands not yet marked CMD_T_COMPLETE.
++       */
++      ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun, 0, TMR_LUN_RESET);
++      if (ret != TMR_FUNCTION_COMPLETE)
++              return FAILED;
++
++      /*
++       * Flush any deferred target core completion work that may still be
++       * queued.  Commands that already had CMD_T_COMPLETE set before the TMR
++       * are skipped by the TMR drain, but their async completion work
++       * (transport_lun_remove_cmd â†’ percpu_ref_put, release_cmd â†’ scsi_done)
++       * may still be pending in target_completion_wq.
++       *
++       * The SCSI EH will reuse in-flight scsi_cmnd structures for recovery
++       * commands (e.g. TUR) immediately after this handler returns SUCCESS â€”
++       * if deferred work is still pending, the memset in queuecommand would
++       * zero the se_cmd while the work accesses it, leaking the LUN
++       * percpu_ref and hanging configfs unlink forever.
++       *
++       * Use blk_mq_tagset_busy_iter() to find all started requests and
++       * flush_work() on each â€” the same pattern used by mpi3mr, scsi_debug,
++       * and other SCSI drivers to drain outstanding commands during reset.
++       */
++      blk_mq_tagset_busy_iter(&sh->tag_set, tcm_loop_flush_work_iter, NULL);
++
++      tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE;
++      return SUCCESS;
+ }
+ static struct scsi_host_template tcm_loop_driver_template = {
diff --git a/queue-5.15/seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch b/queue-5.15/seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch
new file mode 100644 (file)
index 0000000..59e1058
--- /dev/null
@@ -0,0 +1,132 @@
+From stable+bounces-235864-greg=kroah.com@vger.kernel.org Mon Apr 13 00:00:13 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Apr 2026 18:00:05 -0400
+Subject: seg6: separate dst_cache for input and output paths in seg6 lwtunnel
+To: stable@vger.kernel.org
+Cc: Andrea Mayer <andrea.mayer@uniroma2.it>, Nicolas Dichtel <nicolas.dichtel@6wind.com>, Justin Iurman <justin.iurman@gmail.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260412220005.2440027-1-sashal@kernel.org>
+
+From: Andrea Mayer <andrea.mayer@uniroma2.it>
+
+[ Upstream commit c3812651b522fe8437ebb7063b75ddb95b571643 ]
+
+The seg6 lwtunnel uses a single dst_cache per encap route, shared
+between seg6_input_core() and seg6_output_core(). These two paths
+can perform the post-encap SID lookup in different routing contexts
+(e.g., ip rules matching on the ingress interface, or VRF table
+separation). Whichever path runs first populates the cache, and the
+other reuses it blindly, bypassing its own lookup.
+
+Fix this by splitting the cache into cache_input and cache_output,
+so each path maintains its own cached dst independently.
+
+Fixes: 6c8702c60b88 ("ipv6: sr: add support for SRH encapsulation and injection with lwtunnels")
+Cc: stable@vger.kernel.org
+Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Reviewed-by: Justin Iurman <justin.iurman@gmail.com>
+Link: https://patch.msgid.link/20260404004405.4057-2-andrea.mayer@uniroma2.it
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ added missing dst reference loop guard in seg6_output_core() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/seg6_iptunnel.c |   41 ++++++++++++++++++++++++++++-------------
+ 1 file changed, 28 insertions(+), 13 deletions(-)
+
+--- a/net/ipv6/seg6_iptunnel.c
++++ b/net/ipv6/seg6_iptunnel.c
+@@ -48,7 +48,8 @@ static size_t seg6_lwt_headroom(struct s
+ }
+ struct seg6_lwt {
+-      struct dst_cache cache;
++      struct dst_cache cache_input;
++      struct dst_cache cache_output;
+       struct seg6_iptunnel_encap tuninfo[];
+ };
+@@ -486,7 +487,7 @@ static int seg6_input_core(struct net *n
+       slwt = seg6_lwt_lwtunnel(lwtst);
+       local_bh_disable();
+-      dst = dst_cache_get(&slwt->cache);
++      dst = dst_cache_get(&slwt->cache_input);
+       local_bh_enable();
+       err = seg6_do_srh(skb, dst);
+@@ -504,7 +505,7 @@ static int seg6_input_core(struct net *n
+               /* cache only if we don't create a dst reference loop */
+               if (!dst->error && lwtst != dst->lwtstate) {
+                       local_bh_disable();
+-                      dst_cache_set_ip6(&slwt->cache, dst,
++                      dst_cache_set_ip6(&slwt->cache_input, dst,
+                                         &ipv6_hdr(skb)->saddr);
+                       local_bh_enable();
+               }
+@@ -563,7 +564,7 @@ static int seg6_output_core(struct net *
+       slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);
+       local_bh_disable();
+-      dst = dst_cache_get(&slwt->cache);
++      dst = dst_cache_get(&slwt->cache_output);
+       local_bh_enable();
+       err = seg6_do_srh(skb, dst);
+@@ -587,9 +588,12 @@ static int seg6_output_core(struct net *
+                       goto drop;
+               }
+-              local_bh_disable();
+-              dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr);
+-              local_bh_enable();
++              /* cache only if we don't create a dst reference loop */
++              if (orig_dst->lwtstate != dst->lwtstate) {
++                      local_bh_disable();
++                      dst_cache_set_ip6(&slwt->cache_output, dst, &fl6.saddr);
++                      local_bh_enable();
++              }
+               err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev));
+               if (unlikely(err))
+@@ -697,11 +701,13 @@ static int seg6_build_state(struct net *
+       slwt = seg6_lwt_lwtunnel(newts);
+-      err = dst_cache_init(&slwt->cache, GFP_ATOMIC);
+-      if (err) {
+-              kfree(newts);
+-              return err;
+-      }
++      err = dst_cache_init(&slwt->cache_input, GFP_ATOMIC);
++      if (err)
++              goto err_free_newts;
++
++      err = dst_cache_init(&slwt->cache_output, GFP_ATOMIC);
++      if (err)
++              goto err_destroy_input;
+       memcpy(&slwt->tuninfo, tuninfo, tuninfo_len);
+@@ -716,11 +722,20 @@ static int seg6_build_state(struct net *
+       *ts = newts;
+       return 0;
++
++err_destroy_input:
++      dst_cache_destroy(&slwt->cache_input);
++err_free_newts:
++      kfree(newts);
++      return err;
+ }
+ static void seg6_destroy_state(struct lwtunnel_state *lwt)
+ {
+-      dst_cache_destroy(&seg6_lwt_lwtunnel(lwt)->cache);
++      struct seg6_lwt *slwt = seg6_lwt_lwtunnel(lwt);
++
++      dst_cache_destroy(&slwt->cache_input);
++      dst_cache_destroy(&slwt->cache_output);
+ }
+ static int seg6_fill_encap_info(struct sk_buff *skb,
index 690e8ed5c528a8e8c7626d7f919e8b69e0aa4a27..0ad8b8a578ad0cbb43496524a54e892ac954532b 100644 (file)
@@ -540,3 +540,29 @@ rxrpc-fix-reference-count-leak-in-rxrpc_server_keyring.patch
 rxrpc-fix-key-keyring-checks-in-setsockopt-rxrpc_security_key-keyring.patch
 netlink-add-nla-be16-32-types-to-minlen-array.patch
 xen-privcmd-unregister-xenstore-notifier-on-module-exit.patch
+revert-mptcp-add-needs_id-for-netlink-appending-addr.patch
+seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch
+net-rfkill-prevent-unlimited-numbers-of-rfkill-events-from-being-created.patch
+usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch
+usb-gadget-u_ether-fix-race-between-gether_disconnect-and-eth_stop.patch
+usb-gadget-uvc-fix-null-pointer-dereference-during-unbind-race.patch
+ext4-publish-jinode-after-initialization.patch
+ext4-fix-the-might_sleep-warnings-in-kvfree.patch
+ext4-fix-use-after-free-in-update_super_work-when-racing-with-umount.patch
+xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch
+dmaengine-sh-rz-dmac-move-chctrl-updates-under-spinlock.patch
+dmaengine-sh-rz-dmac-protect-the-driver-specific-lists.patch
+kvm-x86-mmu-drop-zap-existing-present-spte-even-when-creating-an-mmio-spte.patch
+net-macb-move-devm_-free-request-_irq-out-of-spin-lock-area.patch
+scsi-target-tcm_loop-drain-commands-in-target_reset-handler.patch
+mm-huge_memory-fix-folio-isn-t-locked-in-softleaf_to_folio.patch
+x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch
+tracing-fix-potential-deadlock-in-cpu-hotplug-with-osnoise.patch
+ksmbd-fix-potencial-oob-in-get_file_all_info-for-compound-requests.patch
+ksmbd-replace-hardcoded-hdr2_len-with-offsetof-in-smb2_calc_max_out_buf_len.patch
+i2c-cp2615-replace-deprecated-strncpy-with-strscpy.patch
+i2c-cp2615-fix-serial-string-null-deref-at-probe.patch
+bluetooth-l2cap-fix-accepting-multiple-l2cap_ecred_conn_req.patch
+drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch
+ksmbd-fix-refcount-leak-when-invalid-session-is-found-on-session-lookup.patch
+ksmbd-fix-dangling-pointer-in-krb_authenticate.patch
diff --git a/queue-5.15/tracing-fix-potential-deadlock-in-cpu-hotplug-with-osnoise.patch b/queue-5.15/tracing-fix-potential-deadlock-in-cpu-hotplug-with-osnoise.patch
new file mode 100644 (file)
index 0000000..7d0aa28
--- /dev/null
@@ -0,0 +1,93 @@
+From stable+bounces-231276-greg=kroah.com@vger.kernel.org Mon Mar 30 23:07:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Mar 2026 17:07:37 -0400
+Subject: tracing: Fix potential deadlock in cpu hotplug with osnoise
+To: stable@vger.kernel.org
+Cc: Luo Haiyang <luo.haiyang@zte.com.cn>, mathieu.desnoyers@efficios.com, zhang.run@zte.com.cn, yang.tao172@zte.com.cn, ran.xiaokai@zte.com.cn, "Masami Hiramatsu (Google)" <mhiramat@kernel.org>, "Steven Rostedt (Google)" <rostedt@goodmis.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260330210737.1213194-1-sashal@kernel.org>
+
+From: Luo Haiyang <luo.haiyang@zte.com.cn>
+
+[ Upstream commit 1f9885732248d22f788e4992c739a98c88ab8a55 ]
+
+The following sequence may leads deadlock in cpu hotplug:
+
+    task1        task2        task3
+    -----        -----        -----
+
+ mutex_lock(&interface_lock)
+
+            [CPU GOING OFFLINE]
+
+            cpus_write_lock();
+            osnoise_cpu_die();
+              kthread_stop(task3);
+                wait_for_completion();
+
+                      osnoise_sleep();
+                        mutex_lock(&interface_lock);
+
+ cpus_read_lock();
+
+ [DEAD LOCK]
+
+Fix by swap the order of cpus_read_lock() and mutex_lock(&interface_lock).
+
+Cc: stable@vger.kernel.org
+Cc: <mathieu.desnoyers@efficios.com>
+Cc: <zhang.run@zte.com.cn>
+Cc: <yang.tao172@zte.com.cn>
+Cc: <ran.xiaokai@zte.com.cn>
+Fixes: bce29ac9ce0bb ("trace: Add osnoise tracer")
+Link: https://patch.msgid.link/20260326141953414bVSj33dAYktqp9Oiyizq8@zte.com.cn
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Luo Haiyang <luo.haiyang@zte.com.cn>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+[ adapted guard() macros to lock/unlock calls ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_osnoise.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/kernel/trace/trace_osnoise.c
++++ b/kernel/trace/trace_osnoise.c
+@@ -1620,8 +1620,8 @@ static void osnoise_hotplug_workfn(struc
+       if (!osnoise_busy)
+               goto out_unlock_trace;
+-      mutex_lock(&interface_lock);
+       cpus_read_lock();
++      mutex_lock(&interface_lock);
+       if (!cpu_online(cpu))
+               goto out_unlock;
+@@ -1634,8 +1634,8 @@ static void osnoise_hotplug_workfn(struc
+       start_kthread(cpu);
+ out_unlock:
+-      cpus_read_unlock();
+       mutex_unlock(&interface_lock);
++      cpus_read_unlock();
+ out_unlock_trace:
+       mutex_unlock(&trace_types_lock);
+ }
+@@ -1772,16 +1772,16 @@ osnoise_cpus_write(struct file *filp, co
+       if (running)
+               osnoise_tracer_stop(tr);
+-      mutex_lock(&interface_lock);
+       /*
+        * osnoise_cpumask is read by CPU hotplug operations.
+        */
+       cpus_read_lock();
++      mutex_lock(&interface_lock);
+       cpumask_copy(&osnoise_cpumask, osnoise_cpumask_new);
+-      cpus_read_unlock();
+       mutex_unlock(&interface_lock);
++      cpus_read_unlock();
+       if (running)
+               osnoise_tracer_start(tr);
diff --git a/queue-5.15/usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch b/queue-5.15/usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch
new file mode 100644 (file)
index 0000000..d7fa22c
--- /dev/null
@@ -0,0 +1,72 @@
+From stable+bounces-235808-greg=kroah.com@vger.kernel.org Sun Apr 12 14:00:10 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Apr 2026 08:00:00 -0400
+Subject: usb: gadget: f_hid: move list and spinlock inits from bind to alloc
+To: stable@vger.kernel.org
+Cc: Michael Zimmermann <sigmaepsilon92@gmail.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260412120000.2096246-1-sashal@kernel.org>
+
+From: Michael Zimmermann <sigmaepsilon92@gmail.com>
+
+[ Upstream commit 4e0a88254ad59f6c53a34bf5fa241884ec09e8b2 ]
+
+There was an issue when you did the following:
+- setup and bind an hid gadget
+- open /dev/hidg0
+- use the resulting fd in EPOLL_CTL_ADD
+- unbind the UDC
+- bind the UDC
+- use the fd in EPOLL_CTL_DEL
+
+When CONFIG_DEBUG_LIST was enabled, a list_del corruption was reported
+within remove_wait_queue (via ep_remove_wait_queue). After some
+debugging I found out that the queues, which f_hid registers via
+poll_wait were the problem. These were initialized using
+init_waitqueue_head inside hidg_bind. So effectively, the bind function
+re-initialized the queues while there were still items in them.
+
+The solution is to move the initialization from hidg_bind to hidg_alloc
+to extend their lifetimes to the lifetime of the function instance.
+
+Additionally, I found many other possibly problematic init calls in the
+bind function, which I moved as well.
+
+Signed-off-by: Michael Zimmermann <sigmaepsilon92@gmail.com>
+Cc: stable <stable@kernel.org>
+Link: https://patch.msgid.link/20260331184844.2388761-1-sigmaepsilon92@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_hid.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -996,13 +996,8 @@ static int hidg_bind(struct usb_configur
+       if (status)
+               goto fail;
+-      spin_lock_init(&hidg->write_spinlock);
+       hidg->write_pending = 1;
+       hidg->req = NULL;
+-      spin_lock_init(&hidg->read_spinlock);
+-      init_waitqueue_head(&hidg->write_queue);
+-      init_waitqueue_head(&hidg->read_queue);
+-      INIT_LIST_HEAD(&hidg->completed_out_req);
+       /* create char device */
+       cdev_init(&hidg->cdev, &f_hidg_fops);
+@@ -1272,6 +1267,12 @@ static struct usb_function *hidg_alloc(s
+       mutex_lock(&opts->lock);
+       ++opts->refcnt;
++      spin_lock_init(&hidg->write_spinlock);
++      spin_lock_init(&hidg->read_spinlock);
++      init_waitqueue_head(&hidg->write_queue);
++      init_waitqueue_head(&hidg->read_queue);
++      INIT_LIST_HEAD(&hidg->completed_out_req);
++
+       device_initialize(&hidg->dev);
+       hidg->dev.release = hidg_release;
+       hidg->dev.class = hidg_class;
diff --git a/queue-5.15/usb-gadget-u_ether-fix-race-between-gether_disconnect-and-eth_stop.patch b/queue-5.15/usb-gadget-u_ether-fix-race-between-gether_disconnect-and-eth_stop.patch
new file mode 100644 (file)
index 0000000..367cf71
--- /dev/null
@@ -0,0 +1,80 @@
+From sashal@kernel.org Sat Apr 11 18:31:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Apr 2026 12:31:06 -0400
+Subject: usb: gadget: u_ether: Fix race between gether_disconnect and eth_stop
+To: stable@vger.kernel.org
+Cc: Kuen-Han Tsai <khtsai@google.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260411163106.807249-1-sashal@kernel.org>
+
+From: Kuen-Han Tsai <khtsai@google.com>
+
+[ Upstream commit e1eabb072c75681f78312c484ccfffb7430f206e ]
+
+A race condition between gether_disconnect() and eth_stop() leads to a
+NULL pointer dereference. Specifically, if eth_stop() is triggered
+concurrently while gether_disconnect() is tearing down the endpoints,
+eth_stop() attempts to access the cleared endpoint descriptor, causing
+the following NPE:
+
+  Unable to handle kernel NULL pointer dereference
+  Call trace:
+   __dwc3_gadget_ep_enable+0x60/0x788
+   dwc3_gadget_ep_enable+0x70/0xe4
+   usb_ep_enable+0x60/0x15c
+   eth_stop+0xb8/0x108
+
+Because eth_stop() crashes while holding the dev->lock, the thread
+running gether_disconnect() fails to acquire the same lock and spins
+forever, resulting in a hardlockup:
+
+  Core - Debugging Information for Hardlockup core(7)
+  Call trace:
+   queued_spin_lock_slowpath+0x94/0x488
+   _raw_spin_lock+0x64/0x6c
+   gether_disconnect+0x19c/0x1e8
+   ncm_set_alt+0x68/0x1a0
+   composite_setup+0x6a0/0xc50
+
+The root cause is that the clearing of dev->port_usb in
+gether_disconnect() is delayed until the end of the function.
+
+Move the clearing of dev->port_usb to the very beginning of
+gether_disconnect() while holding dev->lock. This cuts off the link
+immediately, ensuring eth_stop() will see dev->port_usb as NULL and
+safely bail out.
+
+Fixes: 2b3d942c4878 ("usb ethernet gadget: split out network core")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
+Link: https://patch.msgid.link/20260311-gether-disconnect-npe-v1-1-454966adf7c7@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/u_ether.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/gadget/function/u_ether.c
++++ b/drivers/usb/gadget/function/u_ether.c
+@@ -1173,6 +1173,10 @@ void gether_disconnect(struct gether *li
+       DBG(dev, "%s\n", __func__);
++      spin_lock(&dev->lock);
++      dev->port_usb = NULL;
++      spin_unlock(&dev->lock);
++
+       netif_stop_queue(dev->net);
+       netif_carrier_off(dev->net);
+@@ -1210,10 +1214,6 @@ void gether_disconnect(struct gether *li
+       dev->header_len = 0;
+       dev->unwrap = NULL;
+       dev->wrap = NULL;
+-
+-      spin_lock(&dev->lock);
+-      dev->port_usb = NULL;
+-      spin_unlock(&dev->lock);
+ }
+ EXPORT_SYMBOL_GPL(gether_disconnect);
diff --git a/queue-5.15/usb-gadget-uvc-fix-null-pointer-dereference-during-unbind-race.patch b/queue-5.15/usb-gadget-uvc-fix-null-pointer-dereference-during-unbind-race.patch
new file mode 100644 (file)
index 0000000..add0e2a
--- /dev/null
@@ -0,0 +1,244 @@
+From sashal@kernel.org Sat Apr 11 16:09:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Apr 2026 10:09:48 -0400
+Subject: usb: gadget: uvc: fix NULL pointer dereference during unbind race
+To: stable@vger.kernel.org
+Cc: Jimmy Hu <hhhuuu@google.com>, stable <stable@kernel.org>, Alan Stern <stern@rowland.harvard.edu>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260411140948.765851-1-sashal@kernel.org>
+
+From: Jimmy Hu <hhhuuu@google.com>
+
+[ Upstream commit eba2936bbe6b752a31725a9eb5c674ecbf21ee7d ]
+
+Commit b81ac4395bbe ("usb: gadget: uvc: allow for application to cleanly
+shutdown") introduced two stages of synchronization waits totaling 1500ms
+in uvc_function_unbind() to prevent several types of kernel panics.
+However, this timing-based approach is insufficient during power
+management (PM) transitions.
+
+When the PM subsystem starts freezing user space processes, the
+wait_event_interruptible_timeout() is aborted early, which allows the
+unbind thread to proceed and nullify the gadget pointer
+(cdev->gadget = NULL):
+
+[  814.123447][  T947] configfs-gadget.g1 gadget.0: uvc: uvc_function_unbind()
+[  814.178583][ T3173] PM: suspend entry (deep)
+[  814.192487][ T3173] Freezing user space processes
+[  814.197668][  T947] configfs-gadget.g1 gadget.0: uvc: uvc_function_unbind no clean disconnect, wait for release
+
+When the PM subsystem resumes or aborts the suspend and tasks are
+restarted, the V4L2 release path is executed and attempts to access the
+already nullified gadget pointer, triggering a kernel panic:
+
+[  814.292597][    C0] PM: pm_system_irq_wakeup: 479 triggered dhdpcie_host_wake
+[  814.386727][ T3173] Restarting tasks ...
+[  814.403522][ T4558] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000030
+[  814.404021][ T4558] pc : usb_gadget_deactivate+0x14/0xf4
+[  814.404031][ T4558] lr : usb_function_deactivate+0x54/0x94
+[  814.404078][ T4558] Call trace:
+[  814.404080][ T4558]  usb_gadget_deactivate+0x14/0xf4
+[  814.404083][ T4558]  usb_function_deactivate+0x54/0x94
+[  814.404087][ T4558]  uvc_function_disconnect+0x1c/0x5c
+[  814.404092][ T4558]  uvc_v4l2_release+0x44/0xac
+[  814.404095][ T4558]  v4l2_release+0xcc/0x130
+
+Address the race condition and NULL pointer dereference by:
+
+1. State Synchronization (flag + mutex)
+Introduce a 'func_unbound' flag in struct uvc_device. This allows
+uvc_function_disconnect() to safely skip accessing the nullified
+cdev->gadget pointer. As suggested by Alan Stern, this flag is protected
+by a new mutex (uvc->lock) to ensure proper memory ordering and prevent
+instruction reordering or speculative loads. This mutex is also used to
+protect 'func_connected' for consistent state management.
+
+2. Explicit Synchronization (completion)
+Use a completion to synchronize uvc_function_unbind() with the
+uvc_vdev_release() callback. This prevents Use-After-Free (UAF) by
+ensuring struct uvc_device is freed after all video device resources
+are released.
+
+Fixes: b81ac4395bbe ("usb: gadget: uvc: allow for application to cleanly shutdown")
+Cc: stable <stable@kernel.org>
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jimmy Hu <hhhuuu@google.com>
+Link: https://patch.msgid.link/20260320065427.1374555-1-hhhuuu@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ replaced guard()/scoped_guard() macros ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_uvc.c    |   46 ++++++++++++++++++++++++++++++---
+ drivers/usb/gadget/function/uvc.h      |    3 ++
+ drivers/usb/gadget/function/uvc_v4l2.c |   13 +++++++--
+ 3 files changed, 56 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_uvc.c
++++ b/drivers/usb/gadget/function/f_uvc.c
+@@ -393,6 +393,14 @@ uvc_function_disconnect(struct uvc_devic
+ {
+       int ret;
++      mutex_lock(&uvc->lock);
++      if (uvc->func_unbound) {
++              dev_dbg(&uvc->vdev.dev, "skipping function deactivate (unbound)\n");
++              mutex_unlock(&uvc->lock);
++              return;
++      }
++      mutex_unlock(&uvc->lock);
++
+       if ((ret = usb_function_deactivate(&uvc->func)) < 0)
+               uvcg_info(&uvc->func, "UVC disconnect failed with %d\n", ret);
+ }
+@@ -411,6 +419,15 @@ static ssize_t function_name_show(struct
+ static DEVICE_ATTR_RO(function_name);
++static void uvc_vdev_release(struct video_device *vdev)
++{
++      struct uvc_device *uvc = video_get_drvdata(vdev);
++
++      /* Signal uvc_function_unbind() that the video device has been released */
++      if (uvc->vdev_release_done)
++              complete(uvc->vdev_release_done);
++}
++
+ static int
+ uvc_register_video(struct uvc_device *uvc)
+ {
+@@ -422,7 +439,7 @@ uvc_register_video(struct uvc_device *uv
+       uvc->vdev.v4l2_dev->dev = &cdev->gadget->dev;
+       uvc->vdev.fops = &uvc_v4l2_fops;
+       uvc->vdev.ioctl_ops = &uvc_v4l2_ioctl_ops;
+-      uvc->vdev.release = video_device_release_empty;
++      uvc->vdev.release = uvc_vdev_release;
+       uvc->vdev.vfl_dir = VFL_DIR_TX;
+       uvc->vdev.lock = &uvc->video.mutex;
+       uvc->vdev.device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+@@ -596,6 +613,9 @@ uvc_function_bind(struct usb_configurati
+       int ret = -EINVAL;
+       uvcg_info(f, "%s()\n", __func__);
++      mutex_lock(&uvc->lock);
++      uvc->func_unbound = false;
++      mutex_unlock(&uvc->lock);
+       opts = fi_to_f_uvc_opts(f->fi);
+       /* Sanity check the streaming endpoint module parameters.
+@@ -888,18 +908,25 @@ static void uvc_free(struct usb_function
+ static void uvc_function_unbind(struct usb_configuration *c,
+                               struct usb_function *f)
+ {
++      DECLARE_COMPLETION_ONSTACK(vdev_release_done);
+       struct usb_composite_dev *cdev = c->cdev;
+       struct uvc_device *uvc = to_uvc(f);
+       long wait_ret = 1;
++      bool connected;
+       uvcg_info(f, "%s()\n", __func__);
++      mutex_lock(&uvc->lock);
++      uvc->func_unbound = true;
++      uvc->vdev_release_done = &vdev_release_done;
++      connected = uvc->func_connected;
++      mutex_unlock(&uvc->lock);
+       /* If we know we're connected via v4l2, then there should be a cleanup
+        * of the device from userspace either via UVC_EVENT_DISCONNECT or
+        * though the video device removal uevent. Allow some time for the
+        * application to close out before things get deleted.
+        */
+-      if (uvc->func_connected) {
++      if (connected) {
+               uvcg_dbg(f, "waiting for clean disconnect\n");
+               wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue,
+                               uvc->func_connected == false, msecs_to_jiffies(500));
+@@ -910,8 +937,13 @@ static void uvc_function_unbind(struct u
+       video_unregister_device(&uvc->vdev);
+       v4l2_device_unregister(&uvc->v4l2_dev);
+-      if (uvc->func_connected) {
+-              /* Wait for the release to occur to ensure there are no longer any
++      mutex_lock(&uvc->lock);
++      connected = uvc->func_connected;
++      mutex_unlock(&uvc->lock);
++
++      if (connected) {
++              /*
++               * Wait for the release to occur to ensure there are no longer any
+                * pending operations that may cause panics when resources are cleaned
+                * up.
+                */
+@@ -921,6 +953,10 @@ static void uvc_function_unbind(struct u
+               uvcg_dbg(f, "done waiting for release with ret: %ld\n", wait_ret);
+       }
++      /* Wait for the video device to be released */
++      wait_for_completion(&vdev_release_done);
++      uvc->vdev_release_done = NULL;
++
+       usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
+       kfree(uvc->control_buf);
+@@ -938,6 +974,8 @@ static struct usb_function *uvc_alloc(st
+               return ERR_PTR(-ENOMEM);
+       mutex_init(&uvc->video.mutex);
++      mutex_init(&uvc->lock);
++      uvc->func_unbound = true;
+       uvc->state = UVC_STATE_DISCONNECTED;
+       init_waitqueue_head(&uvc->func_connected_queue);
+       opts = fi_to_f_uvc_opts(fi);
+--- a/drivers/usb/gadget/function/uvc.h
++++ b/drivers/usb/gadget/function/uvc.h
+@@ -130,6 +130,9 @@ struct uvc_device {
+       enum uvc_state state;
+       struct usb_function func;
+       struct uvc_video video;
++      struct completion *vdev_release_done;
++      struct mutex lock;      /* protects func_unbound and func_connected */
++      bool func_unbound;
+       bool func_connected;
+       wait_queue_head_t func_connected_queue;
+--- a/drivers/usb/gadget/function/uvc_v4l2.c
++++ b/drivers/usb/gadget/function/uvc_v4l2.c
+@@ -234,12 +234,18 @@ uvc_v4l2_subscribe_event(struct v4l2_fh
+       if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST)
+               return -EINVAL;
+-      if (sub->type == UVC_EVENT_SETUP && uvc->func_connected)
++      mutex_lock(&uvc->lock);
++
++      if (sub->type == UVC_EVENT_SETUP && uvc->func_connected) {
++              mutex_unlock(&uvc->lock);
+               return -EBUSY;
++      }
+       ret = v4l2_event_subscribe(fh, sub, 2, NULL);
+-      if (ret < 0)
++      if (ret < 0) {
++              mutex_unlock(&uvc->lock);
+               return ret;
++      }
+       if (sub->type == UVC_EVENT_SETUP) {
+               uvc->func_connected = true;
+@@ -247,6 +253,7 @@ uvc_v4l2_subscribe_event(struct v4l2_fh
+               uvc_function_connect(uvc);
+       }
++      mutex_unlock(&uvc->lock);
+       return 0;
+ }
+@@ -255,7 +262,9 @@ static void uvc_v4l2_disable(struct uvc_
+       uvc_function_disconnect(uvc);
+       uvcg_video_enable(&uvc->video, 0);
+       uvcg_free_buffers(&uvc->video.queue);
++      mutex_lock(&uvc->lock);
+       uvc->func_connected = false;
++      mutex_unlock(&uvc->lock);
+       wake_up_interruptible(&uvc->func_connected_queue);
+ }
diff --git a/queue-5.15/x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch b/queue-5.15/x86-cpu-enable-fsgsbase-early-in-cpu_init_exception_handling.patch
new file mode 100644 (file)
index 0000000..cf92145
--- /dev/null
@@ -0,0 +1,142 @@
+From stable+bounces-231413-greg=kroah.com@vger.kernel.org Tue Mar 31 14:21:10 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 31 Mar 2026 08:16:42 -0400
+Subject: x86/cpu: Enable FSGSBASE early in cpu_init_exception_handling()
+To: stable@vger.kernel.org
+Cc: Nikunj A Dadhania <nikunj@amd.com>, Borislav Petkov <bp@alien8.de>, Sohil Mehta <sohil.mehta@intel.com>, stable@kernel.org, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260331121642.2195682-1-sashal@kernel.org>
+
+From: Nikunj A Dadhania <nikunj@amd.com>
+
+[ Upstream commit 05243d490bb7852a8acca7b5b5658019c7797a52 ]
+
+Move FSGSBASE enablement from identify_cpu() to cpu_init_exception_handling()
+to ensure it is enabled before any exceptions can occur on both boot and
+secondary CPUs.
+
+== Background ==
+
+Exception entry code (paranoid_entry()) uses ALTERNATIVE patching based on
+X86_FEATURE_FSGSBASE to decide whether to use RDGSBASE/WRGSBASE instructions
+or the slower RDMSR/SWAPGS sequence for saving/restoring GSBASE.
+
+On boot CPU, ALTERNATIVE patching happens after enabling FSGSBASE in CR4.
+When the feature is available, the code is permanently patched to use
+RDGSBASE/WRGSBASE, which require CR4.FSGSBASE=1 to execute without triggering
+
+== Boot Sequence ==
+
+Boot CPU (with CR pinning enabled):
+  trap_init()
+    cpu_init()                   <- Uses unpatched code (RDMSR/SWAPGS)
+      x2apic_setup()
+  ...
+  arch_cpu_finalize_init()
+    identify_boot_cpu()
+      identify_cpu()
+        cr4_set_bits(X86_CR4_FSGSBASE)  # Enables the feature
+       # This becomes part of cr4_pinned_bits
+    ...
+    alternative_instructions()   <- Patches code to use RDGSBASE/WRGSBASE
+
+Secondary CPUs (with CR pinning enabled):
+  start_secondary()
+    cr4_init()                   <- Code already patched, CR4.FSGSBASE=1
+                                    set implicitly via cr4_pinned_bits
+
+    cpu_init()                   <- exceptions work because FSGSBASE is
+                                    already enabled
+
+Secondary CPU (with CR pinning disabled):
+  start_secondary()
+    cr4_init()                   <- Code already patched, CR4.FSGSBASE=0
+    cpu_init()
+      x2apic_setup()
+        rdmsrq(MSR_IA32_APICBASE)  <- Triggers #VC in SNP guests
+          exc_vmm_communication()
+            paranoid_entry()       <- Uses RDGSBASE with CR4.FSGSBASE=0
+                                      (patched code)
+    ...
+    ap_starting()
+      identify_secondary_cpu()
+        identify_cpu()
+         cr4_set_bits(X86_CR4_FSGSBASE)  <- Enables the feature, which is
+                                             too late
+
+== CR Pinning ==
+
+Currently, for secondary CPUs, CR4.FSGSBASE is set implicitly through
+CR-pinning: the boot CPU sets it during identify_cpu(), it becomes part of
+cr4_pinned_bits, and cr4_init() applies those pinned bits to secondary CPUs.
+This works but creates an undocumented dependency between cr4_init() and the
+pinning mechanism.
+
+== Problem ==
+
+Secondary CPUs boot after alternatives have been applied globally. They
+execute already-patched paranoid_entry() code that uses RDGSBASE/WRGSBASE
+instructions, which require CR4.FSGSBASE=1. Upcoming changes to CR pinning
+behavior will break the implicit dependency, causing secondary CPUs to
+generate #UD.
+
+This issue manifests itself on AMD SEV-SNP guests, where the rdmsrq() in
+x2apic_setup() triggers a #VC exception early during cpu_init(). The #VC
+handler (exc_vmm_communication()) executes the patched paranoid_entry() path.
+Without CR4.FSGSBASE enabled, RDGSBASE instructions trigger #UD.
+
+== Fix ==
+
+Enable FSGSBASE explicitly in cpu_init_exception_handling() before loading
+exception handlers. This makes the dependency explicit and ensures both
+boot and secondary CPUs have FSGSBASE enabled before paranoid_entry()
+executes.
+
+Fixes: c82965f9e530 ("x86/entry/64: Handle FSGSBASE enabled paranoid entry/exit")
+Reported-by: Borislav Petkov <bp@alien8.de>
+Suggested-by: Sohil Mehta <sohil.mehta@intel.com>
+Signed-off-by: Nikunj A Dadhania <nikunj@amd.com>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Reviewed-by: Sohil Mehta <sohil.mehta@intel.com>
+Cc: <stable@kernel.org>
+Link: https://patch.msgid.link/20260318075654.1792916-2-nikunj@amd.com
+[ placed FSGSBASE enablement before load_current_idt() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/cpu/common.c |   18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -1839,12 +1839,6 @@ static void identify_cpu(struct cpuinfo_
+       setup_smap(c);
+       setup_umip(c);
+-      /* Enable FSGSBASE instructions if available. */
+-      if (cpu_has(c, X86_FEATURE_FSGSBASE)) {
+-              cr4_set_bits(X86_CR4_FSGSBASE);
+-              elf_hwcap2 |= HWCAP2_FSGSBASE;
+-      }
+-
+       /*
+        * The vendor-specific functions might have changed features.
+        * Now we do "generic changes."
+@@ -2220,6 +2214,18 @@ void cpu_init_exception_handling(void)
+       load_TR_desc();
++      /*
++       * On CPUs with FSGSBASE support, paranoid_entry() uses
++       * ALTERNATIVE-patched RDGSBASE/WRGSBASE instructions. Secondary CPUs
++       * boot after alternatives are patched globally, so early exceptions
++       * execute patched code that depends on FSGSBASE. Enable the feature
++       * before any exceptions occur.
++       */
++      if (cpu_feature_enabled(X86_FEATURE_FSGSBASE)) {
++              cr4_set_bits(X86_CR4_FSGSBASE);
++              elf_hwcap2 |= HWCAP2_FSGSBASE;
++      }
++
+       /* Finally load the IDT */
+       load_current_idt();
+ }
diff --git a/queue-5.15/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch b/queue-5.15/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch
new file mode 100644 (file)
index 0000000..547ed68
--- /dev/null
@@ -0,0 +1,100 @@
+From stable+bounces-232950-greg=kroah.com@vger.kernel.org Thu Apr  2 11:26:28 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  2 Apr 2026 05:12:46 -0400
+Subject: xfs: save ailp before dropping the AIL lock in push callbacks
+To: stable@vger.kernel.org
+Cc: Yuto Ohnuki <ytohnuki@amazon.com>, syzbot+652af2b3c5569c4ab63c@syzkaller.appspotmail.com, "Darrick J. Wong" <djwong@kernel.org>, Dave Chinner <dchinner@redhat.com>, Carlos Maiolino <cem@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260402091246.482124-1-sashal@kernel.org>
+
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+
+[ Upstream commit 394d70b86fae9fe865e7e6d9540b7696f73aa9b6 ]
+
+In xfs_inode_item_push() and xfs_qm_dquot_logitem_push(), the AIL lock
+is dropped to perform buffer IO. Once the cluster buffer no longer
+protects the log item from reclaim, the log item may be freed by
+background reclaim or the dquot shrinker. The subsequent spin_lock()
+call dereferences lip->li_ailp, which is a use-after-free.
+
+Fix this by saving the ailp pointer in a local variable while the AIL
+lock is held and the log item is guaranteed to be valid.
+
+Reported-by: syzbot+652af2b3c5569c4ab63c@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=652af2b3c5569c4ab63c
+Fixes: 90c60e164012 ("xfs: xfs_iflush() is no longer necessary")
+Cc: stable@vger.kernel.org # v5.9
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Yuto Ohnuki <ytohnuki@amazon.com>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_dquot_item.c |    9 +++++++--
+ fs/xfs/xfs_inode_item.c |    9 +++++++--
+ 2 files changed, 14 insertions(+), 4 deletions(-)
+
+--- a/fs/xfs/xfs_dquot_item.c
++++ b/fs/xfs/xfs_dquot_item.c
+@@ -124,6 +124,7 @@ xfs_qm_dquot_logitem_push(
+ {
+       struct xfs_dquot        *dqp = DQUOT_ITEM(lip)->qli_dquot;
+       struct xfs_buf          *bp = lip->li_buf;
++      struct xfs_ail          *ailp = lip->li_ailp;
+       uint                    rval = XFS_ITEM_SUCCESS;
+       int                     error;
+@@ -152,7 +153,7 @@ xfs_qm_dquot_logitem_push(
+               goto out_unlock;
+       }
+-      spin_unlock(&lip->li_ailp->ail_lock);
++      spin_unlock(&ailp->ail_lock);
+       error = xfs_qm_dqflush(dqp, &bp);
+       if (!error) {
+@@ -162,7 +163,11 @@ xfs_qm_dquot_logitem_push(
+       } else if (error == -EAGAIN)
+               rval = XFS_ITEM_LOCKED;
+-      spin_lock(&lip->li_ailp->ail_lock);
++      /*
++       * The buffer no longer protects the log item from reclaim, so
++       * do not reference lip after this point.
++       */
++      spin_lock(&ailp->ail_lock);
+ out_unlock:
+       xfs_dqunlock(dqp);
+       return rval;
+--- a/fs/xfs/xfs_inode_item.c
++++ b/fs/xfs/xfs_inode_item.c
+@@ -540,6 +540,7 @@ xfs_inode_item_push(
+       struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+       struct xfs_inode        *ip = iip->ili_inode;
+       struct xfs_buf          *bp = lip->li_buf;
++      struct xfs_ail          *ailp = lip->li_ailp;
+       uint                    rval = XFS_ITEM_SUCCESS;
+       int                     error;
+@@ -555,7 +556,7 @@ xfs_inode_item_push(
+       if (!xfs_buf_trylock(bp))
+               return XFS_ITEM_LOCKED;
+-      spin_unlock(&lip->li_ailp->ail_lock);
++      spin_unlock(&ailp->ail_lock);
+       /*
+        * We need to hold a reference for flushing the cluster buffer as it may
+@@ -579,7 +580,11 @@ xfs_inode_item_push(
+               rval = XFS_ITEM_LOCKED;
+       }
+-      spin_lock(&lip->li_ailp->ail_lock);
++      /*
++       * The buffer no longer protects the log item from reclaim, so
++       * do not reference lip after this point.
++       */
++      spin_lock(&ailp->ail_lock);
+       return rval;
+ }