--- /dev/null
+From stable+bounces-219683-greg=kroah.com@vger.kernel.org Wed Feb 25 19:10:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Feb 2026 13:10:32 -0500
+Subject: ata: libata-scsi: drop DPRINTK calls for cdb translation
+To: stable@vger.kernel.org
+Cc: Hannes Reinecke <hare@suse.de>, Damien Le Moal <damien.lemoal@opensource.wdc.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260225181034.910635-2-sashal@kernel.org>
+
+From: Hannes Reinecke <hare@suse.de>
+
+[ Upstream commit 1fe9fb71b2ffcedd794daacf4db2056a6cb5199e ]
+
+Drop DPRINTK calls for cdb translation as they are already covered
+by other traces, and also drop the DPRINTK calls in ata_scsi_hotplug().
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Stable-dep-of: bb3a8154b1a1 ("ata: libata-scsi: refactor ata_scsi_translate()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/libata-scsi.c | 20 +-------------------
+ 1 file changed, 1 insertion(+), 19 deletions(-)
+
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index b57027206ae1e..22c45bc64a95e 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -1472,9 +1472,6 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
+ head = track % dev->heads;
+ sect = (u32)block % dev->sectors + 1;
+
+- DPRINTK("block %u track %u cyl %u head %u sect %u\n",
+- (u32)block, track, cyl, head, sect);
+-
+ /* Check whether the converted CHS can fit.
+ Cylinder: 0-65535
+ Head: 0-15
+@@ -1597,7 +1594,6 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
+ goto invalid_fld;
+ break;
+ default:
+- DPRINTK("no-byte command\n");
+ fp = 0;
+ goto invalid_fld;
+ }
+@@ -1751,7 +1747,6 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
+ early_finish:
+ ata_qc_free(qc);
+ scsi_done(cmd);
+- DPRINTK("EXIT - early finish (good or error)\n");
+ return 0;
+
+ err_did:
+@@ -1759,12 +1754,10 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
+ cmd->result = (DID_ERROR << 16);
+ scsi_done(cmd);
+ err_mem:
+- DPRINTK("EXIT - internal\n");
+ return 0;
+
+ defer:
+ ata_qc_free(qc);
+- DPRINTK("EXIT - defer\n");
+ if (rc == ATA_DEFER_LINK)
+ return SCSI_MLQUEUE_DEVICE_BUSY;
+ else
+@@ -2491,8 +2484,6 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
+ struct ata_port *ap = qc->ap;
+ struct scsi_cmnd *cmd = qc->scsicmd;
+
+- DPRINTK("ATAPI request sense\n");
+-
+ memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+
+ #ifdef CONFIG_ATA_SFF
+@@ -2531,8 +2522,6 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
+ qc->complete_fn = atapi_sense_complete;
+
+ ata_qc_issue(qc);
+-
+- DPRINTK("EXIT\n");
+ }
+
+ /*
+@@ -2642,7 +2631,6 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
+ qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+ if (scmd->sc_data_direction == DMA_TO_DEVICE) {
+ qc->tf.flags |= ATA_TFLAG_WRITE;
+- DPRINTK("direction: write\n");
+ }
+
+ qc->tf.command = ATA_CMD_PACKET;
+@@ -4065,8 +4053,6 @@ int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev)
+ return 0;
+
+ bad_cdb_len:
+- DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n",
+- scmd->cmd_len, scsi_op, dev->cdb_len);
+ scmd->result = DID_ERROR << 16;
+ scsi_done(scmd);
+ return 0;
+@@ -4532,12 +4518,9 @@ void ata_scsi_hotplug(struct work_struct *work)
+ container_of(work, struct ata_port, hotplug_task.work);
+ int i;
+
+- if (ap->pflags & ATA_PFLAG_UNLOADING) {
+- DPRINTK("ENTER/EXIT - unloading\n");
++ if (ap->pflags & ATA_PFLAG_UNLOADING)
+ return;
+- }
+
+- DPRINTK("ENTER\n");
+ mutex_lock(&ap->scsi_scan_mutex);
+
+ /* Unplug detached devices. We cannot use link iterator here
+@@ -4553,7 +4536,6 @@ void ata_scsi_hotplug(struct work_struct *work)
+ ata_scsi_scan_host(ap, 0);
+
+ mutex_unlock(&ap->scsi_scan_mutex);
+- DPRINTK("EXIT\n");
+ }
+
+ /**
+--
+2.51.0
+
--- /dev/null
+From stable+bounces-227506-greg=kroah.com@vger.kernel.org Fri Mar 20 11:18:51 2026
+From: Sven Eckelmann <sven@narfation.org>
+Date: Fri, 20 Mar 2026 11:15:40 +0100
+Subject: batman-adv: avoid OGM aggregation when skb tailroom is insufficient
+To: stable@vger.kernel.org
+Cc: Yang Yang <n05ec@lzu.edu.cn>, Yifan Wu <yifanwucs@gmail.com>, Juefei Pu <tomapufckgml@gmail.com>, Yuan Tan <tanyuan98@outlook.com>, Xin Liu <bird@lzu.edu.cn>, Sven Eckelmann <sven@narfation.org>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20260320101540.1580645-1-sven@narfation.org>
+
+From: Yang Yang <n05ec@lzu.edu.cn>
+
+commit 0d4aef630be9d5f9c1227d07669c26c4383b5ad0 upstream.
+
+When OGM aggregation state is toggled at runtime, an existing forwarded
+packet may have been allocated with only packet_len bytes, while a later
+packet can still be selected for aggregation. Appending in this case can
+hit skb_put overflow conditions.
+
+Reject aggregation when the target skb tailroom cannot accommodate the new
+packet. The caller then falls back to creating a new forward packet
+instead of appending.
+
+Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol")
+Cc: stable@vger.kernel.org
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Signed-off-by: Yuan Tan <tanyuan98@outlook.com>
+Signed-off-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Ao Zhou <n05ec@lzu.edu.cn>
+Signed-off-by: Yang Yang <n05ec@lzu.edu.cn>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+[ Adjust context ]
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/bat_iv_ogm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -465,6 +465,9 @@ batadv_iv_ogm_can_aggregate(const struct
+ !time_after_eq(aggregation_end_time, forw_packet->send_time))
+ return false;
+
++ if (skb_tailroom(forw_packet->skb) < packet_len)
++ return false;
++
+ if (aggregated_bytes > BATADV_MAX_AGGREGATION_BYTES)
+ return false;
+
--- /dev/null
+From stable+bounces-223677-greg=kroah.com@vger.kernel.org Mon Mar 9 15:55:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2026 10:49:54 -0400
+Subject: drm/amd/display: Use GFP_ATOMIC in dc_create_stream_for_sink
+To: stable@vger.kernel.org
+Cc: Natalie Vock <natalie.vock@gmx.de>, Alex Deucher <alexander.deucher@amd.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260309144954.1220459-1-sashal@kernel.org>
+
+From: Natalie Vock <natalie.vock@gmx.de>
+
+[ Upstream commit 28dfe4317541e57fe52f9a290394cd29c348228b ]
+
+This can be called while preemption is disabled, for example by
+dcn32_internal_validate_bw which is called with the FPU active.
+
+Fixes "BUG: scheduling while atomic" messages I encounter on my Navi31
+machine.
+
+Signed-off-by: Natalie Vock <natalie.vock@gmx.de>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit b42dae2ebc5c84a68de63ec4ffdfec49362d53f1)
+Cc: stable@vger.kernel.org
+[ Context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+@@ -167,7 +167,7 @@ struct dc_stream_state *dc_create_stream
+ if (sink == NULL)
+ return NULL;
+
+- stream = kzalloc(sizeof(struct dc_stream_state), GFP_KERNEL);
++ stream = kzalloc(sizeof(struct dc_stream_state), GFP_ATOMIC);
+ if (stream == NULL)
+ goto alloc_fail;
+
--- /dev/null
+From stable+bounces-219699-greg=kroah.com@vger.kernel.org Wed Feb 25 21:09:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Feb 2026 15:09:09 -0500
+Subject: ext4: always allocate blocks only from groups inode can use
+To: stable@vger.kernel.org
+Cc: Jan Kara <jack@suse.cz>, Baokun Li <libaokun1@huawei.com>, Zhang Yi <yi.zhang@huawei.com>, Pedro Falcato <pfalcato@suse.de>, stable@kernel.org, Theodore Ts'o <tytso@mit.edu>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260225200909.1054153-1-sashal@kernel.org>
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 4865c768b563deff1b6a6384e74a62f143427b42 ]
+
+For filesystems with more than 2^32 blocks inodes using indirect block
+based format cannot use blocks beyond the 32-bit limit.
+ext4_mb_scan_groups_linear() takes care to not select these unsupported
+groups for such inodes however other functions selecting groups for
+allocation don't. So far this is harmless because the other selection
+functions are used only with mb_optimize_scan and this is currently
+disabled for inodes with indirect blocks however in the following patch
+we want to enable mb_optimize_scan regardless of inode format.
+
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Acked-by: Pedro Falcato <pfalcato@suse.de>
+Cc: stable@kernel.org
+Link: https://patch.msgid.link/20260114182836.14120-3-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[ Drop a few hunks not needed in older trees ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/mballoc.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -885,6 +885,21 @@ mb_update_avg_fragment_size(struct super
+ write_unlock(&sbi->s_mb_rb_lock);
+ }
+
++static ext4_group_t ext4_get_allocation_groups_count(
++ struct ext4_allocation_context *ac)
++{
++ ext4_group_t ngroups = ext4_get_groups_count(ac->ac_sb);
++
++ /* non-extent files are limited to low blocks/groups */
++ if (!(ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)))
++ ngroups = EXT4_SB(ac->ac_sb)->s_blockfile_groups;
++
++ /* Pairs with smp_wmb() in ext4_update_super() */
++ smp_rmb();
++
++ return ngroups;
++}
++
+ /*
+ * Choose next group by traversing largest_free_order lists. Updates *new_cr if
+ * cr level needs an update.
+@@ -2701,10 +2716,7 @@ ext4_mb_regular_allocator(struct ext4_al
+
+ sb = ac->ac_sb;
+ sbi = EXT4_SB(sb);
+- ngroups = ext4_get_groups_count(sb);
+- /* non-extent files are limited to low blocks/groups */
+- if (!(ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)))
+- ngroups = sbi->s_blockfile_groups;
++ ngroups = ext4_get_allocation_groups_count(ac);
+
+ BUG_ON(ac->ac_status == AC_STATUS_FOUND);
+
--- /dev/null
+From stable+bounces-219160-greg=kroah.com@vger.kernel.org Wed Feb 25 04:06:55 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Feb 2026 22:06:46 -0500
+Subject: ext4: don't set EXT4_GET_BLOCKS_CONVERT when splitting before submitting I/O
+To: stable@vger.kernel.org
+Cc: Zhang Yi <yi.zhang@huawei.com>, Ojaswin Mujoo <ojaswin@linux.ibm.com>, Baokun Li <libaokun1@huawei.com>, stable@kernel.org, Theodore Ts'o <tytso@mit.edu>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260225030646.3846438-1-sashal@kernel.org>
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit feaf2a80e78f89ee8a3464126077ba8683b62791 ]
+
+When allocating blocks during within-EOF DIO and writeback with
+dioread_nolock enabled, EXT4_GET_BLOCKS_PRE_IO was set to split an
+existing large unwritten extent. However, EXT4_GET_BLOCKS_CONVERT was
+set when calling ext4_split_convert_extents(), which may potentially
+result in stale data issues.
+
+Assume we have an unwritten extent, and then DIO writes the second half.
+
+ [UUUUUUUUUUUUUUUU] on-disk extent U: unwritten extent
+ [UUUUUUUUUUUUUUUU] extent status tree
+ |<- ->| ----> dio write this range
+
+First, ext4_iomap_alloc() call ext4_map_blocks() with
+EXT4_GET_BLOCKS_PRE_IO, EXT4_GET_BLOCKS_UNWRIT_EXT and
+EXT4_GET_BLOCKS_CREATE flags set. ext4_map_blocks() find this extent and
+call ext4_split_convert_extents() with EXT4_GET_BLOCKS_CONVERT and the
+above flags set.
+
+Then, ext4_split_convert_extents() calls ext4_split_extent() with
+EXT4_EXT_MAY_ZEROOUT, EXT4_EXT_MARK_UNWRIT2 and EXT4_EXT_DATA_VALID2
+flags set, and it calls ext4_split_extent_at() to split the second half
+with EXT4_EXT_DATA_VALID2, EXT4_EXT_MARK_UNWRIT1, EXT4_EXT_MAY_ZEROOUT
+and EXT4_EXT_MARK_UNWRIT2 flags set. However, ext4_split_extent_at()
+failed to insert extent since a temporary lack -ENOSPC. It zeroes out
+the first half but convert the entire on-disk extent to written since
+the EXT4_EXT_DATA_VALID2 flag set, but left the second half as unwritten
+in the extent status tree.
+
+ [0000000000SSSSSS] data S: stale data, 0: zeroed
+ [WWWWWWWWWWWWWWWW] on-disk extent W: written extent
+ [WWWWWWWWWWUUUUUU] extent status tree
+
+Finally, if the DIO failed to write data to the disk, the stale data in
+the second half will be exposed once the cached extent entry is gone.
+
+Fix this issue by not passing EXT4_GET_BLOCKS_CONVERT when splitting
+an unwritten extent before submitting I/O, and make
+ext4_split_convert_extents() to zero out the entire extent range
+to zero for this case, and also mark the extent in the extent status
+tree for consistency.
+
+Fixes: b8a8684502a0 ("ext4: Introduce FALLOC_FL_ZERO_RANGE flag for fallocate")
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Cc: stable@kernel.org
+Message-ID: <20251129103247.686136-4-yi.zhang@huaweicloud.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[ different function signatures ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3711,11 +3711,15 @@ static int ext4_split_convert_extents(ha
+ /* Convert to unwritten */
+ if (flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN) {
+ split_flag |= EXT4_EXT_DATA_VALID1;
+- /* Convert to initialized */
+- } else if (flags & EXT4_GET_BLOCKS_CONVERT) {
++ /* Split the existing unwritten extent */
++ } else if (flags & (EXT4_GET_BLOCKS_UNWRIT_EXT |
++ EXT4_GET_BLOCKS_CONVERT)) {
+ split_flag |= ee_block + ee_len <= eof_block ?
+ EXT4_EXT_MAY_ZEROOUT : 0;
+- split_flag |= (EXT4_EXT_MARK_UNWRIT2 | EXT4_EXT_DATA_VALID2);
++ split_flag |= EXT4_EXT_MARK_UNWRIT2;
++ /* Convert to initialized */
++ if (flags & EXT4_GET_BLOCKS_CONVERT)
++ split_flag |= EXT4_EXT_DATA_VALID2;
+ }
+ flags |= EXT4_GET_BLOCKS_PRE_IO;
+ return ext4_split_extent(handle, inode, ppath, map, split_flag, flags);
+@@ -3880,7 +3884,7 @@ ext4_ext_handle_unwritten_extents(handle
+ /* get_block() before submitting IO, split the extent */
+ if (flags & EXT4_GET_BLOCKS_PRE_IO) {
+ ret = ext4_split_convert_extents(handle, inode, map, ppath,
+- flags | EXT4_GET_BLOCKS_CONVERT);
++ flags);
+ if (ret < 0) {
+ err = ret;
+ goto out2;
--- /dev/null
+From stable+bounces-219623-greg=kroah.com@vger.kernel.org Wed Feb 25 14:51:50 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Feb 2026 08:46:56 -0500
+Subject: ext4: drop extent cache when splitting extent fails
+To: stable@vger.kernel.org
+Cc: Zhang Yi <yi.zhang@huawei.com>, Baokun Li <libaokun1@huawei.com>, stable@kernel.org, Ojaswin Mujoo <ojaswin@linux.ibm.com>, Theodore Ts'o <tytso@mit.edu>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260225134656.309822-1-sashal@kernel.org>
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+[ Upstream commit 79b592e8f1b435796cbc2722190368e3e8ffd7a1 ]
+
+When the split extent fails, we might leave some extents still being
+processed and return an error directly, which will result in stale
+extent entries remaining in the extent status tree. So drop all of the
+remaining potentially stale extents if the splitting fails.
+
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Cc: stable@kernel.org
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Message-ID: <20251129103247.686136-8-yi.zhang@huaweicloud.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[ bring error handling pattern closer to upstream ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3236,7 +3236,9 @@ static int ext4_split_extent_at(handle_t
+ ext4_ext_mark_unwritten(ex2);
+
+ err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
+- if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
++ if (err && err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
++ goto out_err;
++ if (!err)
+ goto out;
+
+ /*
+@@ -3252,7 +3254,8 @@ static int ext4_split_extent_at(handle_t
+ if (IS_ERR(path)) {
+ EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
+ split, PTR_ERR(path));
+- return PTR_ERR(path);
++ err = PTR_ERR(path);
++ goto out_err;
+ }
+ depth = ext_depth(inode);
+ ex = path[depth].p_ext;
+@@ -3308,6 +3311,9 @@ fix_extent_len:
+ */
+ ext4_ext_dirty(handle, inode, path + path->p_depth);
+ return err;
++out_err:
++ /* Remove all remaining potentially stale extents. */
++ ext4_es_remove_extent(inode, ee_block, ee_len);
+ out:
+ ext4_ext_show_leaf(inode, *ppath);
+ return err;
--- /dev/null
+From stable+bounces-219643-greg=kroah.com@vger.kernel.org Wed Feb 25 15:57:47 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Feb 2026 09:52:32 -0500
+Subject: ext4: fix dirtyclusters double decrement on fs shutdown
+To: stable@vger.kernel.org
+Cc: Brian Foster <bfoster@redhat.com>, Baokun Li <libaokun1@huawei.com>, Theodore Ts'o <tytso@mit.edu>, stable@kernel.org, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260225145232.546260-1-sashal@kernel.org>
+
+From: Brian Foster <bfoster@redhat.com>
+
+[ Upstream commit 94a8cea54cd935c54fa2fba70354757c0fc245e3 ]
+
+fstests test generic/388 occasionally reproduces a warning in
+ext4_put_super() associated with the dirty clusters count:
+
+ WARNING: CPU: 7 PID: 76064 at fs/ext4/super.c:1324 ext4_put_super+0x48c/0x590 [ext4]
+
+Tracing the failure shows that the warning fires due to an
+s_dirtyclusters_counter value of -1. IOW, this appears to be a
+spurious decrement as opposed to some sort of leak. Further tracing
+of the dirty cluster count deltas and an LLM scan of the resulting
+output identified the cause as a double decrement in the error path
+between ext4_mb_mark_diskspace_used() and the caller
+ext4_mb_new_blocks().
+
+First, note that generic/388 is a shutdown vs. fsstress test and so
+produces a random set of operations and shutdown injections. In the
+problematic case, the shutdown triggers an error return from the
+ext4_handle_dirty_metadata() call(s) made from
+ext4_mb_mark_context(). The changed value is non-zero at this point,
+so ext4_mb_mark_diskspace_used() does not exit after the error
+bubbles up from ext4_mb_mark_context(). Instead, the former
+decrements both cluster counters and returns the error up to
+ext4_mb_new_blocks(). The latter falls into the !ar->len out path
+which decrements the dirty clusters counter a second time, creating
+the inconsistency.
+
+To avoid this problem and simplify ownership of the cluster
+reservation in this codepath, lift the counter reduction to a single
+place in the caller. This makes it more clear that
+ext4_mb_new_blocks() is responsible for acquiring cluster
+reservation (via ext4_claim_free_clusters()) in the !delalloc case
+as well as releasing it, regardless of whether it ends up consumed
+or returned due to failure.
+
+Fixes: 0087d9fb3f29 ("ext4: Fix s_dirty_blocks_counter if block allocation failed with nodelalloc")
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Link: https://patch.msgid.link/20260113171905.118284-1-bfoster@redhat.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+[ Drop mballoc-test changes ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/mballoc.c | 21 +++++----------------
+ 1 file changed, 5 insertions(+), 16 deletions(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -3835,8 +3835,7 @@ void ext4_exit_mballoc(void)
+ * Returns 0 if success or error code
+ */
+ static noinline_for_stack int
+-ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
+- handle_t *handle, unsigned int reserv_clstrs)
++ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, handle_t *handle)
+ {
+ struct buffer_head *bitmap_bh = NULL;
+ struct ext4_group_desc *gdp;
+@@ -3924,13 +3923,6 @@ ext4_mb_mark_diskspace_used(struct ext4_
+
+ ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
+ percpu_counter_sub(&sbi->s_freeclusters_counter, ac->ac_b_ex.fe_len);
+- /*
+- * Now reduce the dirty block count also. Should not go negative
+- */
+- if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED))
+- /* release all the reserved blocks if non delalloc */
+- percpu_counter_sub(&sbi->s_dirtyclusters_counter,
+- reserv_clstrs);
+
+ if (sbi->s_log_groups_per_flex) {
+ ext4_group_t flex_group = ext4_flex_group(sbi,
+@@ -5802,7 +5794,7 @@ repeat:
+ ext4_mb_pa_free(ac);
+ }
+ if (likely(ac->ac_status == AC_STATUS_FOUND)) {
+- *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_clstrs);
++ *errp = ext4_mb_mark_diskspace_used(ac, handle);
+ if (*errp) {
+ ext4_discard_allocated_blocks(ac);
+ goto errout;
+@@ -5834,12 +5826,9 @@ out:
+ kmem_cache_free(ext4_ac_cachep, ac);
+ if (inquota && ar->len < inquota)
+ dquot_free_block(ar->inode, EXT4_C2B(sbi, inquota - ar->len));
+- if (!ar->len) {
+- if ((ar->flags & EXT4_MB_DELALLOC_RESERVED) == 0)
+- /* release all the reserved blocks if non delalloc */
+- percpu_counter_sub(&sbi->s_dirtyclusters_counter,
+- reserv_clstrs);
+- }
++ /* release any reserved blocks */
++ if (reserv_clstrs)
++ percpu_counter_sub(&sbi->s_dirtyclusters_counter, reserv_clstrs);
+
+ trace_ext4_allocate_blocks(ar, (unsigned long long)block);
+
--- /dev/null
+From stable+bounces-219635-greg=kroah.com@vger.kernel.org Wed Feb 25 15:38:14 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 25 Feb 2026 09:33:49 -0500
+Subject: ext4: fix e4b bitmap inconsistency reports
+To: stable@vger.kernel.org
+Cc: Yongjian Sun <sunyongjian1@huawei.com>, Zhang Yi <yi.zhang@huawei.com>, Baokun Li <libaokun1@huawei.com>, Jan Kara <jack@suse.cz>, Theodore Ts'o <tytso@mit.edu>, stable@kernel.org, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260225143349.471932-1-sashal@kernel.org>
+
+From: Yongjian Sun <sunyongjian1@huawei.com>
+
+[ Upstream commit bdc56a9c46b2a99c12313122b9352b619a2e719e ]
+
+A bitmap inconsistency issue was observed during stress tests under
+mixed huge-page workloads. Ext4 reported multiple e4b bitmap check
+failures like:
+
+ext4_mb_complex_scan_group:2508: group 350, 8179 free clusters as
+per group info. But got 8192 blocks
+
+Analysis and experimentation confirmed that the issue is caused by a
+race condition between page migration and bitmap modification. Although
+this timing window is extremely narrow, it is still hit in practice:
+
+folio_lock ext4_mb_load_buddy
+__migrate_folio
+ check ref count
+ folio_mc_copy __filemap_get_folio
+ folio_try_get(folio)
+ ......
+ mb_mark_used
+ ext4_mb_unload_buddy
+ __folio_migrate_mapping
+ folio_ref_freeze
+folio_unlock
+
+The root cause of this issue is that the fast path of load_buddy only
+increments the folio's reference count, which is insufficient to prevent
+concurrent folio migration. We observed that the folio migration process
+acquires the folio lock. Therefore, we can determine whether to take the
+fast path in load_buddy by checking the lock status. If the folio is
+locked, we opt for the slow path (which acquires the lock) to close this
+concurrency window.
+
+Additionally, this change addresses the following issues:
+
+When the DOUBLE_CHECK macro is enabled to inspect bitmap-related
+issues, the following error may be triggered:
+
+corruption in group 324 at byte 784(6272): f in copy != ff on
+disk/prealloc
+
+Analysis reveals that this is a false positive. There is a specific race
+window where the bitmap and the group descriptor become momentarily
+inconsistent, leading to this error report:
+
+ext4_mb_load_buddy ext4_mb_load_buddy
+ __filemap_get_folio(create|lock)
+ folio_lock
+ ext4_mb_init_cache
+ folio_mark_uptodate
+ __filemap_get_folio(no lock)
+ ......
+ mb_mark_used
+ mb_mark_used_double
+ mb_cmp_bitmaps
+ mb_set_bits(e4b->bd_bitmap)
+ folio_unlock
+
+The original logic assumed that since mb_cmp_bitmaps is called when the
+bitmap is newly loaded from disk, the folio lock would be sufficient to
+prevent concurrent access. However, this overlooks a specific race
+condition: if another process attempts to load buddy and finds the folio
+is already in an uptodate state, it will immediately begin using it without
+holding folio lock.
+
+Signed-off-by: Yongjian Sun <sunyongjian1@huawei.com>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20260106090820.836242-1-sunyongjian@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+[ folio -> page ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/mballoc.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -1568,16 +1568,17 @@ ext4_mb_load_buddy_gfp(struct super_bloc
+ /* we could use find_or_create_page(), but it locks page
+ * what we'd like to avoid in fast path ... */
+ page = find_get_page_flags(inode->i_mapping, pnum, FGP_ACCESSED);
+- if (page == NULL || !PageUptodate(page)) {
++ if (page == NULL || !PageUptodate(page) || PageLocked(page)) {
++ /*
++ * PageLocked is employed to detect ongoing page
++ * migrations, since concurrent migrations can lead to
++ * bitmap inconsistency. And if we are not uptodate that
++ * implies somebody just created the page but is yet to
++ * initialize it. We can drop the page reference and
++ * try to get the page with lock in both cases to avoid
++ * concurrency.
++ */
+ if (page)
+- /*
+- * drop the page reference and try
+- * to get the page with lock. If we
+- * are not uptodate that implies
+- * somebody just created the page but
+- * is yet to initialize the same. So
+- * wait for it to initialize.
+- */
+ put_page(page);
+ page = find_or_create_page(inode->i_mapping, pnum, gfp);
+ if (page) {
+@@ -1612,7 +1613,7 @@ ext4_mb_load_buddy_gfp(struct super_bloc
+ poff = block % blocks_per_page;
+
+ page = find_get_page_flags(inode->i_mapping, pnum, FGP_ACCESSED);
+- if (page == NULL || !PageUptodate(page)) {
++ if (page == NULL || !PageUptodate(page) || PageLocked(page)) {
+ if (page)
+ put_page(page);
+ page = find_or_create_page(inode->i_mapping, pnum, gfp);
--- /dev/null
+From stable+bounces-219136-greg=kroah.com@vger.kernel.org Wed Feb 25 03:35:14 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Feb 2026 21:35:05 -0500
+Subject: ksmbd: call ksmbd_vfs_kern_path_end_removing() on some error paths
+To: stable@vger.kernel.org
+Cc: Fedor Pchelkin <pchelkin@ispras.ru>, Namjae Jeon <linkinjeon@kernel.org>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260225023506.3815115-1-sashal@kernel.org>
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit a09dc10d1353f0e92c21eae2a79af1c2b1ddcde8 ]
+
+There are two places where ksmbd_vfs_kern_path_end_removing() needs to be
+called in order to balance what the corresponding successful call to
+ksmbd_vfs_kern_path_start_removing() has done, i.e. drop inode locks and
+put the taken references. Otherwise there might be potential deadlocks
+and unbalanced locks which are caught like:
+
+BUG: workqueue leaked lock or atomic: kworker/5:21/0x00000000/7596
+ last function: handle_ksmbd_work
+2 locks held by kworker/5:21/7596:
+ #0: ffff8881051ae448 (sb_writers#3){.+.+}-{0:0}, at: ksmbd_vfs_kern_path_locked+0x142/0x660
+ #1: ffff888130e966c0 (&type->i_mutex_dir_key#3/1){+.+.}-{4:4}, at: ksmbd_vfs_kern_path_locked+0x17d/0x660
+CPU: 5 PID: 7596 Comm: kworker/5:21 Not tainted 6.1.162-00456-gc29b353f383b #138
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
+Workqueue: ksmbd-io handle_ksmbd_work
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x44/0x5b
+ process_one_work.cold+0x57/0x5c
+ worker_thread+0x82/0x600
+ kthread+0x153/0x190
+ ret_from_fork+0x22/0x30
+ </TASK>
+
+Found by Linux Verification Center (linuxtesting.org).
+
+Fixes: d5fc1400a34b ("smb/server: avoid deadlock when linking with ReplaceIfExists")
+Cc: stable@vger.kernel.org
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Acked-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+[ ksmbd_vfs_kern_path_end_removing() call -> ksmbd_vfs_kern_path_unlock() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ksmbd/smb2pdu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -5652,14 +5652,14 @@ static int smb2_create_link(struct ksmbd
+ rc = -EINVAL;
+ ksmbd_debug(SMB, "cannot delete %s\n",
+ link_name);
+- goto out;
+ }
+ } else {
+ rc = -EEXIST;
+ ksmbd_debug(SMB, "link already exists\n");
+- goto out;
+ }
+ ksmbd_vfs_kern_path_unlock(&parent_path, &path);
++ if (rc)
++ goto out;
+ }
+ rc = ksmbd_vfs_link(work, target_name, link_name);
+ if (rc)
--- /dev/null
+From alvalan9@foxmail.com Wed Feb 25 11:34:13 2026
+From: Alva Lan <alvalan9@foxmail.com>
+Date: Wed, 25 Feb 2026 18:33:45 +0800
+Subject: ksmbd: fix null pointer dereference error in generate_encryptionkey
+To: stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: Namjae Jeon <linkinjeon@kernel.org>, zdi-disclosures@trendmicro.com, Steve French <stfrench@microsoft.com>, Alva Lan <alvalan9@foxmail.com>
+Message-ID: <tencent_C3D62F38B3307E0DE0B470350C1FCD926008@qq.com>
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit 9b493ab6f35178afd8d619800df9071992f715de ]
+
+If client send two session setups with krb5 authenticate to ksmbd,
+null pointer dereference error in generate_encryptionkey could happen.
+sess->Preauth_HashValue is set to NULL if session is valid.
+So this patch skip generate encryption key if session is valid.
+
+Cc: stable@vger.kernel.org
+Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-27654
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Alva Lan <alvalan9@foxmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ksmbd/smb2pdu.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -1628,11 +1628,24 @@ static int krb5_authenticate(struct ksmb
+ }
+ rsp->SecurityBufferLength = cpu_to_le16(out_len);
+
+- if ((conn->sign || server_conf.enforced_signing) ||
++ /*
++ * If session state is SMB2_SESSION_VALID, We can assume
++ * that it is reauthentication. And the user/password
++ * has been verified, so return it here.
++ */
++ if (sess->state == SMB2_SESSION_VALID) {
++ if (conn->binding)
++ goto binding_session;
++ return 0;
++ }
++
++ if ((rsp->SessionFlags != SMB2_SESSION_FLAG_IS_GUEST_LE &&
++ (conn->sign || server_conf.enforced_signing)) ||
+ (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED))
+ sess->sign = true;
+
+- if (smb3_encryption_negotiated(conn)) {
++ if (smb3_encryption_negotiated(conn) &&
++ !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) {
+ retval = conn->ops->generate_encryptionkey(conn, sess);
+ if (retval) {
+ ksmbd_debug(SMB,
+@@ -1645,6 +1658,7 @@ static int krb5_authenticate(struct ksmb
+ sess->sign = false;
+ }
+
++binding_session:
+ if (conn->dialect >= SMB30_PROT_ID) {
+ chann = lookup_chann_list(sess, conn);
+ if (!chann) {
--- /dev/null
+From stable+bounces-223697-greg=kroah.com@vger.kernel.org Mon Mar 9 17:21:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2026 12:06:22 -0400
+Subject: mptcp: pm: avoid sending RM_ADDR over same subflow
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Frank Lorenz <lorenz-frank@web.de>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260309160622.1298481-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit fb8d0bccb221080630efcd9660c9f9349e53cc9e ]
+
+RM_ADDR are sent over an active subflow, the first one in the subflows
+list. There is then a high chance the initial subflow is picked. With
+the in-kernel PM, when an endpoint is removed, a RM_ADDR is sent, then
+linked subflows are closed. This is done for each active MPTCP
+connection.
+
+MPTCP endpoints are likely removed because the attached network is no
+longer available or usable. In this case, it is better to avoid sending
+this RM_ADDR over the subflow that is going to be removed, but prefer
+sending it over another active and non stale subflow, if any.
+
+This modification avoids situations where the other end is not notified
+when a subflow is no longer usable: typically when the endpoint linked
+to the initial subflow is removed, especially on the server side.
+
+Fixes: 8dd5efb1f91b ("mptcp: send ack for rm_addr")
+Cc: stable@vger.kernel.org
+Reported-by: Frank Lorenz <lorenz-frank@web.de>
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/612
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260303-net-mptcp-misc-fixes-7-0-rc2-v1-2-4b5462b6f016@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ pm.c => pm_netlink.c + replaced subflow_get_local_id() with subflow->local_id ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm.c | 2 -
+ net/mptcp/pm_netlink.c | 57 +++++++++++++++++++++++++++++++++++++++----------
+ net/mptcp/protocol.h | 2 +
+ 3 files changed, 49 insertions(+), 12 deletions(-)
+
+--- a/net/mptcp/pm.c
++++ b/net/mptcp/pm.c
+@@ -55,7 +55,7 @@ int mptcp_pm_remove_addr(struct mptcp_so
+ msk->pm.rm_list_tx = *rm_list;
+ rm_addr |= BIT(MPTCP_RM_ADDR_SIGNAL);
+ WRITE_ONCE(msk->pm.addr_signal, rm_addr);
+- mptcp_pm_nl_addr_send_ack(msk);
++ mptcp_pm_nl_addr_send_ack_avoid_list(msk, rm_list);
+ return 0;
+ }
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -753,9 +753,23 @@ bool mptcp_pm_nl_is_init_remote_addr(str
+ return addresses_equal(&mpc_remote, remote, remote->port);
+ }
+
+-void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
++static bool subflow_in_rm_list(const struct mptcp_subflow_context *subflow,
++ const struct mptcp_rm_list *rm_list)
++{
++ u8 i, id = subflow->local_id;
++
++ for (i = 0; i < rm_list->nr; i++) {
++ if (rm_list->ids[i] == id)
++ return true;
++ }
++
++ return false;
++}
++
++void mptcp_pm_nl_addr_send_ack_avoid_list(struct mptcp_sock *msk,
++ const struct mptcp_rm_list *rm_list)
+ {
+- struct mptcp_subflow_context *subflow;
++ struct mptcp_subflow_context *subflow, *same_id = NULL;
+
+ msk_owned_by_me(msk);
+ lockdep_assert_held(&msk->pm.lock);
+@@ -766,18 +780,39 @@ void mptcp_pm_nl_addr_send_ack(struct mp
+
+ __mptcp_flush_join_list(msk);
+ mptcp_for_each_subflow(msk, subflow) {
+- if (__mptcp_subflow_active(subflow)) {
+- struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
++ if (!__mptcp_subflow_active(subflow))
++ continue;
+
+- spin_unlock_bh(&msk->pm.lock);
+- pr_debug("send ack for %s\n",
+- mptcp_pm_should_add_signal(msk) ? "add_addr" : "rm_addr");
+-
+- mptcp_subflow_send_ack(ssk);
+- spin_lock_bh(&msk->pm.lock);
+- break;
++ if (unlikely(rm_list &&
++ subflow_in_rm_list(subflow, rm_list))) {
++ if (!same_id)
++ same_id = subflow;
++ } else {
++ goto send_ack;
+ }
+ }
++
++ if (same_id)
++ subflow = same_id;
++ else
++ return;
++
++send_ack:
++ {
++ struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
++
++ spin_unlock_bh(&msk->pm.lock);
++ pr_debug("send ack for %s\n",
++ mptcp_pm_should_add_signal(msk) ? "add_addr" : "rm_addr");
++
++ mptcp_subflow_send_ack(ssk);
++ spin_lock_bh(&msk->pm.lock);
++ }
++}
++
++void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
++{
++ mptcp_pm_nl_addr_send_ack_avoid_list(msk, NULL);
+ }
+
+ int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -753,6 +753,8 @@ void mptcp_pm_add_addr_send_ack(struct m
+ bool mptcp_pm_nl_is_init_remote_addr(struct mptcp_sock *msk,
+ const struct mptcp_addr_info *remote);
+ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk);
++void mptcp_pm_nl_addr_send_ack_avoid_list(struct mptcp_sock *msk,
++ const struct mptcp_rm_list *rm_list);
+ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk,
+ const struct mptcp_rm_list *rm_list);
+ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup);
--- /dev/null
+From stable+bounces-223661-greg=kroah.com@vger.kernel.org Mon Mar 9 15:02:23 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2026 09:59:58 -0400
+Subject: net: phy: register phy led_triggers during probe to avoid AB-BA deadlock
+To: stable@vger.kernel.org
+Cc: Andrew Lunn <andrew@lunn.ch>, Shiji Yang <yangshiji66@outlook.com>, Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260309135959.1064428-1-sashal@kernel.org>
+
+From: Andrew Lunn <andrew@lunn.ch>
+
+[ Upstream commit c8dbdc6e380e7e96a51706db3e4b7870d8a9402d ]
+
+There is an AB-BA deadlock when both LEDS_TRIGGER_NETDEV and
+LED_TRIGGER_PHY are enabled:
+
+[ 1362.049207] [<8054e4b8>] led_trigger_register+0x5c/0x1fc <-- Trying to get lock "triggers_list_lock" via down_write(&triggers_list_lock);
+[ 1362.054536] [<80662830>] phy_led_triggers_register+0xd0/0x234
+[ 1362.060329] [<8065e200>] phy_attach_direct+0x33c/0x40c
+[ 1362.065489] [<80651fc4>] phylink_fwnode_phy_connect+0x15c/0x23c
+[ 1362.071480] [<8066ee18>] mtk_open+0x7c/0xba0
+[ 1362.075849] [<806d714c>] __dev_open+0x280/0x2b0
+[ 1362.080384] [<806d7668>] __dev_change_flags+0x244/0x24c
+[ 1362.085598] [<806d7698>] dev_change_flags+0x28/0x78
+[ 1362.090528] [<807150e4>] dev_ioctl+0x4c0/0x654 <-- Hold lock "rtnl_mutex" by calling rtnl_lock();
+[ 1362.094985] [<80694360>] sock_ioctl+0x2f4/0x4e0
+[ 1362.099567] [<802e9c4c>] sys_ioctl+0x32c/0xd8c
+[ 1362.104022] [<80014504>] syscall_common+0x34/0x58
+
+Here LED_TRIGGER_PHY is registering LED triggers during phy_attach
+while holding RTNL and then taking triggers_list_lock.
+
+[ 1362.191101] [<806c2640>] register_netdevice_notifier+0x60/0x168 <-- Trying to get lock "rtnl_mutex" via rtnl_lock();
+[ 1362.197073] [<805504ac>] netdev_trig_activate+0x194/0x1e4
+[ 1362.202490] [<8054e28c>] led_trigger_set+0x1d4/0x360 <-- Hold lock "triggers_list_lock" by down_read(&triggers_list_lock);
+[ 1362.207511] [<8054eb38>] led_trigger_write+0xd8/0x14c
+[ 1362.212566] [<80381d98>] sysfs_kf_bin_write+0x80/0xbc
+[ 1362.217688] [<8037fcd8>] kernfs_fop_write_iter+0x17c/0x28c
+[ 1362.223174] [<802cbd70>] vfs_write+0x21c/0x3c4
+[ 1362.227712] [<802cc0c4>] ksys_write+0x78/0x12c
+[ 1362.232164] [<80014504>] syscall_common+0x34/0x58
+
+Here LEDS_TRIGGER_NETDEV is being enabled on an LED. It first takes
+triggers_list_lock and then RTNL. A classical AB-BA deadlock.
+
+phy_led_triggers_registers() does not require the RTNL, it does not
+make any calls into the network stack which require protection. There
+is also no requirement the PHY has been attached to a MAC, the
+triggers only make use of phydev state. This allows the call to
+phy_led_triggers_registers() to be placed elsewhere. PHY probe() and
+release() don't hold RTNL, so solving the AB-BA deadlock.
+
+Reported-by: Shiji Yang <yangshiji66@outlook.com>
+Closes: https://lore.kernel.org/all/OS7PR01MB13602B128BA1AD3FA38B6D1FFBC69A@OS7PR01MB13602.jpnprd01.prod.outlook.com/
+Fixes: 06f502f57d0d ("leds: trigger: Introduce a NETDEV trigger")
+Cc: stable@vger.kernel.org
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Tested-by: Shiji Yang <yangshiji66@outlook.com>
+Link: https://patch.msgid.link/20260222152601.1978655-1-andrew@lunn.ch
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+[ dropped `is_on_sfp_module` guards and `CONFIG_PHYLIB_LEDS`/`of_phy_leds` logic ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/phy_device.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -1508,7 +1508,6 @@ int phy_attach_direct(struct net_device
+ return err;
+
+ phy_resume(phydev);
+- phy_led_triggers_register(phydev);
+
+ return err;
+
+@@ -1765,8 +1764,6 @@ void phy_detach(struct phy_device *phyde
+ }
+ phydev->phylink = NULL;
+
+- phy_led_triggers_unregister(phydev);
+-
+ if (phydev->mdio.dev.driver)
+ module_put(phydev->mdio.dev.driver->owner);
+
+@@ -3120,10 +3117,14 @@ static int phy_probe(struct device *dev)
+ /* Set the state to READY by default */
+ phydev->state = PHY_READY;
+
++ /* Register the PHY LED triggers */
++ phy_led_triggers_register(phydev);
++
++ return 0;
++
+ out:
+ /* Re-assert the reset signal on error */
+- if (err)
+- phy_device_reset(phydev, 1);
++ phy_device_reset(phydev, 1);
+
+ return err;
+ }
+@@ -3134,6 +3135,8 @@ static int phy_remove(struct device *dev
+
+ cancel_delayed_work_sync(&phydev->state_queue);
+
++ phy_led_triggers_unregister(phydev);
++
+ phydev->state = PHY_DOWN;
+
+ sfp_bus_del_upstream(phydev->sfp_bus);
--- /dev/null
+From stable+bounces-227765-greg=kroah.com@vger.kernel.org Sat Mar 21 13:41:32 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 21 Mar 2026 08:41:08 -0400
+Subject: pmdomain: bcm: bcm2835-power: Increase ASB control timeout
+To: stable@vger.kernel.org
+Cc: "Maíra Canal" <mcanal@igalia.com>, "Stefan Wahren" <wahrenst@gmx.net>, "Ulf Hansson" <ulf.hansson@linaro.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260321124108.268680-1-sashal@kernel.org>
+
+From: Maíra Canal <mcanal@igalia.com>
+
+[ Upstream commit b826d2c0b0ecb844c84431ba6b502e744f5d919a ]
+
+The bcm2835_asb_control() function uses a tight polling loop to wait
+for the ASB bridge to acknowledge a request. During intensive workloads,
+this handshake intermittently fails for V3D's master ASB on BCM2711,
+resulting in "Failed to disable ASB master for v3d" errors during
+runtime PM suspend. As a consequence, the failed power-off leaves V3D in
+a broken state, leading to bus faults or system hangs on later accesses.
+
+As the timeout is insufficient in some scenarios, increase the polling
+timeout from 1us to 5us, which is still negligible in the context of a
+power domain transition. Also, replace the open-coded ktime_get_ns()/
+cpu_relax() polling loop with readl_poll_timeout_atomic().
+
+Cc: stable@vger.kernel.org
+Fixes: 670c672608a1 ("soc: bcm: bcm2835-pm: Add support for power domains under a new binding.")
+Signed-off-by: Maíra Canal <mcanal@igalia.com>
+Reviewed-by: Stefan Wahren <wahrenst@gmx.net>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+[ adapted unified bcm2835_asb_control() function changes to separate bcm2835_asb_enable() and bcm2835_asb_disable() functions ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/soc/bcm/bcm2835-power.c | 27 +++++++++++----------------
+ 1 file changed, 11 insertions(+), 16 deletions(-)
+
+--- a/drivers/soc/bcm/bcm2835-power.c
++++ b/drivers/soc/bcm/bcm2835-power.c
+@@ -9,6 +9,7 @@
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/mfd/bcm2835-pm.h>
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+@@ -150,40 +151,34 @@ struct bcm2835_power {
+
+ static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg)
+ {
+- u64 start;
++ u32 val;
+
+ if (!reg)
+ return 0;
+
+- start = ktime_get_ns();
+-
+ /* Enable the module's async AXI bridges. */
+ ASB_WRITE(reg, ASB_READ(reg) & ~ASB_REQ_STOP);
+- while (ASB_READ(reg) & ASB_ACK) {
+- cpu_relax();
+- if (ktime_get_ns() - start >= 1000)
+- return -ETIMEDOUT;
+- }
++
++ if (readl_poll_timeout_atomic(power->asb + reg, val,
++ !(val & ASB_ACK), 0, 5))
++ return -ETIMEDOUT;
+
+ return 0;
+ }
+
+ static int bcm2835_asb_disable(struct bcm2835_power *power, u32 reg)
+ {
+- u64 start;
++ u32 val;
+
+ if (!reg)
+ return 0;
+
+- start = ktime_get_ns();
+-
+ /* Enable the module's async AXI bridges. */
+ ASB_WRITE(reg, ASB_READ(reg) | ASB_REQ_STOP);
+- while (!(ASB_READ(reg) & ASB_ACK)) {
+- cpu_relax();
+- if (ktime_get_ns() - start >= 1000)
+- return -ETIMEDOUT;
+- }
++
++ if (readl_poll_timeout_atomic(power->asb + reg, val,
++ !!(val & ASB_ACK), 0, 5))
++ return -ETIMEDOUT;
+
+ return 0;
+ }
--- /dev/null
+From stable+bounces-223648-greg=kroah.com@vger.kernel.org Mon Mar 9 14:29:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2026 09:27:39 -0400
+Subject: RDMA/irdma: Fix kernel stack leak in irdma_create_user_ah()
+To: stable@vger.kernel.org
+Cc: Jason Gunthorpe <jgg@ziepe.ca>, Jason Gunthorpe <jgg@nvidia.com>, Leon Romanovsky <leon@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260309132739.944769-1-sashal@kernel.org>
+
+From: Jason Gunthorpe <jgg@ziepe.ca>
+
+[ Upstream commit 74586c6da9ea222a61c98394f2fc0a604748438c ]
+
+struct irdma_create_ah_resp { // 8 bytes, no padding
+ __u32 ah_id; // offset 0 - SET (uresp.ah_id = ah->sc_ah.ah_info.ah_idx)
+ __u8 rsvd[4]; // offset 4 - NEVER SET <- LEAK
+};
+
+rsvd[4]: 4 bytes of stack memory leaked unconditionally. Only ah_id is assigned before ib_respond_udata().
+
+The reserved members of the structure were not zeroed.
+
+Cc: stable@vger.kernel.org
+Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://patch.msgid.link/3-v1-83e918d69e73+a9-rdma_udata_rc_jgg@nvidia.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+[ adapted fix to combined irdma_create_ah() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/irdma/verbs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -4170,7 +4170,7 @@ static int irdma_create_ah(struct ib_ah
+ struct irdma_sc_ah *sc_ah;
+ u32 ah_id = 0;
+ struct irdma_ah_info *ah_info;
+- struct irdma_create_ah_resp uresp;
++ struct irdma_create_ah_resp uresp = {};
+ union {
+ struct sockaddr saddr;
+ struct sockaddr_in saddr_in;
drm-exynos-vidi-use-priv-vidi_dev-for-ctx-lookup-in-vidi_connection_ioctl.patch
drm-exynos-vidi-fix-to-avoid-directly-dereferencing-user-pointer.patch
drm-exynos-vidi-use-ctx-lock-to-protect-struct-vidi_context-member-variables-related-to-memory-alloc-free.patch
+ksmbd-call-ksmbd_vfs_kern_path_end_removing-on-some-error-paths.patch
+ext4-don-t-set-ext4_get_blocks_convert-when-splitting-before-submitting-i-o.patch
+ext4-drop-extent-cache-when-splitting-extent-fails.patch
+ext4-fix-e4b-bitmap-inconsistency-reports.patch
+ext4-fix-dirtyclusters-double-decrement-on-fs-shutdown.patch
+ksmbd-fix-null-pointer-dereference-error-in-generate_encryptionkey.patch
+ext4-always-allocate-blocks-only-from-groups-inode-can-use.patch
+wifi-libertas-fix-use-after-free-in-lbs_free_adapter.patch
+wifi-cfg80211-move-scan-done-work-to-wiphy-work.patch
+wifi-cfg80211-cancel-rfkill_block-work-in-wiphy_unregister.patch
+rdma-irdma-fix-kernel-stack-leak-in-irdma_create_user_ah.patch
+smb-client-don-t-log-plaintext-credentials-in-cifs_set_cifscreds.patch
+net-phy-register-phy-led_triggers-during-probe-to-avoid-ab-ba-deadlock.patch
+drm-amd-display-use-gfp_atomic-in-dc_create_stream_for_sink.patch
+mptcp-pm-avoid-sending-rm_addr-over-same-subflow.patch
+pmdomain-bcm-bcm2835-power-increase-asb-control-timeout.patch
+batman-adv-avoid-ogm-aggregation-when-skb-tailroom-is-insufficient.patch
+ata-libata-scsi-drop-dprintk-calls-for-cdb-translation.patch
--- /dev/null
+From stable+bounces-223662-greg=kroah.com@vger.kernel.org Mon Mar 9 15:00:27 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2026 10:00:09 -0400
+Subject: smb: client: Don't log plaintext credentials in cifs_set_cifscreds
+To: stable@vger.kernel.org
+Cc: Thorsten Blum <thorsten.blum@linux.dev>, "Paulo Alcantara (Red Hat)" <pc@manguebit.org>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260309140009.1065571-1-sashal@kernel.org>
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit 2f37dc436d4e61ff7ae0b0353cf91b8c10396e4d ]
+
+When debug logging is enabled, cifs_set_cifscreds() logs the key
+payload and exposes the plaintext username and password. Remove the
+debug log to avoid exposing credentials.
+
+Fixes: 8a8798a5ff90 ("cifs: fetch credentials out of keyring for non-krb5 auth multiuser mounts")
+Cc: stable@vger.kernel.org
+Acked-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/connect.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1874,7 +1874,6 @@ cifs_set_cifscreds(struct smb3_fs_contex
+ /* find first : in payload */
+ payload = upayload->data;
+ delim = strnchr(payload, upayload->datalen, ':');
+- cifs_dbg(FYI, "payload=%s\n", payload);
+ if (!delim) {
+ cifs_dbg(FYI, "Unable to find ':' in payload (datalen=%d)\n",
+ upayload->datalen);
--- /dev/null
+From stable+bounces-223620-greg=kroah.com@vger.kernel.org Mon Mar 9 12:44:02 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2026 07:42:24 -0400
+Subject: wifi: cfg80211: cancel rfkill_block work in wiphy_unregister()
+To: stable@vger.kernel.org
+Cc: Daniil Dulov <d.dulov@aladdin.ru>, Johannes Berg <johannes.berg@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260309114224.831897-2-sashal@kernel.org>
+
+From: Daniil Dulov <d.dulov@aladdin.ru>
+
+[ Upstream commit 767d23ade706d5fa51c36168e92a9c5533c351a1 ]
+
+There is a use-after-free error in cfg80211_shutdown_all_interfaces found
+by syzkaller:
+
+BUG: KASAN: use-after-free in cfg80211_shutdown_all_interfaces+0x213/0x220
+Read of size 8 at addr ffff888112a78d98 by task kworker/0:5/5326
+CPU: 0 UID: 0 PID: 5326 Comm: kworker/0:5 Not tainted 6.19.0-rc2 #2 PREEMPT(voluntary)
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+Workqueue: events cfg80211_rfkill_block_work
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x116/0x1f0
+ print_report+0xcd/0x630
+ kasan_report+0xe0/0x110
+ cfg80211_shutdown_all_interfaces+0x213/0x220
+ cfg80211_rfkill_block_work+0x1e/0x30
+ process_one_work+0x9cf/0x1b70
+ worker_thread+0x6c8/0xf10
+ kthread+0x3c5/0x780
+ ret_from_fork+0x56d/0x700
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+The problem arises due to the rfkill_block work is not cancelled when wiphy
+is being unregistered. In order to fix the issue cancel the corresponding
+work in wiphy_unregister().
+
+Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
+
+Fixes: 1f87f7d3a3b4 ("cfg80211: add rfkill support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniil Dulov <d.dulov@aladdin.ru>
+Link: https://patch.msgid.link/20260211082024.1967588-1-d.dulov@aladdin.ru
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/wireless/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1104,6 +1104,7 @@ void wiphy_unregister(struct wiphy *wiph
+ /* this has nothing to do now but make sure it's gone */
+ cancel_work_sync(&rdev->wiphy_work);
+
++ cancel_work_sync(&rdev->rfkill_block);
+ cancel_work_sync(&rdev->conn_work);
+ flush_work(&rdev->event_work);
+ cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
--- /dev/null
+From stable+bounces-223619-greg=kroah.com@vger.kernel.org Mon Mar 9 12:42:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2026 07:42:23 -0400
+Subject: wifi: cfg80211: move scan done work to wiphy work
+To: stable@vger.kernel.org
+Cc: Johannes Berg <johannes.berg@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260309114224.831897-1-sashal@kernel.org>
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit fe0af9fe54d0ff53aa49eef390c8962355b274e2 ]
+
+Move the scan done work to the new wiphy work to
+simplify the code a bit.
+
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Stable-dep-of: 767d23ade706 ("wifi: cfg80211: cancel rfkill_block work in wiphy_unregister()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/wireless/core.c | 3 +--
+ net/wireless/core.h | 4 ++--
+ net/wireless/scan.c | 14 ++++----------
+ 3 files changed, 7 insertions(+), 14 deletions(-)
+
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -525,7 +525,7 @@ use_default_name:
+ spin_lock_init(&rdev->bss_lock);
+ INIT_LIST_HEAD(&rdev->bss_list);
+ INIT_LIST_HEAD(&rdev->sched_scan_req_list);
+- INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
++ wiphy_work_init(&rdev->scan_done_wk, __cfg80211_scan_done);
+ INIT_DELAYED_WORK(&rdev->dfs_update_channels_wk,
+ cfg80211_dfs_channels_update_work);
+ #ifdef CONFIG_CFG80211_WEXT
+@@ -1104,7 +1104,6 @@ void wiphy_unregister(struct wiphy *wiph
+ /* this has nothing to do now but make sure it's gone */
+ cancel_work_sync(&rdev->wiphy_work);
+
+- flush_work(&rdev->scan_done_wk);
+ cancel_work_sync(&rdev->conn_work);
+ flush_work(&rdev->event_work);
+ cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -75,7 +75,7 @@ struct cfg80211_registered_device {
+ struct sk_buff *scan_msg;
+ struct list_head sched_scan_req_list;
+ time64_t suspend_at;
+- struct work_struct scan_done_wk;
++ struct wiphy_work scan_done_wk;
+
+ struct genl_info *cur_cmd_info;
+
+@@ -445,7 +445,7 @@ bool cfg80211_valid_key_idx(struct cfg80
+ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
+ struct key_params *params, int key_idx,
+ bool pairwise, const u8 *mac_addr);
+-void __cfg80211_scan_done(struct work_struct *wk);
++void __cfg80211_scan_done(struct wiphy *wiphy, struct wiphy_work *wk);
+ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
+ bool send_message);
+ void cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -1079,16 +1079,9 @@ void ___cfg80211_scan_done(struct cfg802
+ nl80211_send_scan_msg(rdev, msg);
+ }
+
+-void __cfg80211_scan_done(struct work_struct *wk)
++void __cfg80211_scan_done(struct wiphy *wiphy, struct wiphy_work *wk)
+ {
+- struct cfg80211_registered_device *rdev;
+-
+- rdev = container_of(wk, struct cfg80211_registered_device,
+- scan_done_wk);
+-
+- wiphy_lock(&rdev->wiphy);
+- ___cfg80211_scan_done(rdev, true);
+- wiphy_unlock(&rdev->wiphy);
++ ___cfg80211_scan_done(wiphy_to_rdev(wiphy), true);
+ }
+
+ void cfg80211_scan_done(struct cfg80211_scan_request *request,
+@@ -1114,7 +1107,8 @@ void cfg80211_scan_done(struct cfg80211_
+ }
+
+ request->notified = true;
+- queue_work(cfg80211_wq, &wiphy_to_rdev(request->wiphy)->scan_done_wk);
++ wiphy_work_queue(request->wiphy,
++ &wiphy_to_rdev(request->wiphy)->scan_done_wk);
+ }
+ EXPORT_SYMBOL(cfg80211_scan_done);
+
--- /dev/null
+From stable+bounces-223611-greg=kroah.com@vger.kernel.org Mon Mar 9 12:26:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Mar 2026 07:21:38 -0400
+Subject: wifi: libertas: fix use-after-free in lbs_free_adapter()
+To: stable@vger.kernel.org
+Cc: Daniel Hodges <git@danielhodges.dev>, Johannes Berg <johannes.berg@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260309112138.816064-1-sashal@kernel.org>
+
+From: Daniel Hodges <git@danielhodges.dev>
+
+[ Upstream commit 03cc8f90d0537fcd4985c3319b4fafbf2e3fb1f0 ]
+
+The lbs_free_adapter() function uses timer_delete() (non-synchronous)
+for both command_timer and tx_lockup_timer before the structure is
+freed. This is incorrect because timer_delete() does not wait for
+any running timer callback to complete.
+
+If a timer callback is executing when lbs_free_adapter() is called,
+the callback will access freed memory since lbs_cfg_free() frees the
+containing structure immediately after lbs_free_adapter() returns.
+
+Both timer callbacks (lbs_cmd_timeout_handler and lbs_tx_lockup_handler)
+access priv->driver_lock, priv->cur_cmd, priv->dev, and other fields,
+which would all be use-after-free violations.
+
+Use timer_delete_sync() instead to ensure any running timer callback
+has completed before returning.
+
+This bug was introduced in commit 8f641d93c38a ("libertas: detect TX
+lockups and reset hardware") where del_timer() was used instead of
+del_timer_sync() in the cleanup path. The command_timer has had the
+same issue since the driver was first written.
+
+Fixes: 8f641d93c38a ("libertas: detect TX lockups and reset hardware")
+Fixes: 954ee164f4f4 ("[PATCH] libertas: reorganize and simplify init sequence")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Hodges <git@danielhodges.dev>
+Link: https://patch.msgid.link/20260206195356.15647-1-git@danielhodges.dev
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[ del_timer() => timer_delete_sync() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/marvell/libertas/main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/marvell/libertas/main.c
++++ b/drivers/net/wireless/marvell/libertas/main.c
+@@ -882,8 +882,8 @@ static void lbs_free_adapter(struct lbs_
+ {
+ lbs_free_cmd_buffer(priv);
+ kfifo_free(&priv->event_fifo);
+- del_timer(&priv->command_timer);
+- del_timer(&priv->tx_lockup_timer);
++ timer_delete_sync(&priv->command_timer);
++ timer_delete_sync(&priv->tx_lockup_timer);
+ del_timer(&priv->auto_deepsleep_timer);
+ }
+