From: Sasha Levin Date: Mon, 14 Jul 2025 17:18:53 +0000 (-0400) Subject: Fixes for 5.15 X-Git-Tag: v5.4.296~33 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=afb372608268d366867071eb76f378748e289a53;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/atm-idt77252-add-missing-dma_map_error.patch b/queue-5.15/atm-idt77252-add-missing-dma_map_error.patch new file mode 100644 index 0000000000..2f2569364f --- /dev/null +++ b/queue-5.15/atm-idt77252-add-missing-dma_map_error.patch @@ -0,0 +1,53 @@ +From 1e2a7c11629bf312395bd8f8dae6a3ba236d3154 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Jun 2025 08:41:47 +0200 +Subject: atm: idt77252: Add missing `dma_map_error()` + +From: Thomas Fourier + +[ Upstream commit c4890963350dcf4e9a909bae23665921fba4ad27 ] + +The DMA map functions can fail and should be tested for errors. + +Signed-off-by: Thomas Fourier +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250624064148.12815-3-fourier.thomas@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/atm/idt77252.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c +index 7810f974b2ca9..d9ee20f0048fe 100644 +--- a/drivers/atm/idt77252.c ++++ b/drivers/atm/idt77252.c +@@ -852,6 +852,8 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc, + + IDT77252_PRV_PADDR(skb) = dma_map_single(&card->pcidev->dev, skb->data, + skb->len, DMA_TO_DEVICE); ++ if (dma_mapping_error(&card->pcidev->dev, IDT77252_PRV_PADDR(skb))) ++ return -ENOMEM; + + error = -EINVAL; + +@@ -1857,6 +1859,8 @@ add_rx_skb(struct idt77252_dev *card, int queue, + paddr = dma_map_single(&card->pcidev->dev, skb->data, + skb_end_pointer(skb) - skb->data, + DMA_FROM_DEVICE); ++ if (dma_mapping_error(&card->pcidev->dev, paddr)) ++ goto outpoolrm; + IDT77252_PRV_PADDR(skb) = paddr; + + if (push_rx_skb(card, skb, queue)) { +@@ -1871,6 +1875,7 @@ add_rx_skb(struct idt77252_dev *card, int queue, + dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb), + skb_end_pointer(skb) - skb->data, DMA_FROM_DEVICE); + ++outpoolrm: + handle = IDT77252_PRV_POOL(skb); + card->sbpool[POOL_QUEUE(handle)].skb[POOL_INDEX(handle)] = NULL; + +-- +2.39.5 + diff --git a/queue-5.15/bnxt_en-fix-dcb-ets-validation.patch b/queue-5.15/bnxt_en-fix-dcb-ets-validation.patch new file mode 100644 index 0000000000..43dd0be516 --- /dev/null +++ b/queue-5.15/bnxt_en-fix-dcb-ets-validation.patch @@ -0,0 +1,49 @@ +From b840c9cf14249b4fd8a564cb4395ab3ee81eefdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Jul 2025 14:39:36 -0700 +Subject: bnxt_en: Fix DCB ETS validation + +From: Shravya KN + +[ Upstream commit b74c2a2e9cc471e847abd87e50a2354c07e02040 ] + +In bnxt_ets_validate(), the code incorrectly loops over all possible +traffic classes to check and add the ETS settings. Fix it to loop +over the configured traffic classes only. + +The unconfigured traffic classes will default to TSA_ETS with 0 +bandwidth. Looping over these unconfigured traffic classes may +cause the validation to fail and trigger this error message: + +"rejecting ETS config starving a TC\n" + +The .ieee_setets() will then fail. + +Fixes: 7df4ae9fe855 ("bnxt_en: Implement DCBNL to support host-based DCBX.") +Reviewed-by: Sreekanth Reddy +Signed-off-by: Shravya KN +Signed-off-by: Michael Chan +Link: https://patch.msgid.link/20250710213938.1959625-2-michael.chan@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c +index 228a5db7e1434..596513ffdfd9c 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c +@@ -479,7 +479,9 @@ static int bnxt_ets_validate(struct bnxt *bp, struct ieee_ets *ets, u8 *tc) + + if ((ets->tc_tx_bw[i] || ets->tc_tsa[i]) && i > bp->max_tc) + return -EINVAL; ++ } + ++ for (i = 0; i < max_tc; i++) { + switch (ets->tc_tsa[i]) { + case IEEE_8021QAZ_TSA_STRICT: + break; +-- +2.39.5 + diff --git a/queue-5.15/bnxt_en-set-dma-unmap-len-correctly-for-xdp_redirect.patch b/queue-5.15/bnxt_en-set-dma-unmap-len-correctly-for-xdp_redirect.patch new file mode 100644 index 0000000000..fcac2b4146 --- /dev/null +++ b/queue-5.15/bnxt_en-set-dma-unmap-len-correctly-for-xdp_redirect.patch @@ -0,0 +1,72 @@ +From 9452b3ce2aef01dd96f46f16bb5843b242cc94a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Jul 2025 14:39:38 -0700 +Subject: bnxt_en: Set DMA unmap len correctly for XDP_REDIRECT + +From: Somnath Kotur + +[ Upstream commit 3cdf199d4755d477972ee87110b2aebc88b3cfad ] + +When transmitting an XDP_REDIRECT packet, call dma_unmap_len_set() +with the proper length instead of 0. This bug triggers this warning +on a system with IOMMU enabled: + +WARNING: CPU: 36 PID: 0 at drivers/iommu/dma-iommu.c:842 __iommu_dma_unmap+0x159/0x170 +RIP: 0010:__iommu_dma_unmap+0x159/0x170 +Code: a8 00 00 00 00 48 c7 45 b0 00 00 00 00 48 c7 45 c8 00 00 00 00 48 c7 45 a0 ff ff ff ff 4c 89 45 +b8 4c 89 45 c0 e9 77 ff ff ff <0f> 0b e9 60 ff ff ff e8 8b bf 6a 00 66 66 2e 0f 1f 84 00 00 00 00 +RSP: 0018:ff22d31181150c88 EFLAGS: 00010206 +RAX: 0000000000002000 RBX: 00000000e13a0000 RCX: 0000000000000000 +RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +RBP: ff22d31181150cf0 R08: ff22d31181150ca8 R09: 0000000000000000 +R10: 0000000000000000 R11: ff22d311d36c9d80 R12: 0000000000001000 +R13: ff13544d10645010 R14: ff22d31181150c90 R15: ff13544d0b2bac00 +FS: 0000000000000000(0000) GS:ff13550908a00000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00005be909dacff8 CR3: 0008000173408003 CR4: 0000000000f71ef0 +PKRU: 55555554 +Call Trace: + +? show_regs+0x6d/0x80 +? __warn+0x89/0x160 +? __iommu_dma_unmap+0x159/0x170 +? report_bug+0x17e/0x1b0 +? handle_bug+0x46/0x90 +? exc_invalid_op+0x18/0x80 +? asm_exc_invalid_op+0x1b/0x20 +? __iommu_dma_unmap+0x159/0x170 +? __iommu_dma_unmap+0xb3/0x170 +iommu_dma_unmap_page+0x4f/0x100 +dma_unmap_page_attrs+0x52/0x220 +? srso_alias_return_thunk+0x5/0xfbef5 +? xdp_return_frame+0x2e/0xd0 +bnxt_tx_int_xdp+0xdf/0x440 [bnxt_en] +__bnxt_poll_work_done+0x81/0x1e0 [bnxt_en] +bnxt_poll+0xd3/0x1e0 [bnxt_en] + +Fixes: f18c2b77b2e4 ("bnxt_en: optimized XDP_REDIRECT support") +Signed-off-by: Somnath Kotur +Signed-off-by: Michael Chan +Link: https://patch.msgid.link/20250710213938.1959625-4-michael.chan@broadcom.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +index 148b58f3468b3..8a5009e66a134 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +@@ -67,7 +67,7 @@ static void __bnxt_xmit_xdp_redirect(struct bnxt *bp, + tx_buf->action = XDP_REDIRECT; + tx_buf->xdpf = xdpf; + dma_unmap_addr_set(tx_buf, mapping, mapping); +- dma_unmap_len_set(tx_buf, len, 0); ++ dma_unmap_len_set(tx_buf, len, len); + } + + void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts) +-- +2.39.5 + diff --git a/queue-5.15/btrfs-fix-inode-lookup-error-handling-during-log-rep.patch b/queue-5.15/btrfs-fix-inode-lookup-error-handling-during-log-rep.patch new file mode 100644 index 0000000000..861e5f5842 --- /dev/null +++ b/queue-5.15/btrfs-fix-inode-lookup-error-handling-during-log-rep.patch @@ -0,0 +1,311 @@ +From 6adb7d09869b148ebee4563459ec4a0750bd11b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Jun 2025 15:58:31 +0100 +Subject: btrfs: fix inode lookup error handling during log replay + +From: Filipe Manana + +[ Upstream commit 5f61b961599acbd2bed028d3089105a1f7d224b8 ] + +When replaying log trees we use read_one_inode() to get an inode, which is +just a wrapper around btrfs_iget_logging(), which in turn is a wrapper for +btrfs_iget(). But read_one_inode() always returns NULL for any error +that btrfs_iget_logging() / btrfs_iget() may return and this is a problem +because: + +1) In many callers of read_one_inode() we convert the NULL into -EIO, + which is not accurate since btrfs_iget() may return -ENOMEM and -ENOENT + for example, besides -EIO and other errors. So during log replay we + may end up reporting a false -EIO, which is confusing since we may + not have had any IO error at all; + +2) When replaying directory deletes, at replay_dir_deletes(), we assume + the NULL returned from read_one_inode() means that the inode doesn't + exist and then proceed as if no error had happened. This is wrong + because unless btrfs_iget() returned ERR_PTR(-ENOENT), we had an + actual error and the target inode may exist in the target subvolume + root - this may later result in the log replay code failing at a + later stage (if we are "lucky") or succeed but leaving some + inconsistency in the filesystem. + +So fix this by not ignoring errors from btrfs_iget_logging() and as +a consequence remove the read_one_inode() wrapper and just use +btrfs_iget_logging() directly. Also since btrfs_iget_logging() is +supposed to be called only against subvolume roots, just like +read_one_inode() which had a comment about it, add an assertion to +btrfs_iget_logging() to check that the target root corresponds to a +subvolume root. + +Fixes: 5d4f98a28c7d ("Btrfs: Mixed back reference (FORWARD ROLLING FORMAT CHANGE)") +Reviewed-by: Johannes Thumshirn +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/tree-log.c | 139 +++++++++++++++++++++++++------------------- + 1 file changed, 78 insertions(+), 61 deletions(-) + +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 7049a19e07baf..0ee7ae8f21398 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -584,18 +584,25 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, + return 0; + } + +-/* +- * simple helper to read an inode off the disk from a given root +- * This can only be called for subvolume roots and not for the log +- */ +-static noinline struct inode *read_one_inode(struct btrfs_root *root, +- u64 objectid) ++static struct inode *btrfs_iget_logging(u64 objectid, struct btrfs_root *root) + { ++ unsigned int nofs_flag; + struct inode *inode; + ++ /* Only meant to be called for subvolume roots and not for log roots. */ ++ ASSERT(is_fstree(btrfs_root_id(root))); ++ ++ /* ++ * We're holding a transaction handle whether we are logging or ++ * replaying a log tree, so we must make sure NOFS semantics apply ++ * because btrfs_alloc_inode() may be triggered and it uses GFP_KERNEL ++ * to allocate an inode, which can recurse back into the filesystem and ++ * attempt a transaction commit, resulting in a deadlock. ++ */ ++ nofs_flag = memalloc_nofs_save(); + inode = btrfs_iget(root->fs_info->sb, objectid, root); +- if (IS_ERR(inode)) +- inode = NULL; ++ memalloc_nofs_restore(nofs_flag); ++ + return inode; + } + +@@ -652,9 +659,9 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, + goto out; + } + +- inode = read_one_inode(root, key->objectid); +- if (!inode) { +- ret = -EIO; ++ inode = btrfs_iget_logging(key->objectid, root); ++ if (IS_ERR(inode)) { ++ ret = PTR_ERR(inode); + goto out; + } + +@@ -936,9 +943,9 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, + read_extent_buffer(leaf, name, (unsigned long)(di + 1), name_len); + btrfs_release_path(path); + +- inode = read_one_inode(root, location.objectid); +- if (!inode) { +- ret = -EIO; ++ inode = btrfs_iget_logging(location.objectid, root); ++ if (IS_ERR(inode)) { ++ ret = PTR_ERR(inode); + goto out; + } + +@@ -1173,10 +1180,12 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, + kfree(victim_name); + return ret; + } else if (!ret) { +- ret = -ENOENT; +- victim_parent = read_one_inode(root, +- parent_objectid); +- if (victim_parent) { ++ victim_parent = btrfs_iget_logging(parent_objectid, root); ++ if (IS_ERR(victim_parent)) { ++ ret = PTR_ERR(victim_parent); ++ kfree(victim_name); ++ return ret; ++ } else { + inc_nlink(&inode->vfs_inode); + btrfs_release_path(path); + +@@ -1333,9 +1342,9 @@ static int unlink_old_inode_refs(struct btrfs_trans_handle *trans, + struct inode *dir; + + btrfs_release_path(path); +- dir = read_one_inode(root, parent_id); +- if (!dir) { +- ret = -ENOENT; ++ dir = btrfs_iget_logging(parent_id, root); ++ if (IS_ERR(dir)) { ++ ret = PTR_ERR(dir); + kfree(name); + goto out; + } +@@ -1432,9 +1441,9 @@ static int add_link(struct btrfs_trans_handle *trans, struct btrfs_root *root, + */ + btrfs_dir_item_key_to_cpu(path->nodes[0], dir_item, &key); + btrfs_release_path(path); +- other_inode = read_one_inode(root, key.objectid); +- if (!other_inode) { +- ret = -ENOENT; ++ other_inode = btrfs_iget_logging(key.objectid, root); ++ if (IS_ERR(other_inode)) { ++ ret = PTR_ERR(other_inode); + goto out; + } + ret = unlink_inode_for_log_replay(trans, BTRFS_I(dir), BTRFS_I(other_inode), +@@ -1506,15 +1515,17 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, + * copy the back ref in. The link count fixup code will take + * care of the rest + */ +- dir = read_one_inode(root, parent_objectid); +- if (!dir) { +- ret = -ENOENT; ++ dir = btrfs_iget_logging(parent_objectid, root); ++ if (IS_ERR(dir)) { ++ ret = PTR_ERR(dir); ++ dir = NULL; + goto out; + } + +- inode = read_one_inode(root, inode_objectid); +- if (!inode) { +- ret = -EIO; ++ inode = btrfs_iget_logging(inode_objectid, root); ++ if (IS_ERR(inode)) { ++ ret = PTR_ERR(inode); ++ inode = NULL; + goto out; + } + +@@ -1526,11 +1537,13 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, + * parent object can change from one array + * item to another. + */ +- if (!dir) +- dir = read_one_inode(root, parent_objectid); + if (!dir) { +- ret = -ENOENT; +- goto out; ++ dir = btrfs_iget_logging(parent_objectid, root); ++ if (IS_ERR(dir)) { ++ ret = PTR_ERR(dir); ++ dir = NULL; ++ goto out; ++ } + } + } else { + ret = ref_get_fields(eb, ref_ptr, &namelen, &name, +@@ -1834,9 +1847,9 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, + break; + + btrfs_release_path(path); +- inode = read_one_inode(root, key.offset); +- if (!inode) { +- ret = -EIO; ++ inode = btrfs_iget_logging(key.offset, root); ++ if (IS_ERR(inode)) { ++ ret = PTR_ERR(inode); + break; + } + +@@ -1871,9 +1884,9 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans, + int ret = 0; + struct inode *inode; + +- inode = read_one_inode(root, objectid); +- if (!inode) +- return -EIO; ++ inode = btrfs_iget_logging(objectid, root); ++ if (IS_ERR(inode)) ++ return PTR_ERR(inode); + + key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID; + key.type = BTRFS_ORPHAN_ITEM_KEY; +@@ -1911,14 +1924,14 @@ static noinline int insert_one_name(struct btrfs_trans_handle *trans, + struct inode *dir; + int ret; + +- inode = read_one_inode(root, location->objectid); +- if (!inode) +- return -ENOENT; ++ inode = btrfs_iget_logging(location->objectid, root); ++ if (IS_ERR(inode)) ++ return PTR_ERR(inode); + +- dir = read_one_inode(root, dirid); +- if (!dir) { ++ dir = btrfs_iget_logging(dirid, root); ++ if (IS_ERR(dir)) { + iput(inode); +- return -EIO; ++ return PTR_ERR(dir); + } + + ret = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), name, +@@ -1966,9 +1979,9 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, + bool update_size = (key->type == BTRFS_DIR_INDEX_KEY); + bool name_added = false; + +- dir = read_one_inode(root, key->objectid); +- if (!dir) +- return -EIO; ++ dir = btrfs_iget_logging(key->objectid, root); ++ if (IS_ERR(dir)) ++ return PTR_ERR(dir); + + name_len = btrfs_dir_name_len(eb, di); + name = kmalloc(name_len, GFP_NOFS); +@@ -2318,9 +2331,10 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans, + btrfs_dir_item_key_to_cpu(eb, di, &location); + btrfs_release_path(path); + btrfs_release_path(log_path); +- inode = read_one_inode(root, location.objectid); +- if (!inode) { +- ret = -EIO; ++ inode = btrfs_iget_logging(location.objectid, root); ++ if (IS_ERR(inode)) { ++ ret = PTR_ERR(inode); ++ inode = NULL; + goto out; + } + +@@ -2472,14 +2486,17 @@ static noinline int replay_dir_deletes(struct btrfs_trans_handle *trans, + if (!log_path) + return -ENOMEM; + +- dir = read_one_inode(root, dirid); +- /* it isn't an error if the inode isn't there, that can happen +- * because we replay the deletes before we copy in the inode item +- * from the log ++ dir = btrfs_iget_logging(dirid, root); ++ /* ++ * It isn't an error if the inode isn't there, that can happen because ++ * we replay the deletes before we copy in the inode item from the log. + */ +- if (!dir) { ++ if (IS_ERR(dir)) { + btrfs_free_path(log_path); +- return 0; ++ ret = PTR_ERR(dir); ++ if (ret == -ENOENT) ++ ret = 0; ++ return ret; + } + + range_start = 0; +@@ -2634,9 +2651,9 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, + struct inode *inode; + u64 from; + +- inode = read_one_inode(root, key.objectid); +- if (!inode) { +- ret = -EIO; ++ inode = btrfs_iget_logging(key.objectid, root); ++ if (IS_ERR(inode)) { ++ ret = PTR_ERR(inode); + break; + } + from = ALIGN(i_size_read(inode), +-- +2.39.5 + diff --git a/queue-5.15/can-m_can-m_can_handle_lost_msg-downgrade-msg-lost-i.patch b/queue-5.15/can-m_can-m_can_handle_lost_msg-downgrade-msg-lost-i.patch new file mode 100644 index 0000000000..f50568be41 --- /dev/null +++ b/queue-5.15/can-m_can-m_can_handle_lost_msg-downgrade-msg-lost-i.patch @@ -0,0 +1,40 @@ +From 9e40dcc60bd4edd1c79a350ba8900efcb5456c6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Jul 2025 12:12:02 +0200 +Subject: can: m_can: m_can_handle_lost_msg(): downgrade msg lost in rx message + to debug level + +From: Sean Nyekjaer + +[ Upstream commit 58805e9cbc6f6a28f35d90e740956e983a0e036e ] + +Downgrade the "msg lost in rx" message to debug level, to prevent +flooding the kernel log with error messages. + +Fixes: e0d1f4816f2a ("can: m_can: add Bosch M_CAN controller support") +Reviewed-by: Vincent Mailhol +Signed-off-by: Sean Nyekjaer +Link: https://patch.msgid.link/20250711-mcan_ratelimit-v3-1-7413e8e21b84@geanix.com +[mkl: enhance commit message] +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + drivers/net/can/m_can/m_can.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c +index e8b35661c5389..17b893eb286e7 100644 +--- a/drivers/net/can/m_can/m_can.c ++++ b/drivers/net/can/m_can/m_can.c +@@ -582,7 +582,7 @@ static int m_can_handle_lost_msg(struct net_device *dev) + struct can_frame *frame; + u32 timestamp = 0; + +- netdev_err(dev, "msg lost in rxf0\n"); ++ netdev_dbg(dev, "msg lost in rxf0\n"); + + stats->rx_errors++; + stats->rx_over_errors++; +-- +2.39.5 + diff --git a/queue-5.15/dma-buf-add-dma_resv_for_each_fence_unlocked-v8.patch b/queue-5.15/dma-buf-add-dma_resv_for_each_fence_unlocked-v8.patch new file mode 100644 index 0000000000..1097475e73 --- /dev/null +++ b/queue-5.15/dma-buf-add-dma_resv_for_each_fence_unlocked-v8.patch @@ -0,0 +1,267 @@ +From 0920e166d51a31f630ef4037c02dcdc05ed71d19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Jun 2021 15:10:03 +0200 +Subject: dma-buf: add dma_resv_for_each_fence_unlocked v8 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christian König + +[ Upstream commit c921ff373b469ad7907cde219fa700909f59cac4 ] + +Abstract the complexity of iterating over all the fences +in a dma_resv object. + +The new loop handles the whole RCU and retry dance and +returns only fences where we can be sure we grabbed the +right one. + +v2: fix accessing the shared fences while they might be freed, + improve kerneldoc, rename _cursor to _iter, add + dma_resv_iter_is_exclusive, add dma_resv_iter_begin/end + +v3: restructor the code, move rcu_read_lock()/unlock() into the + iterator, add dma_resv_iter_is_restarted() + +v4: fix NULL deref when no explicit fence exists, drop superflous + rcu_read_lock()/unlock() calls. + +v5: fix typos in the documentation + +v6: fix coding error when excl fence is NULL + +v7: one more logic fix + +v8: fix index check in dma_resv_iter_is_exclusive() + +Signed-off-by: Christian König +Reviewed-by: Tvrtko Ursulin (v7) +Link: https://patchwork.freedesktop.org/patch/msgid/20211005113742.1101-2-christian.koenig@amd.com +Stable-dep-of: 2b95a7db6e0f ("dma-buf: fix timeout handling in dma_resv_wait_timeout v2") +Signed-off-by: Sasha Levin +--- + drivers/dma-buf/dma-resv.c | 100 +++++++++++++++++++++++++++++++++++++ + include/linux/dma-resv.h | 95 +++++++++++++++++++++++++++++++++++ + 2 files changed, 195 insertions(+) + +diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c +index e744fd87c63c8..c747b19c3be16 100644 +--- a/drivers/dma-buf/dma-resv.c ++++ b/drivers/dma-buf/dma-resv.c +@@ -313,6 +313,106 @@ void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence) + } + EXPORT_SYMBOL(dma_resv_add_excl_fence); + ++/** ++ * dma_resv_iter_restart_unlocked - restart the unlocked iterator ++ * @cursor: The dma_resv_iter object to restart ++ * ++ * Restart the unlocked iteration by initializing the cursor object. ++ */ ++static void dma_resv_iter_restart_unlocked(struct dma_resv_iter *cursor) ++{ ++ cursor->seq = read_seqcount_begin(&cursor->obj->seq); ++ cursor->index = -1; ++ if (cursor->all_fences) ++ cursor->fences = dma_resv_shared_list(cursor->obj); ++ else ++ cursor->fences = NULL; ++ cursor->is_restarted = true; ++} ++ ++/** ++ * dma_resv_iter_walk_unlocked - walk over fences in a dma_resv obj ++ * @cursor: cursor to record the current position ++ * ++ * Return all the fences in the dma_resv object which are not yet signaled. ++ * The returned fence has an extra local reference so will stay alive. ++ * If a concurrent modify is detected the whole iteration is started over again. ++ */ ++static void dma_resv_iter_walk_unlocked(struct dma_resv_iter *cursor) ++{ ++ struct dma_resv *obj = cursor->obj; ++ ++ do { ++ /* Drop the reference from the previous round */ ++ dma_fence_put(cursor->fence); ++ ++ if (cursor->index == -1) { ++ cursor->fence = dma_resv_excl_fence(obj); ++ cursor->index++; ++ if (!cursor->fence) ++ continue; ++ ++ } else if (!cursor->fences || ++ cursor->index >= cursor->fences->shared_count) { ++ cursor->fence = NULL; ++ break; ++ ++ } else { ++ struct dma_resv_list *fences = cursor->fences; ++ unsigned int idx = cursor->index++; ++ ++ cursor->fence = rcu_dereference(fences->shared[idx]); ++ } ++ cursor->fence = dma_fence_get_rcu(cursor->fence); ++ if (!cursor->fence || !dma_fence_is_signaled(cursor->fence)) ++ break; ++ } while (true); ++} ++ ++/** ++ * dma_resv_iter_first_unlocked - first fence in an unlocked dma_resv obj. ++ * @cursor: the cursor with the current position ++ * ++ * Returns the first fence from an unlocked dma_resv obj. ++ */ ++struct dma_fence *dma_resv_iter_first_unlocked(struct dma_resv_iter *cursor) ++{ ++ rcu_read_lock(); ++ do { ++ dma_resv_iter_restart_unlocked(cursor); ++ dma_resv_iter_walk_unlocked(cursor); ++ } while (read_seqcount_retry(&cursor->obj->seq, cursor->seq)); ++ rcu_read_unlock(); ++ ++ return cursor->fence; ++} ++EXPORT_SYMBOL(dma_resv_iter_first_unlocked); ++ ++/** ++ * dma_resv_iter_next_unlocked - next fence in an unlocked dma_resv obj. ++ * @cursor: the cursor with the current position ++ * ++ * Returns the next fence from an unlocked dma_resv obj. ++ */ ++struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor) ++{ ++ bool restart; ++ ++ rcu_read_lock(); ++ cursor->is_restarted = false; ++ restart = read_seqcount_retry(&cursor->obj->seq, cursor->seq); ++ do { ++ if (restart) ++ dma_resv_iter_restart_unlocked(cursor); ++ dma_resv_iter_walk_unlocked(cursor); ++ restart = true; ++ } while (read_seqcount_retry(&cursor->obj->seq, cursor->seq)); ++ rcu_read_unlock(); ++ ++ return cursor->fence; ++} ++EXPORT_SYMBOL(dma_resv_iter_next_unlocked); ++ + /** + * dma_resv_copy_fences - Copy all fences from src to dst. + * @dst: the destination reservation object +diff --git a/include/linux/dma-resv.h b/include/linux/dma-resv.h +index e1ca2080a1ff1..ef9f94ce2cc38 100644 +--- a/include/linux/dma-resv.h ++++ b/include/linux/dma-resv.h +@@ -75,6 +75,101 @@ struct dma_resv { + struct dma_resv_list __rcu *fence; + }; + ++/** ++ * struct dma_resv_iter - current position into the dma_resv fences ++ * ++ * Don't touch this directly in the driver, use the accessor function instead. ++ */ ++struct dma_resv_iter { ++ /** @obj: The dma_resv object we iterate over */ ++ struct dma_resv *obj; ++ ++ /** @all_fences: If all fences should be returned */ ++ bool all_fences; ++ ++ /** @fence: the currently handled fence */ ++ struct dma_fence *fence; ++ ++ /** @seq: sequence number to check for modifications */ ++ unsigned int seq; ++ ++ /** @index: index into the shared fences */ ++ unsigned int index; ++ ++ /** @fences: the shared fences */ ++ struct dma_resv_list *fences; ++ ++ /** @is_restarted: true if this is the first returned fence */ ++ bool is_restarted; ++}; ++ ++struct dma_fence *dma_resv_iter_first_unlocked(struct dma_resv_iter *cursor); ++struct dma_fence *dma_resv_iter_next_unlocked(struct dma_resv_iter *cursor); ++ ++/** ++ * dma_resv_iter_begin - initialize a dma_resv_iter object ++ * @cursor: The dma_resv_iter object to initialize ++ * @obj: The dma_resv object which we want to iterate over ++ * @all_fences: If all fences should be returned or just the exclusive one ++ */ ++static inline void dma_resv_iter_begin(struct dma_resv_iter *cursor, ++ struct dma_resv *obj, ++ bool all_fences) ++{ ++ cursor->obj = obj; ++ cursor->all_fences = all_fences; ++ cursor->fence = NULL; ++} ++ ++/** ++ * dma_resv_iter_end - cleanup a dma_resv_iter object ++ * @cursor: the dma_resv_iter object which should be cleaned up ++ * ++ * Make sure that the reference to the fence in the cursor is properly ++ * dropped. ++ */ ++static inline void dma_resv_iter_end(struct dma_resv_iter *cursor) ++{ ++ dma_fence_put(cursor->fence); ++} ++ ++/** ++ * dma_resv_iter_is_exclusive - test if the current fence is the exclusive one ++ * @cursor: the cursor of the current position ++ * ++ * Returns true if the currently returned fence is the exclusive one. ++ */ ++static inline bool dma_resv_iter_is_exclusive(struct dma_resv_iter *cursor) ++{ ++ return cursor->index == 0; ++} ++ ++/** ++ * dma_resv_iter_is_restarted - test if this is the first fence after a restart ++ * @cursor: the cursor with the current position ++ * ++ * Return true if this is the first fence in an iteration after a restart. ++ */ ++static inline bool dma_resv_iter_is_restarted(struct dma_resv_iter *cursor) ++{ ++ return cursor->is_restarted; ++} ++ ++/** ++ * dma_resv_for_each_fence_unlocked - unlocked fence iterator ++ * @cursor: a struct dma_resv_iter pointer ++ * @fence: the current fence ++ * ++ * Iterate over the fences in a struct dma_resv object without holding the ++ * &dma_resv.lock and using RCU instead. The cursor needs to be initialized ++ * with dma_resv_iter_begin() and cleaned up with dma_resv_iter_end(). Inside ++ * the iterator a reference to the dma_fence is held and the RCU lock dropped. ++ * When the dma_resv is modified the iteration starts over again. ++ */ ++#define dma_resv_for_each_fence_unlocked(cursor, fence) \ ++ for (fence = dma_resv_iter_first_unlocked(cursor); \ ++ fence; fence = dma_resv_iter_next_unlocked(cursor)) ++ + #define dma_resv_held(obj) lockdep_is_held(&(obj)->lock.base) + #define dma_resv_assert_held(obj) lockdep_assert_held(&(obj)->lock.base) + +-- +2.39.5 + diff --git a/queue-5.15/dma-buf-fix-timeout-handling-in-dma_resv_wait_timeou.patch b/queue-5.15/dma-buf-fix-timeout-handling-in-dma_resv_wait_timeou.patch new file mode 100644 index 0000000000..41dea0df3e --- /dev/null +++ b/queue-5.15/dma-buf-fix-timeout-handling-in-dma_resv_wait_timeou.patch @@ -0,0 +1,61 @@ +From f08f0b284e86693f4ad0863dfb0d13061824f7bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Jan 2025 10:47:48 +0100 +Subject: dma-buf: fix timeout handling in dma_resv_wait_timeout v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christian König + +[ Upstream commit 2b95a7db6e0f75587bffddbb490399cbb87e4985 ] + +Even the kerneldoc says that with a zero timeout the function should not +wait for anything, but still return 1 to indicate that the fences are +signaled now. + +Unfortunately that isn't what was implemented, instead of only returning +1 we also waited for at least one jiffies. + +Fix that by adjusting the handling to what the function is actually +documented to do. + +v2: improve code readability + +Reported-by: Marek Olšák +Reported-by: Lucas Stach +Signed-off-by: Christian König +Reviewed-by: Lucas Stach +Cc: +Link: https://lore.kernel.org/r/20250129105841.1806-1-christian.koenig@amd.com +Signed-off-by: Sasha Levin +--- + drivers/dma-buf/dma-resv.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c +index 8db368c7d35c3..cafaa54c3d9f1 100644 +--- a/drivers/dma-buf/dma-resv.c ++++ b/drivers/dma-buf/dma-resv.c +@@ -619,11 +619,13 @@ long dma_resv_wait_timeout(struct dma_resv *obj, bool wait_all, bool intr, + dma_resv_iter_begin(&cursor, obj, wait_all); + dma_resv_for_each_fence_unlocked(&cursor, fence) { + +- ret = dma_fence_wait_timeout(fence, intr, ret); +- if (ret <= 0) { +- dma_resv_iter_end(&cursor); +- return ret; +- } ++ ret = dma_fence_wait_timeout(fence, intr, timeout); ++ if (ret <= 0) ++ break; ++ ++ /* Even for zero timeout the return value is 1 */ ++ if (timeout) ++ timeout = ret; + } + dma_resv_iter_end(&cursor); + +-- +2.39.5 + diff --git a/queue-5.15/dma-buf-use-new-iterator-in-dma_resv_wait_timeout.patch b/queue-5.15/dma-buf-use-new-iterator-in-dma_resv_wait_timeout.patch new file mode 100644 index 0000000000..825a966707 --- /dev/null +++ b/queue-5.15/dma-buf-use-new-iterator-in-dma_resv_wait_timeout.patch @@ -0,0 +1,114 @@ +From b1b4a816787124b98f1051fed83cd838a4d2dd2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 15 Jun 2021 15:28:03 +0200 +Subject: dma-buf: use new iterator in dma_resv_wait_timeout +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christian König + +[ Upstream commit ada5c48b11a3df814701daa9cd11305a75a5f1a5 ] + +This makes the function much simpler since the complex +retry logic is now handled elsewhere. + +Signed-off-by: Christian König +Reviewed-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20211005113742.1101-7-christian.koenig@amd.com +Stable-dep-of: 2b95a7db6e0f ("dma-buf: fix timeout handling in dma_resv_wait_timeout v2") +Signed-off-by: Sasha Levin +--- + drivers/dma-buf/dma-resv.c | 69 +++++--------------------------------- + 1 file changed, 8 insertions(+), 61 deletions(-) + +diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c +index c747b19c3be16..8db368c7d35c3 100644 +--- a/drivers/dma-buf/dma-resv.c ++++ b/drivers/dma-buf/dma-resv.c +@@ -613,74 +613,21 @@ long dma_resv_wait_timeout(struct dma_resv *obj, bool wait_all, bool intr, + unsigned long timeout) + { + long ret = timeout ? timeout : 1; +- unsigned int seq, shared_count; ++ struct dma_resv_iter cursor; + struct dma_fence *fence; +- int i; + +-retry: +- shared_count = 0; +- seq = read_seqcount_begin(&obj->seq); +- rcu_read_lock(); +- i = -1; +- +- fence = dma_resv_excl_fence(obj); +- if (fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { +- if (!dma_fence_get_rcu(fence)) +- goto unlock_retry; +- +- if (dma_fence_is_signaled(fence)) { +- dma_fence_put(fence); +- fence = NULL; +- } +- +- } else { +- fence = NULL; +- } +- +- if (wait_all) { +- struct dma_resv_list *fobj = dma_resv_shared_list(obj); +- +- if (fobj) +- shared_count = fobj->shared_count; +- +- for (i = 0; !fence && i < shared_count; ++i) { +- struct dma_fence *lfence; +- +- lfence = rcu_dereference(fobj->shared[i]); +- if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, +- &lfence->flags)) +- continue; +- +- if (!dma_fence_get_rcu(lfence)) +- goto unlock_retry; +- +- if (dma_fence_is_signaled(lfence)) { +- dma_fence_put(lfence); +- continue; +- } ++ dma_resv_iter_begin(&cursor, obj, wait_all); ++ dma_resv_for_each_fence_unlocked(&cursor, fence) { + +- fence = lfence; +- break; ++ ret = dma_fence_wait_timeout(fence, intr, ret); ++ if (ret <= 0) { ++ dma_resv_iter_end(&cursor); ++ return ret; + } + } ++ dma_resv_iter_end(&cursor); + +- rcu_read_unlock(); +- if (fence) { +- if (read_seqcount_retry(&obj->seq, seq)) { +- dma_fence_put(fence); +- goto retry; +- } +- +- ret = dma_fence_wait_timeout(fence, intr, ret); +- dma_fence_put(fence); +- if (ret > 0 && wait_all && (i + 1 < shared_count)) +- goto retry; +- } + return ret; +- +-unlock_retry: +- rcu_read_unlock(); +- goto retry; + } + EXPORT_SYMBOL_GPL(dma_resv_wait_timeout); + +-- +2.39.5 + diff --git a/queue-5.15/hid-add-ignore-quirk-for-smartlinktechnology.patch b/queue-5.15/hid-add-ignore-quirk-for-smartlinktechnology.patch new file mode 100644 index 0000000000..5b2ab58bdd --- /dev/null +++ b/queue-5.15/hid-add-ignore-quirk-for-smartlinktechnology.patch @@ -0,0 +1,65 @@ +From c8cc326c315f491e8c6d2fc6bce2557e6cdf5c00 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Jun 2025 15:29:59 +0800 +Subject: HID: Add IGNORE quirk for SMARTLINKTECHNOLOGY + +From: Zhang Heng + +[ Upstream commit 1a8953f4f7746c6a515989774fe03047c522c613 ] + +MARTLINKTECHNOLOGY is a microphone device, when the HID interface in an +audio device is requested to get specific report id, the following error +may occur. + +[ 562.939373] usb 1-1.4.1.2: new full-speed USB device number 21 using xhci_hcd +[ 563.104908] usb 1-1.4.1.2: New USB device found, idVendor=4c4a, idProduct=4155, bcdDevice= 1.00 +[ 563.104910] usb 1-1.4.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[ 563.104911] usb 1-1.4.1.2: Product: USB Composite Device +[ 563.104912] usb 1-1.4.1.2: Manufacturer: SmartlinkTechnology +[ 563.104913] usb 1-1.4.1.2: SerialNumber: 20201111000001 +[ 563.229499] input: SmartlinkTechnology USB Composite Device as /devices/pci0000:00/0000:00:07.1/0000:04:00.3/usb1/1-1/1-1.4/1-1.4.1/1-1.4.1.2/1-1.4.1.2:1.2/0003:4C4A:4155.000F/input/input35 +[ 563.291505] hid-generic 0003:4C4A:4155.000F: input,hidraw2: USB HID v2.01 Keyboard [SmartlinkTechnology USB Composite Device] on usb-0000:04:00.3-1.4.1.2/input2 +[ 563.291557] usbhid 1-1.4.1.2:1.3: couldn't find an input interrupt endpoint +[ 568.506654] usb 1-1.4.1.2: 1:1: usb_set_interface failed (-110) +[ 573.626656] usb 1-1.4.1.2: 1:1: usb_set_interface failed (-110) +[ 578.746657] usb 1-1.4.1.2: 1:1: usb_set_interface failed (-110) +[ 583.866655] usb 1-1.4.1.2: 1:1: usb_set_interface failed (-110) +[ 588.986657] usb 1-1.4.1.2: 1:1: usb_set_interface failed (-110) + +Ignore HID interface. The device is working properly. + +Signed-off-by: Zhang Heng +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-ids.h | 3 +++ + drivers/hid/hid-quirks.c | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 17d00cb1e9be6..6b3c380584402 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -1401,4 +1401,7 @@ + #define USB_VENDOR_ID_SIGNOTEC 0x2133 + #define USB_DEVICE_ID_SIGNOTEC_VIEWSONIC_PD1011 0x0018 + ++#define USB_VENDOR_ID_SMARTLINKTECHNOLOGY 0x4c4a ++#define USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155 0x4155 ++ + #endif +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index 126cadb117fef..f188a79330c68 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -874,6 +874,7 @@ static const struct hid_device_id hid_ignore_list[] = { + #endif + { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, + { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_HP_5MP_CAMERA_5473) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SMARTLINKTECHNOLOGY, USB_DEVICE_ID_SMARTLINKTECHNOLOGY_4155) }, + { } + }; + +-- +2.39.5 + diff --git a/queue-5.15/hid-lenovo-add-support-for-thinkpad-x1-tablet-thin-k.patch b/queue-5.15/hid-lenovo-add-support-for-thinkpad-x1-tablet-thin-k.patch new file mode 100644 index 0000000000..6e61df63ca --- /dev/null +++ b/queue-5.15/hid-lenovo-add-support-for-thinkpad-x1-tablet-thin-k.patch @@ -0,0 +1,120 @@ +From 2f3359877c9c2b036cfa4417454d49c6d39ff074 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Jun 2025 13:34:38 +0900 +Subject: HID: lenovo: Add support for ThinkPad X1 Tablet Thin Keyboard Gen2 + +From: Akira Inoue + +[ Upstream commit a8905238c3bbe13db90065ed74682418f23830c3 ] + +Add "Thinkpad X1 Tablet Gen 2 Keyboard" PID to hid-lenovo driver to fix trackpoint not working issue. + +Signed-off-by: Akira Inoue +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-lenovo.c | 8 ++++++++ + drivers/hid/hid-multitouch.c | 8 +++++++- + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 08494eb652091..17d00cb1e9be6 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -764,6 +764,7 @@ + #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 + #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 + #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 ++#define USB_DEVICE_ID_LENOVO_X1_TAB2 0x60a4 + #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 + #define USB_DEVICE_ID_LENOVO_X12_TAB 0x60fe + #define USB_DEVICE_ID_LENOVO_X12_TAB2 0x61ae +diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c +index 9536f468b42c5..d74f0ddb45fdb 100644 +--- a/drivers/hid/hid-lenovo.c ++++ b/drivers/hid/hid-lenovo.c +@@ -343,6 +343,7 @@ static int lenovo_input_mapping(struct hid_device *hdev, + return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, + usage, bit, max); + case USB_DEVICE_ID_LENOVO_X1_TAB: ++ case USB_DEVICE_ID_LENOVO_X1_TAB2: + case USB_DEVICE_ID_LENOVO_X1_TAB3: + return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max); + default: +@@ -432,6 +433,7 @@ static ssize_t attr_fn_lock_store(struct device *dev, + break; + case USB_DEVICE_ID_LENOVO_TP10UBKBD: + case USB_DEVICE_ID_LENOVO_X1_TAB: ++ case USB_DEVICE_ID_LENOVO_X1_TAB2: + case USB_DEVICE_ID_LENOVO_X1_TAB3: + ret = lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value); + if (ret) +@@ -616,6 +618,7 @@ static int lenovo_event(struct hid_device *hdev, struct hid_field *field, + return lenovo_event_cptkbd(hdev, field, usage, value); + case USB_DEVICE_ID_LENOVO_TP10UBKBD: + case USB_DEVICE_ID_LENOVO_X1_TAB: ++ case USB_DEVICE_ID_LENOVO_X1_TAB2: + case USB_DEVICE_ID_LENOVO_X1_TAB3: + return lenovo_event_tp10ubkbd(hdev, field, usage, value); + default: +@@ -899,6 +902,7 @@ static int lenovo_led_brightness_set(struct led_classdev *led_cdev, + break; + case USB_DEVICE_ID_LENOVO_TP10UBKBD: + case USB_DEVICE_ID_LENOVO_X1_TAB: ++ case USB_DEVICE_ID_LENOVO_X1_TAB2: + case USB_DEVICE_ID_LENOVO_X1_TAB3: + ret = lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value); + break; +@@ -1140,6 +1144,7 @@ static int lenovo_probe(struct hid_device *hdev, + break; + case USB_DEVICE_ID_LENOVO_TP10UBKBD: + case USB_DEVICE_ID_LENOVO_X1_TAB: ++ case USB_DEVICE_ID_LENOVO_X1_TAB2: + case USB_DEVICE_ID_LENOVO_X1_TAB3: + ret = lenovo_probe_tp10ubkbd(hdev); + break; +@@ -1207,6 +1212,7 @@ static void lenovo_remove(struct hid_device *hdev) + break; + case USB_DEVICE_ID_LENOVO_TP10UBKBD: + case USB_DEVICE_ID_LENOVO_X1_TAB: ++ case USB_DEVICE_ID_LENOVO_X1_TAB2: + case USB_DEVICE_ID_LENOVO_X1_TAB3: + lenovo_remove_tp10ubkbd(hdev); + break; +@@ -1253,6 +1259,8 @@ static const struct hid_device_id lenovo_devices[] = { + */ + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB) }, ++ { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, ++ USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB2) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB3) }, + { } +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index bc9ba011ff607..c12f7cb7e1d95 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -2108,12 +2108,18 @@ static const struct hid_device_id mt_devices[] = { + HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC, + USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_7010) }, + +- /* Lenovo X1 TAB Gen 2 */ ++ /* Lenovo X1 TAB Gen 1 */ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_LENOVO, + USB_DEVICE_ID_LENOVO_X1_TAB) }, + ++ /* Lenovo X1 TAB Gen 2 */ ++ { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, ++ HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, ++ USB_VENDOR_ID_LENOVO, ++ USB_DEVICE_ID_LENOVO_X1_TAB2) }, ++ + /* Lenovo X1 TAB Gen 3 */ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, +-- +2.39.5 + diff --git a/queue-5.15/hid-quirks-add-quirk-for-2-chicony-electronics-hp-5m.patch b/queue-5.15/hid-quirks-add-quirk-for-2-chicony-electronics-hp-5m.patch new file mode 100644 index 0000000000..d6e1be1940 --- /dev/null +++ b/queue-5.15/hid-quirks-add-quirk-for-2-chicony-electronics-hp-5m.patch @@ -0,0 +1,54 @@ +From bb8095b5d90d9732f5d59f3d6934705dc688ae52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 May 2025 13:50:15 +0800 +Subject: HID: quirks: Add quirk for 2 Chicony Electronics HP 5MP Cameras + +From: Chia-Lin Kao (AceLan) + +[ Upstream commit 54bae4c17c11688339eb73a04fd24203bb6e7494 ] + +The Chicony Electronics HP 5MP Cameras (USB ID 04F2:B824 & 04F2:B82C) +report a HID sensor interface that is not actually implemented. +Attempting to access this non-functional sensor via iio_info causes +system hangs as runtime PM tries to wake up an unresponsive sensor. + +Add these 2 devices to the HID ignore list since the sensor interface is +non-functional by design and should not be exposed to userspace. + +Signed-off-by: Chia-Lin Kao (AceLan) +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-ids.h | 2 ++ + drivers/hid/hid-quirks.c | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 6b3c380584402..bdad42f1e9f96 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -283,6 +283,8 @@ + #define USB_DEVICE_ID_ASUS_AK1D 0x1125 + #define USB_DEVICE_ID_CHICONY_TOSHIBA_WT10A 0x1408 + #define USB_DEVICE_ID_CHICONY_ACER_SWITCH12 0x1421 ++#define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA 0xb824 ++#define USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA2 0xb82c + + #define USB_VENDOR_ID_CHUNGHWAT 0x2247 + #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index f188a79330c68..72b7aebcc771f 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -727,6 +727,8 @@ static const struct hid_device_id hid_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, + { HID_USB_DEVICE(USB_VENDOR_ID_AXENTIA, USB_DEVICE_ID_AXENTIA_FM_RADIO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_HP_5MP_CAMERA2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI4713) }, +-- +2.39.5 + diff --git a/queue-5.15/input-xpad-support-acer-ngr-200-controller.patch b/queue-5.15/input-xpad-support-acer-ngr-200-controller.patch new file mode 100644 index 0000000000..4ef69cef42 --- /dev/null +++ b/queue-5.15/input-xpad-support-acer-ngr-200-controller.patch @@ -0,0 +1,43 @@ +From 755d4d2c7ac77dbd89122a5a7df1c7a79f9ce497 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Jun 2025 16:29:40 -0700 +Subject: Input: xpad - support Acer NGR 200 Controller + +From: Nilton Perim Neto + +[ Upstream commit 22c69d786ef8fb789c61ca75492a272774221324 ] + +Add the NGR 200 Xbox 360 to the list of recognized controllers. + +Signed-off-by: Nilton Perim Neto +Link: https://lore.kernel.org/r/20250608060517.14967-1-niltonperimneto@gmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/joystick/xpad.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 98397c2c6bfac..a5207d6a5ebea 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -149,6 +149,7 @@ static const struct xpad_device { + { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX }, + { 0x05fe, 0x3030, "Chic Controller", 0, XTYPE_XBOX }, + { 0x05fe, 0x3031, "Chic Controller", 0, XTYPE_XBOX }, ++ { 0x0502, 0x1305, "Acer NGR200", 0, XTYPE_XBOX }, + { 0x062a, 0x0020, "Logic3 Xbox GamePad", 0, XTYPE_XBOX }, + { 0x062a, 0x0033, "Competition Pro Steering Wheel", 0, XTYPE_XBOX }, + { 0x06a3, 0x0200, "Saitek Racing Wheel", 0, XTYPE_XBOX }, +@@ -443,6 +444,7 @@ static const struct usb_device_id xpad_table[] = { + XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ + XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ + XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ ++ XPAD_XBOX360_VENDOR(0x0502), /* Acer Inc. X-Box 360 style controllers */ + XPAD_XBOX360_VENDOR(0x056e), /* Elecom JC-U3613M */ + XPAD_XBOX360_VENDOR(0x06a3), /* Saitek P3600 */ + XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ +-- +2.39.5 + diff --git a/queue-5.15/ksmbd-fix-a-mount-write-count-leak-in-ksmbd_vfs_kern.patch b/queue-5.15/ksmbd-fix-a-mount-write-count-leak-in-ksmbd_vfs_kern.patch new file mode 100644 index 0000000000..8cf1ef395f --- /dev/null +++ b/queue-5.15/ksmbd-fix-a-mount-write-count-leak-in-ksmbd_vfs_kern.patch @@ -0,0 +1,39 @@ +From e114ce87c0ccb80f05c5f6bf3a5dcebd39caa624 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 6 Jul 2025 02:26:45 +0100 +Subject: ksmbd: fix a mount write count leak in ksmbd_vfs_kern_path_locked() + +From: Al Viro + +[ Upstream commit 277627b431a0a6401635c416a21b2a0f77a77347 ] + +If the call of ksmbd_vfs_lock_parent() fails, we drop the parent_path +references and return an error. We need to drop the write access we +just got on parent_path->mnt before we drop the mount reference - callers +assume that ksmbd_vfs_kern_path_locked() returns with mount write +access grabbed if and only if it has returned 0. + +Fixes: 864fb5d37163 ("ksmbd: fix possible deadlock in smb2_open") +Signed-off-by: Al Viro +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/ksmbd/vfs.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ksmbd/vfs.c b/fs/ksmbd/vfs.c +index 7afb2412c4d43..4804976c0c13f 100644 +--- a/fs/ksmbd/vfs.c ++++ b/fs/ksmbd/vfs.c +@@ -1280,6 +1280,7 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name, + + err = ksmbd_vfs_lock_parent(parent_path->dentry, path->dentry); + if (err) { ++ mnt_drop_write(parent_path->mnt); + path_put(path); + path_put(parent_path); + } +-- +2.39.5 + diff --git a/queue-5.15/md-raid1-fix-stack-memory-use-after-return-in-raid1_.patch b/queue-5.15/md-raid1-fix-stack-memory-use-after-return-in-raid1_.patch new file mode 100644 index 0000000000..3d9189d2c9 --- /dev/null +++ b/queue-5.15/md-raid1-fix-stack-memory-use-after-return-in-raid1_.patch @@ -0,0 +1,80 @@ +From 8f68a33454a757e3931a2e357356e5b7fa9da24f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Jun 2025 19:28:40 +0800 +Subject: md/raid1: Fix stack memory use after return in raid1_reshape + +From: Wang Jinchao + +[ Upstream commit d67ed2ccd2d1dcfda9292c0ea8697a9d0f2f0d98 ] + +In the raid1_reshape function, newpool is +allocated on the stack and assigned to conf->r1bio_pool. +This results in conf->r1bio_pool.wait.head pointing +to a stack address. +Accessing this address later can lead to a kernel panic. + +Example access path: + +raid1_reshape() +{ + // newpool is on the stack + mempool_t newpool, oldpool; + // initialize newpool.wait.head to stack address + mempool_init(&newpool, ...); + conf->r1bio_pool = newpool; +} + +raid1_read_request() or raid1_write_request() +{ + alloc_r1bio() + { + mempool_alloc() + { + // if pool->alloc fails + remove_element() + { + --pool->curr_nr; + } + } + } +} + +mempool_free() +{ + if (pool->curr_nr < pool->min_nr) { + // pool->wait.head is a stack address + // wake_up() will try to access this invalid address + // which leads to a kernel panic + return; + wake_up(&pool->wait); + } +} + +Fix: +reinit conf->r1bio_pool.wait after assigning newpool. + +Fixes: afeee514ce7f ("md: convert to bioset_init()/mempool_init()") +Signed-off-by: Wang Jinchao +Reviewed-by: Yu Kuai +Link: https://lore.kernel.org/linux-raid/20250612112901.3023950-1-wangjinchao600@gmail.com +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/raid1.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c +index de87606b2e04c..3eacac244f3de 100644 +--- a/drivers/md/raid1.c ++++ b/drivers/md/raid1.c +@@ -3319,6 +3319,7 @@ static int raid1_reshape(struct mddev *mddev) + /* ok, everything is stopped */ + oldpool = conf->r1bio_pool; + conf->r1bio_pool = newpool; ++ init_waitqueue_head(&conf->r1bio_pool.wait); + + for (d = d2 = 0; d < conf->raid_disks; d++) { + struct md_rdev *rdev = conf->mirrors[d].rdev; +-- +2.39.5 + diff --git a/queue-5.15/nbd-fix-uaf-in-nbd_genl_connect-error-path.patch b/queue-5.15/nbd-fix-uaf-in-nbd_genl_connect-error-path.patch new file mode 100644 index 0000000000..86aee3f497 --- /dev/null +++ b/queue-5.15/nbd-fix-uaf-in-nbd_genl_connect-error-path.patch @@ -0,0 +1,86 @@ +From 39b93e5ab8304c5e884c326dee1f425bea78b5b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Jun 2025 21:24:05 +0800 +Subject: nbd: fix uaf in nbd_genl_connect() error path + +From: Zheng Qixing + +[ Upstream commit aa9552438ebf015fc5f9f890dbfe39f0c53cf37e ] + +There is a use-after-free issue in nbd: + +block nbd6: Receive control failed (result -104) +block nbd6: shutting down sockets +================================================================== +BUG: KASAN: slab-use-after-free in recv_work+0x694/0xa80 drivers/block/nbd.c:1022 +Write of size 4 at addr ffff8880295de478 by task kworker/u33:0/67 + +CPU: 2 UID: 0 PID: 67 Comm: kworker/u33:0 Not tainted 6.15.0-rc5-syzkaller-00123-g2c89c1b655c0 #0 PREEMPT(full) +Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 +Workqueue: nbd6-recv recv_work +Call Trace: + + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 + print_address_description mm/kasan/report.c:408 [inline] + print_report+0xc3/0x670 mm/kasan/report.c:521 + kasan_report+0xe0/0x110 mm/kasan/report.c:634 + check_region_inline mm/kasan/generic.c:183 [inline] + kasan_check_range+0xef/0x1a0 mm/kasan/generic.c:189 + instrument_atomic_read_write include/linux/instrumented.h:96 [inline] + atomic_dec include/linux/atomic/atomic-instrumented.h:592 [inline] + recv_work+0x694/0xa80 drivers/block/nbd.c:1022 + process_one_work+0x9cc/0x1b70 kernel/workqueue.c:3238 + process_scheduled_works kernel/workqueue.c:3319 [inline] + worker_thread+0x6c8/0xf10 kernel/workqueue.c:3400 + kthread+0x3c2/0x780 kernel/kthread.c:464 + ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:153 + ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 + + +nbd_genl_connect() does not properly stop the device on certain +error paths after nbd_start_device() has been called. This causes +the error path to put nbd->config while recv_work continue to use +the config after putting it, leading to use-after-free in recv_work. + +This patch moves nbd_start_device() after the backend file creation. + +Reported-by: syzbot+48240bab47e705c53126@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68227a04.050a0220.f2294.00b5.GAE@google.com/T/ +Fixes: 6497ef8df568 ("nbd: provide a way for userspace processes to identify device backends") +Signed-off-by: Zheng Qixing +Reviewed-by: Yu Kuai +Link: https://lore.kernel.org/r/20250612132405.364904-1-zhengqixing@huaweicloud.com +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 1b04fd7c6b98a..eca713f87614f 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2011,9 +2011,7 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) + goto out; + } + } +- ret = nbd_start_device(nbd); +- if (ret) +- goto out; ++ + if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER]) { + nbd->backend = nla_strdup(info->attrs[NBD_ATTR_BACKEND_IDENTIFIER], + GFP_KERNEL); +@@ -2029,6 +2027,8 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) + goto out; + } + set_bit(NBD_RT_HAS_BACKEND_FILE, &config->runtime_flags); ++ ++ ret = nbd_start_device(nbd); + out: + mutex_unlock(&nbd->config_lock); + if (!ret) { +-- +2.39.5 + diff --git a/queue-5.15/net-appletalk-fix-device-refcount-leak-in-atrtr_crea.patch b/queue-5.15/net-appletalk-fix-device-refcount-leak-in-atrtr_crea.patch new file mode 100644 index 0000000000..22ead73e48 --- /dev/null +++ b/queue-5.15/net-appletalk-fix-device-refcount-leak-in-atrtr_crea.patch @@ -0,0 +1,38 @@ +From db65611917dc41a17c514062948bf037836c94ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Jul 2025 03:52:51 +0000 +Subject: net: appletalk: Fix device refcount leak in atrtr_create() + +From: Kito Xu + +[ Upstream commit 711c80f7d8b163d3ecd463cd96f07230f488e750 ] + +When updating an existing route entry in atrtr_create(), the old device +reference was not being released before assigning the new device, +leading to a device refcount leak. Fix this by calling dev_put() to +release the old device reference before holding the new one. + +Fixes: c7f905f0f6d4 ("[ATALK]: Add missing dev_hold() to atrtr_create().") +Signed-off-by: Kito Xu +Link: https://patch.msgid.link/tencent_E1A26771CDAB389A0396D1681A90A49E5D09@qq.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/appletalk/ddp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c +index 8daa3a1bfa4cd..344a38905c48d 100644 +--- a/net/appletalk/ddp.c ++++ b/net/appletalk/ddp.c +@@ -563,6 +563,7 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint) + + /* Fill in the routing entry */ + rt->target = ta->sat_addr; ++ dev_put(rt->dev); /* Release old device */ + dev_hold(devhint); + rt->dev = devhint; + rt->flags = r->rt_flags; +-- +2.39.5 + diff --git a/queue-5.15/net-ll_temac-fix-missing-tx_pending-check-in-ethtool.patch b/queue-5.15/net-ll_temac-fix-missing-tx_pending-check-in-ethtool.patch new file mode 100644 index 0000000000..fa66a59175 --- /dev/null +++ b/queue-5.15/net-ll_temac-fix-missing-tx_pending-check-in-ethtool.patch @@ -0,0 +1,45 @@ +From bb5e7cb697ca72a87da04d2244f2d753de31c66d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 10 Jul 2025 11:06:17 -0700 +Subject: net: ll_temac: Fix missing tx_pending check in + ethtools_set_ringparam() + +From: Alok Tiwari + +[ Upstream commit e81750b4e3826fedce7362dad839cb40384d60ae ] + +The function ll_temac_ethtools_set_ringparam() incorrectly checked +rx_pending twice, once correctly for RX and once mistakenly in place +of tx_pending. This caused tx_pending to be left unchecked against +TX_BD_NUM_MAX. +As a result, invalid TX ring sizes may have been accepted or valid +ones wrongly rejected based on the RX limit, leading to potential +misconfiguration or unexpected results. + +This patch corrects the condition to properly validate tx_pending. + +Fixes: f7b261bfc35e ("net: ll_temac: Make RX/TX ring sizes configurable") +Signed-off-by: Alok Tiwari +Link: https://patch.msgid.link/20250710180621.2383000-1-alok.a.tiwari@oracle.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/xilinx/ll_temac_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index 4e45153959c79..ce0d2760a55e0 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -1299,7 +1299,7 @@ static int ll_temac_ethtools_set_ringparam(struct net_device *ndev, + if (ering->rx_pending > RX_BD_NUM_MAX || + ering->rx_mini_pending || + ering->rx_jumbo_pending || +- ering->rx_pending > TX_BD_NUM_MAX) ++ ering->tx_pending > TX_BD_NUM_MAX) + return -EINVAL; + + if (netif_running(ndev)) +-- +2.39.5 + diff --git a/queue-5.15/net-phy-microchip-limit-100m-workaround-to-link-down.patch b/queue-5.15/net-phy-microchip-limit-100m-workaround-to-link-down.patch new file mode 100644 index 0000000000..671abe0fd3 --- /dev/null +++ b/queue-5.15/net-phy-microchip-limit-100m-workaround-to-link-down.patch @@ -0,0 +1,60 @@ +From c8374fcde90f95f113c260bf5cb08509ef3f868d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Jul 2025 15:07:53 +0200 +Subject: net: phy: microchip: limit 100M workaround to link-down events on + LAN88xx + +From: Oleksij Rempel + +[ Upstream commit dd4360c0e8504f2f7639c7f5d07c93cfd6a98333 ] + +Restrict the 100Mbit forced-mode workaround to link-down transitions +only, to prevent repeated link reset cycles in certain configurations. + +The workaround was originally introduced to improve signal reliability +when switching cables between long and short distances. It temporarily +forces the PHY into 10 Mbps before returning to 100 Mbps. + +However, when used with autonegotiating link partners (e.g., Intel i350), +executing this workaround on every link change can confuse the partner +and cause constant renegotiation loops. This results in repeated link +down/up transitions and the PHY never reaching a stable state. + +Limit the workaround to only run during the PHY_NOLINK state. This ensures +it is triggered only once per link drop, avoiding disruptive toggling +while still preserving its intended effect. + +Note: I am not able to reproduce the original issue that this workaround +addresses. I can only confirm that 100 Mbit mode works correctly in my +test setup. Based on code inspection, I assume the workaround aims to +reset some internal state machine or signal block by toggling speeds. +However, a PHY reset is already performed earlier in the function via +phy_init_hw(), which may achieve a similar effect. Without a reproducer, +I conservatively keep the workaround but restrict its conditions. + +Fixes: e57cf3639c32 ("net: lan78xx: fix accessing the LAN7800's internal phy specific registers from the MAC driver") +Signed-off-by: Oleksij Rempel +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20250709130753.3994461-3-o.rempel@pengutronix.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/microchip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/microchip.c b/drivers/net/phy/microchip.c +index 230f2fcf9c46a..f2860ec7ac17e 100644 +--- a/drivers/net/phy/microchip.c ++++ b/drivers/net/phy/microchip.c +@@ -351,7 +351,7 @@ static void lan88xx_link_change_notify(struct phy_device *phydev) + * As workaround, set to 10 before setting to 100 + * at forced 100 F/H mode. + */ +- if (!phydev->autoneg && phydev->speed == 100) { ++ if (phydev->state == PHY_NOLINK && !phydev->autoneg && phydev->speed == 100) { + /* disable phy interrupt */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; +-- +2.39.5 + diff --git a/queue-5.15/net-usb-qmi_wwan-add-simcom-8230c-composition.patch b/queue-5.15/net-usb-qmi_wwan-add-simcom-8230c-composition.patch new file mode 100644 index 0000000000..86267cf56b --- /dev/null +++ b/queue-5.15/net-usb-qmi_wwan-add-simcom-8230c-composition.patch @@ -0,0 +1,63 @@ +From 55b2114067406a94e2932f3b9a1130229f0698c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Jun 2025 10:27:02 +0800 +Subject: net: usb: qmi_wwan: add SIMCom 8230C composition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiaowei Li + +[ Upstream commit 0b39b055b5b48cbbdf5746a1ca6e3f6b0221e537 ] + +Add support for SIMCom 8230C which is based on Qualcomm SDX35 chip. +0x9071: tty (DM) + tty (NMEA) + tty (AT) + rmnet +T: Bus=01 Lev=01 Prnt=01 Port=05 Cnt=02 Dev#= 8 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=1e0e ProdID=9071 Rev= 5.15 +S: Manufacturer=SIMCOM +S: Product=SDXBAAGHA-IDP _SN:D744C4C5 +S: SerialNumber=0123456789ABCDEF +C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option +E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan +E: Ad=86(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=none +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Signed-off-by: Xiaowei Li +Acked-by: Bjørn Mork +Link: https://patch.msgid.link/tencent_21D781FAA4969FEACA6ABB460362B52C9409@qq.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/qmi_wwan.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 600a190f22128..d21d23f10d422 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1421,6 +1421,7 @@ static const struct usb_device_id products[] = { + {QMI_FIXED_INTF(0x03f0, 0x9d1d, 1)}, /* HP lt4120 Snapdragon X5 LTE */ + {QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */ + {QMI_QUIRK_SET_DTR(0x1e0e, 0x9001, 5)}, /* SIMCom 7100E, 7230E, 7600E ++ */ ++ {QMI_QUIRK_SET_DTR(0x1e0e, 0x9071, 3)}, /* SIMCom 8230C ++ */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)}, /* Quectel EC21 Mini PCIe */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)}, /* Quectel EG91 */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x0195, 4)}, /* Quectel EG95 */ +-- +2.39.5 + diff --git a/queue-5.15/netfilter-flowtable-account-for-ethernet-header-in-n.patch b/queue-5.15/netfilter-flowtable-account-for-ethernet-header-in-n.patch new file mode 100644 index 0000000000..aad8e23942 --- /dev/null +++ b/queue-5.15/netfilter-flowtable-account-for-ethernet-header-in-n.patch @@ -0,0 +1,61 @@ +From ee15ebbadad5c093693fdcfbb7435bad73e12f4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Jul 2025 12:45:17 +0000 +Subject: netfilter: flowtable: account for Ethernet header in + nf_flow_pppoe_proto() + +From: Eric Dumazet + +[ Upstream commit 18cdb3d982da8976b28d57691eb256ec5688fad2 ] + +syzbot found a potential access to uninit-value in nf_flow_pppoe_proto() + +Blamed commit forgot the Ethernet header. + +BUG: KMSAN: uninit-value in nf_flow_offload_inet_hook+0x7e4/0x940 net/netfilter/nf_flow_table_inet.c:27 + nf_flow_offload_inet_hook+0x7e4/0x940 net/netfilter/nf_flow_table_inet.c:27 + nf_hook_entry_hookfn include/linux/netfilter.h:157 [inline] + nf_hook_slow+0xe1/0x3d0 net/netfilter/core.c:623 + nf_hook_ingress include/linux/netfilter_netdev.h:34 [inline] + nf_ingress net/core/dev.c:5742 [inline] + __netif_receive_skb_core+0x4aff/0x70c0 net/core/dev.c:5837 + __netif_receive_skb_one_core net/core/dev.c:5975 [inline] + __netif_receive_skb+0xcc/0xac0 net/core/dev.c:6090 + netif_receive_skb_internal net/core/dev.c:6176 [inline] + netif_receive_skb+0x57/0x630 net/core/dev.c:6235 + tun_rx_batched+0x1df/0x980 drivers/net/tun.c:1485 + tun_get_user+0x4ee0/0x6b40 drivers/net/tun.c:1938 + tun_chr_write_iter+0x3e9/0x5c0 drivers/net/tun.c:1984 + new_sync_write fs/read_write.c:593 [inline] + vfs_write+0xb4b/0x1580 fs/read_write.c:686 + ksys_write fs/read_write.c:738 [inline] + __do_sys_write fs/read_write.c:749 [inline] + +Reported-by: syzbot+bf6ed459397e307c3ad2@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/686bc073.a00a0220.c7b3.0086.GAE@google.com/T/#u +Fixes: 87b3593bed18 ("netfilter: flowtable: validate pppoe header") +Signed-off-by: Eric Dumazet +Reviewed-by: Pablo Neira Ayuso +Link: https://patch.msgid.link/20250707124517.614489-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_flow_table.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h +index 8e98fb8edff8d..664c3637e283c 100644 +--- a/include/net/netfilter/nf_flow_table.h ++++ b/include/net/netfilter/nf_flow_table.h +@@ -336,7 +336,7 @@ static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb) + + static inline bool nf_flow_pppoe_proto(struct sk_buff *skb, __be16 *inner_proto) + { +- if (!pskb_may_pull(skb, PPPOE_SES_HLEN)) ++ if (!pskb_may_pull(skb, ETH_HLEN + PPPOE_SES_HLEN)) + return false; + + *inner_proto = __nf_flow_pppoe_proto(skb); +-- +2.39.5 + diff --git a/queue-5.15/platform-x86-think-lmi-fix-sysfs-group-cleanup.patch b/queue-5.15/platform-x86-think-lmi-fix-sysfs-group-cleanup.patch new file mode 100644 index 0000000000..a490bcb337 --- /dev/null +++ b/queue-5.15/platform-x86-think-lmi-fix-sysfs-group-cleanup.patch @@ -0,0 +1,131 @@ +From 357c8f1ceab8d83276cdda4f32b6380846fb4f9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Jul 2025 04:49:29 -0400 +Subject: platform/x86: think-lmi: Fix sysfs group cleanup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kurt Borja + +[ Upstream commit 4f30f946f27b7f044cf8f3f1f353dee1dcd3517a ] + +Many error paths in tlmi_sysfs_init() lead to sysfs groups being removed +when they were not even created. + +Fix this by letting the kobject core manage these groups through their +kobj_type's defult_groups. + +Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms") +Cc: stable@vger.kernel.org +Reviewed-by: Mark Pearson +Reviewed-by: Ilpo Järvinen +Signed-off-by: Kurt Borja +Link: https://lore.kernel.org/r/20250630-lmi-fix-v3-3-ce4f81c9c481@gmail.com +Signed-off-by: Ilpo Järvinen +Signed-off-by: Sasha Levin +--- + drivers/platform/x86/think-lmi.c | 35 +++++++++----------------------- + 1 file changed, 10 insertions(+), 25 deletions(-) + +diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c +index 36ff64a7b6847..cc46aa5f1da2c 100644 +--- a/drivers/platform/x86/think-lmi.c ++++ b/drivers/platform/x86/think-lmi.c +@@ -491,6 +491,7 @@ static struct attribute *auth_attrs[] = { + static const struct attribute_group auth_attr_group = { + .attrs = auth_attrs, + }; ++__ATTRIBUTE_GROUPS(auth_attr); + + /* ---- Attributes sysfs --------------------------------------------------------- */ + static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribute *attr, +@@ -643,6 +644,7 @@ static const struct attribute_group tlmi_attr_group = { + .is_visible = attr_is_visible, + .attrs = tlmi_attrs, + }; ++__ATTRIBUTE_GROUPS(tlmi_attr); + + static ssize_t tlmi_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +@@ -688,12 +690,14 @@ static void tlmi_pwd_setting_release(struct kobject *kobj) + + static struct kobj_type tlmi_attr_setting_ktype = { + .release = &tlmi_attr_setting_release, +- .sysfs_ops = &tlmi_kobj_sysfs_ops, ++ .sysfs_ops = &kobj_sysfs_ops, ++ .default_groups = tlmi_attr_groups, + }; + + static struct kobj_type tlmi_pwd_setting_ktype = { + .release = &tlmi_pwd_setting_release, +- .sysfs_ops = &tlmi_kobj_sysfs_ops, ++ .sysfs_ops = &kobj_sysfs_ops, ++ .default_groups = auth_attr_groups, + }; + + static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr, +@@ -765,25 +769,18 @@ static struct kobj_attribute debug_cmd = __ATTR_WO(debug_cmd); + /* ---- Initialisation --------------------------------------------------------- */ + static void tlmi_release_attr(void) + { +- int i; ++ struct kobject *pos, *n; + + /* Attribute structures */ +- for (i = 0; i < TLMI_SETTINGS_COUNT; i++) { +- if (tlmi_priv.setting[i]) { +- sysfs_remove_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group); +- kobject_put(&tlmi_priv.setting[i]->kobj); +- } +- } + sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr); + if (tlmi_priv.can_debug_cmd && debug_support) + sysfs_remove_file(&tlmi_priv.attribute_kset->kobj, &debug_cmd.attr); + kset_unregister(tlmi_priv.attribute_kset); + + /* Authentication structures */ +- sysfs_remove_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group); +- kobject_put(&tlmi_priv.pwd_admin->kobj); +- sysfs_remove_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group); +- kobject_put(&tlmi_priv.pwd_power->kobj); ++ list_for_each_entry_safe(pos, n, &tlmi_priv.authentication_kset->list, entry) ++ kobject_put(pos); ++ + kset_unregister(tlmi_priv.authentication_kset); + } + +@@ -855,10 +852,6 @@ static int tlmi_sysfs_init(void) + "%s", tlmi_priv.setting[i]->display_name); + if (ret) + goto fail_create_attr; +- +- ret = sysfs_create_group(&tlmi_priv.setting[i]->kobj, &tlmi_attr_group); +- if (ret) +- goto fail_create_attr; + } + + ret = sysfs_create_file(&tlmi_priv.attribute_kset->kobj, &pending_reboot.attr); +@@ -876,19 +869,11 @@ static int tlmi_sysfs_init(void) + if (ret) + goto fail_create_attr; + +- ret = sysfs_create_group(&tlmi_priv.pwd_admin->kobj, &auth_attr_group); +- if (ret) +- goto fail_create_attr; +- + tlmi_priv.pwd_power->kobj.kset = tlmi_priv.authentication_kset; + ret = kobject_add(&tlmi_priv.pwd_power->kobj, NULL, "%s", "System"); + if (ret) + goto fail_create_attr; + +- ret = sysfs_create_group(&tlmi_priv.pwd_power->kobj, &auth_attr_group); +- if (ret) +- goto fail_create_attr; +- + return ret; + + fail_create_attr: +-- +2.39.5 + diff --git a/queue-5.15/raid10-cleanup-memleak-at-raid10_make_request.patch b/queue-5.15/raid10-cleanup-memleak-at-raid10_make_request.patch new file mode 100644 index 0000000000..ef1c0423a4 --- /dev/null +++ b/queue-5.15/raid10-cleanup-memleak-at-raid10_make_request.patch @@ -0,0 +1,81 @@ +From 43f341bc18c0070772a8c10fb055ce516823f7a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 3 Jul 2025 11:23:04 -0400 +Subject: raid10: cleanup memleak at raid10_make_request + +From: Nigel Croxon + +[ Upstream commit 43806c3d5b9bb7d74ba4e33a6a8a41ac988bde24 ] + +If raid10_read_request or raid10_write_request registers a new +request and the REQ_NOWAIT flag is set, the code does not +free the malloc from the mempool. + +unreferenced object 0xffff8884802c3200 (size 192): + comm "fio", pid 9197, jiffies 4298078271 + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 88 41 02 00 00 00 00 00 .........A...... + 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace (crc c1a049a2): + __kmalloc+0x2bb/0x450 + mempool_alloc+0x11b/0x320 + raid10_make_request+0x19e/0x650 [raid10] + md_handle_request+0x3b3/0x9e0 + __submit_bio+0x394/0x560 + __submit_bio_noacct+0x145/0x530 + submit_bio_noacct_nocheck+0x682/0x830 + __blkdev_direct_IO_async+0x4dc/0x6b0 + blkdev_read_iter+0x1e5/0x3b0 + __io_read+0x230/0x1110 + io_read+0x13/0x30 + io_issue_sqe+0x134/0x1180 + io_submit_sqes+0x48c/0xe90 + __do_sys_io_uring_enter+0x574/0x8b0 + do_syscall_64+0x5c/0xe0 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +V4: changing backing tree to see if CKI tests will pass. +The patch code has not changed between any versions. + +Fixes: c9aa889b035f ("md: raid10 add nowait support") +Signed-off-by: Nigel Croxon +Link: https://lore.kernel.org/linux-raid/c0787379-9caa-42f3-b5fc-369aed784400@redhat.com +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/raid10.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index e6c0e24cb9ae2..5b0f38e7c8f13 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -1196,8 +1196,11 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio, + rcu_read_unlock(); + } + +- if (!regular_request_wait(mddev, conf, bio, r10_bio->sectors)) ++ if (!regular_request_wait(mddev, conf, bio, r10_bio->sectors)) { ++ raid_end_bio_io(r10_bio); + return; ++ } ++ + rdev = read_balance(conf, r10_bio, &max_sectors); + if (!rdev) { + if (err_rdev) { +@@ -1431,8 +1434,11 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio, + } + + sectors = r10_bio->sectors; +- if (!regular_request_wait(mddev, conf, bio, sectors)) ++ if (!regular_request_wait(mddev, conf, bio, sectors)) { ++ raid_end_bio_io(r10_bio); + return; ++ } ++ + if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && + (mddev->reshape_backwards + ? (bio->bi_iter.bi_sector < conf->reshape_safe && +-- +2.39.5 + diff --git a/queue-5.15/series b/queue-5.15/series index 12323c78a6..33d551ecc5 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -38,3 +38,38 @@ rdma-mlx5-fix-vport-loopback-for-mpv-device.patch pwm-mediatek-ensure-to-disable-clocks-in-error-path.patch netlink-fix-rmem-check-in-netlink_broadcast_deliver.patch netlink-make-sure-we-allow-at-least-one-dump-skb.patch +virtio-net-ensure-the-received-length-does-not-excee.patch +xhci-allow-rpm-on-the-usb-controller-1022-43f7-by-de.patch +usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch +xhci-disable-stream-for-xhc-controller-with-xhci_bro.patch +input-xpad-support-acer-ngr-200-controller.patch +usb-cdnsp-remove-trb_flush_endpoint-command.patch +usb-cdnsp-replace-snprintf-with-the-safer-scnprintf-.patch +usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch +usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch +smb-client-fix-readdir-returning-wrong-type-with-pos.patch +dma-buf-add-dma_resv_for_each_fence_unlocked-v8.patch +dma-buf-use-new-iterator-in-dma_resv_wait_timeout.patch +dma-buf-fix-timeout-handling-in-dma_resv_wait_timeou.patch +platform-x86-think-lmi-fix-sysfs-group-cleanup.patch +btrfs-fix-inode-lookup-error-handling-during-log-rep.patch +wifi-zd1211rw-fix-potential-null-pointer-dereference.patch +md-raid1-fix-stack-memory-use-after-return-in-raid1_.patch +raid10-cleanup-memleak-at-raid10_make_request.patch +nbd-fix-uaf-in-nbd_genl_connect-error-path.patch +smb-server-make-use-of-rdma_destroy_qp.patch +ksmbd-fix-a-mount-write-count-leak-in-ksmbd_vfs_kern.patch +netfilter-flowtable-account-for-ethernet-header-in-n.patch +net-appletalk-fix-device-refcount-leak-in-atrtr_crea.patch +net-phy-microchip-limit-100m-workaround-to-link-down.patch +can-m_can-m_can_handle_lost_msg-downgrade-msg-lost-i.patch +net-ll_temac-fix-missing-tx_pending-check-in-ethtool.patch +bnxt_en-fix-dcb-ets-validation.patch +bnxt_en-set-dma-unmap-len-correctly-for-xdp_redirect.patch +atm-idt77252-add-missing-dma_map_error.patch +um-vector-reduce-stack-usage-in-vector_eth_configure.patch +net-usb-qmi_wwan-add-simcom-8230c-composition.patch +hid-lenovo-add-support-for-thinkpad-x1-tablet-thin-k.patch +vt-add-missing-notification-when-switching-back-to-t.patch +hid-add-ignore-quirk-for-smartlinktechnology.patch +hid-quirks-add-quirk-for-2-chicony-electronics-hp-5m.patch diff --git a/queue-5.15/smb-client-fix-readdir-returning-wrong-type-with-pos.patch b/queue-5.15/smb-client-fix-readdir-returning-wrong-type-with-pos.patch new file mode 100644 index 0000000000..5939a925b4 --- /dev/null +++ b/queue-5.15/smb-client-fix-readdir-returning-wrong-type-with-pos.patch @@ -0,0 +1,57 @@ +From e0a5ae8bdad18a7b15daf2cd56ef88c44925427f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 12 Jul 2025 03:52:17 -0400 +Subject: smb: client: fix readdir returning wrong type with POSIX extensions + +From: Philipp Kerling + +[ Upstream commit b8f89cb723b9e66f5dbd7199e4036fee34fb0de0 ] + +When SMB 3.1.1 POSIX Extensions are negotiated, userspace applications +using readdir() or getdents() calls without stat() on each individual file +(such as a simple "ls" or "find") would misidentify file types and exhibit +strange behavior such as not descending into directories. The reason for +this behavior is an oversight in the cifs_posix_to_fattr conversion +function. Instead of extracting the entry type for cf_dtype from the +properly converted cf_mode field, it tries to extract the type from the +PDU. While the wire representation of the entry mode is similar in +structure to POSIX stat(), the assignments of the entry types are +different. Applying the S_DT macro to cf_mode instead yields the correct +result. This is also what the equivalent function +smb311_posix_info_to_fattr in inode.c already does for stat() etc.; which +is why "ls -l" would give the correct file type but "ls" would not (as +identified by the colors). + +Cc: stable@vger.kernel.org +Signed-off-by: Philipp Kerling +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/cifs/readdir.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c +index 6aa3c267f4ca4..6512fece737ed 100644 +--- a/fs/cifs/readdir.c ++++ b/fs/cifs/readdir.c +@@ -262,7 +262,6 @@ cifs_posix_to_fattr(struct cifs_fattr *fattr, struct smb2_posix_info *info, + + if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { + fattr->cf_mode |= S_IFDIR; +- fattr->cf_dtype = DT_DIR; + } else { + /* + * mark anything that is not a dir as regular +@@ -270,8 +269,8 @@ cifs_posix_to_fattr(struct cifs_fattr *fattr, struct smb2_posix_info *info, + * attribute and will be marked as needing revaluation + */ + fattr->cf_mode |= S_IFREG; +- fattr->cf_dtype = DT_REG; + } ++ fattr->cf_dtype = S_DT(fattr->cf_mode); + + if (reparse_file_needs_reval(fattr)) + fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; +-- +2.39.5 + diff --git a/queue-5.15/smb-server-make-use-of-rdma_destroy_qp.patch b/queue-5.15/smb-server-make-use-of-rdma_destroy_qp.patch new file mode 100644 index 0000000000..9f5e0e9dd7 --- /dev/null +++ b/queue-5.15/smb-server-make-use-of-rdma_destroy_qp.patch @@ -0,0 +1,72 @@ +From b8154fce42b88dbd16795e3b438aea42210e4bf7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 2 Jul 2025 09:18:05 +0200 +Subject: smb: server: make use of rdma_destroy_qp() + +From: Stefan Metzmacher + +[ Upstream commit 0c2b53997e8f5e2ec9e0fbd17ac0436466b65488 ] + +The qp is created by rdma_create_qp() as t->cm_id->qp +and t->qp is just a shortcut. + +rdma_destroy_qp() also calls ib_destroy_qp(cm_id->qp) internally, +but it is protected by a mutex, clears the cm_id and also calls +trace_cm_qp_destroy(). + +This should make the tracing more useful as both +rdma_create_qp() and rdma_destroy_qp() are traces and it makes +the code look more sane as functions from the same layer are used +for the specific qp object. + +trace-cmd stream -e rdma_cma:cm_qp_create -e rdma_cma:cm_qp_destroy +shows this now while doing a mount and unmount from a client: + + <...>-80 [002] 378.514182: cm_qp_create: cm.id=1 src=172.31.9.167:5445 dst=172.31.9.166:37113 tos=0 pd.id=0 qp_type=RC send_wr=867 recv_wr=255 qp_num=1 rc=0 + <...>-6283 [001] 381.686172: cm_qp_destroy: cm.id=1 src=172.31.9.167:5445 dst=172.31.9.166:37113 tos=0 qp_num=1 + +Before we only saw the first line. + +Cc: Namjae Jeon +Cc: Steve French +Cc: Sergey Senozhatsky +Cc: Hyunchul Lee +Cc: Tom Talpey +Cc: linux-cifs@vger.kernel.org +Fixes: 0626e6641f6b ("cifsd: add server handler for central processing and tranport layers") +Signed-off-by: Stefan Metzmacher +Reviewed-by: Tom Talpey +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/ksmbd/transport_rdma.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/fs/ksmbd/transport_rdma.c b/fs/ksmbd/transport_rdma.c +index 355673f2830be..91e663d5d5bc1 100644 +--- a/fs/ksmbd/transport_rdma.c ++++ b/fs/ksmbd/transport_rdma.c +@@ -426,7 +426,8 @@ static void free_transport(struct smb_direct_transport *t) + if (t->qp) { + ib_drain_qp(t->qp); + ib_mr_pool_destroy(t->qp, &t->qp->rdma_mrs); +- ib_destroy_qp(t->qp); ++ t->qp = NULL; ++ rdma_destroy_qp(t->cm_id); + } + + ksmbd_debug(RDMA, "drain the reassembly queue\n"); +@@ -1934,8 +1935,8 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t, + return 0; + err: + if (t->qp) { +- ib_destroy_qp(t->qp); + t->qp = NULL; ++ rdma_destroy_qp(t->cm_id); + } + if (t->recv_cq) { + ib_destroy_cq(t->recv_cq); +-- +2.39.5 + diff --git a/queue-5.15/um-vector-reduce-stack-usage-in-vector_eth_configure.patch b/queue-5.15/um-vector-reduce-stack-usage-in-vector_eth_configure.patch new file mode 100644 index 0000000000..0ec9cfe87a --- /dev/null +++ b/queue-5.15/um-vector-reduce-stack-usage-in-vector_eth_configure.patch @@ -0,0 +1,93 @@ +From 3842c844caf945912d4027b545a916e65797c463 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 23 Jun 2025 19:08:29 +0800 +Subject: um: vector: Reduce stack usage in vector_eth_configure() + +From: Tiwei Bie + +[ Upstream commit 2d65fc13be85c336c56af7077f08ccd3a3a15a4a ] + +When compiling with clang (19.1.7), initializing *vp using a compound +literal may result in excessive stack usage. Fix it by initializing the +required fields of *vp individually. + +Without this patch: + +$ objdump -d arch/um/drivers/vector_kern.o | ./scripts/checkstack.pl x86_64 0 +... +0x0000000000000540 vector_eth_configure [vector_kern.o]:1472 +... + +With this patch: + +$ objdump -d arch/um/drivers/vector_kern.o | ./scripts/checkstack.pl x86_64 0 +... +0x0000000000000540 vector_eth_configure [vector_kern.o]:208 +... + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202506221017.WtB7Usua-lkp@intel.com/ +Signed-off-by: Tiwei Bie +Link: https://patch.msgid.link/20250623110829.314864-1-tiwei.btw@antgroup.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + arch/um/drivers/vector_kern.c | 42 +++++++++++------------------------ + 1 file changed, 13 insertions(+), 29 deletions(-) + +diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c +index c63ccf1ab4a20..41fc93ce4d372 100644 +--- a/arch/um/drivers/vector_kern.c ++++ b/arch/um/drivers/vector_kern.c +@@ -1603,35 +1603,19 @@ static void vector_eth_configure( + + device->dev = dev; + +- *vp = ((struct vector_private) +- { +- .list = LIST_HEAD_INIT(vp->list), +- .dev = dev, +- .unit = n, +- .options = get_transport_options(def), +- .rx_irq = 0, +- .tx_irq = 0, +- .parsed = def, +- .max_packet = get_mtu(def) + ETH_HEADER_OTHER, +- /* TODO - we need to calculate headroom so that ip header +- * is 16 byte aligned all the time +- */ +- .headroom = get_headroom(def), +- .form_header = NULL, +- .verify_header = NULL, +- .header_rxbuffer = NULL, +- .header_txbuffer = NULL, +- .header_size = 0, +- .rx_header_size = 0, +- .rexmit_scheduled = false, +- .opened = false, +- .transport_data = NULL, +- .in_write_poll = false, +- .coalesce = 2, +- .req_size = get_req_size(def), +- .in_error = false, +- .bpf = NULL +- }); ++ INIT_LIST_HEAD(&vp->list); ++ vp->dev = dev; ++ vp->unit = n; ++ vp->options = get_transport_options(def); ++ vp->parsed = def; ++ vp->max_packet = get_mtu(def) + ETH_HEADER_OTHER; ++ /* ++ * TODO - we need to calculate headroom so that ip header ++ * is 16 byte aligned all the time ++ */ ++ vp->headroom = get_headroom(def); ++ vp->coalesce = 2; ++ vp->req_size = get_req_size(def); + + dev->features = dev->hw_features = (NETIF_F_SG | NETIF_F_FRAGLIST); + tasklet_setup(&vp->tx_poll, vector_tx_poll); +-- +2.39.5 + diff --git a/queue-5.15/usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch b/queue-5.15/usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch new file mode 100644 index 0000000000..7642a270f9 --- /dev/null +++ b/queue-5.15/usb-cdnsp-fix-issue-with-cv-bad-descriptor-test.patch @@ -0,0 +1,121 @@ +From 20d06199e72ce17b5607146e46bee8a50ba85891 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Jun 2025 08:23:12 +0000 +Subject: usb: cdnsp: Fix issue with CV Bad Descriptor test + +From: Pawel Laszczak + +[ Upstream commit 2831a81077f5162f104ba5a97a7d886eb371c21c ] + +The SSP2 controller has extra endpoint state preserve bit (ESP) which +setting causes that endpoint state will be preserved during +Halt Endpoint command. It is used only for EP0. +Without this bit the Command Verifier "TD 9.10 Bad Descriptor Test" +failed. +Setting this bit doesn't have any impact for SSP controller. + +Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver") +Cc: stable +Signed-off-by: Pawel Laszczak +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/PH7PR07MB95382CCD50549DABAEFD6156DD7CA@PH7PR07MB9538.namprd07.prod.outlook.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/cdns3/cdnsp-debug.h | 5 +++-- + drivers/usb/cdns3/cdnsp-ep0.c | 18 +++++++++++++++--- + drivers/usb/cdns3/cdnsp-gadget.h | 6 ++++++ + drivers/usb/cdns3/cdnsp-ring.c | 3 ++- + 4 files changed, 26 insertions(+), 6 deletions(-) + +diff --git a/drivers/usb/cdns3/cdnsp-debug.h b/drivers/usb/cdns3/cdnsp-debug.h +index cd138acdcce16..86860686d8363 100644 +--- a/drivers/usb/cdns3/cdnsp-debug.h ++++ b/drivers/usb/cdns3/cdnsp-debug.h +@@ -327,12 +327,13 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0, + case TRB_RESET_EP: + case TRB_HALT_ENDPOINT: + ret = scnprintf(str, size, +- "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c", ++ "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c %c", + cdnsp_trb_type_string(type), + ep_num, ep_id % 2 ? "out" : "in", + TRB_TO_EP_INDEX(field3), field1, field0, + TRB_TO_SLOT_ID(field3), +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ field3 & TRB_CYCLE ? 'C' : 'c', ++ field3 & TRB_ESP ? 'P' : 'p'); + break; + case TRB_STOP_RING: + ret = scnprintf(str, size, +diff --git a/drivers/usb/cdns3/cdnsp-ep0.c b/drivers/usb/cdns3/cdnsp-ep0.c +index f317d3c847810..5cd9b898ce971 100644 +--- a/drivers/usb/cdns3/cdnsp-ep0.c ++++ b/drivers/usb/cdns3/cdnsp-ep0.c +@@ -414,6 +414,7 @@ static int cdnsp_ep0_std_request(struct cdnsp_device *pdev, + void cdnsp_setup_analyze(struct cdnsp_device *pdev) + { + struct usb_ctrlrequest *ctrl = &pdev->setup; ++ struct cdnsp_ep *pep; + int ret = -EINVAL; + u16 len; + +@@ -427,10 +428,21 @@ void cdnsp_setup_analyze(struct cdnsp_device *pdev) + goto out; + } + ++ pep = &pdev->eps[0]; ++ + /* Restore the ep0 to Stopped/Running state. */ +- if (pdev->eps[0].ep_state & EP_HALTED) { +- trace_cdnsp_ep0_halted("Restore to normal state"); +- cdnsp_halt_endpoint(pdev, &pdev->eps[0], 0); ++ if (pep->ep_state & EP_HALTED) { ++ if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_HALTED) ++ cdnsp_halt_endpoint(pdev, pep, 0); ++ ++ /* ++ * Halt Endpoint Command for SSP2 for ep0 preserve current ++ * endpoint state and driver has to synchronize the ++ * software endpoint state with endpoint output context ++ * state. ++ */ ++ pep->ep_state &= ~EP_HALTED; ++ pep->ep_state |= EP_STOPPED; + } + + /* +diff --git a/drivers/usb/cdns3/cdnsp-gadget.h b/drivers/usb/cdns3/cdnsp-gadget.h +index 48336e121ed6f..155fd770a8cd9 100644 +--- a/drivers/usb/cdns3/cdnsp-gadget.h ++++ b/drivers/usb/cdns3/cdnsp-gadget.h +@@ -987,6 +987,12 @@ enum cdnsp_setup_dev { + #define STREAM_ID_FOR_TRB(p) ((((p)) << 16) & GENMASK(31, 16)) + #define SCT_FOR_TRB(p) (((p) << 1) & 0x7) + ++/* ++ * Halt Endpoint Command TRB field. ++ * The ESP bit only exists in the SSP2 controller. ++ */ ++#define TRB_ESP BIT(9) ++ + /* Link TRB specific fields. */ + #define TRB_TC BIT(1) + +diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c +index 795668435c77e..42db256978bcc 100644 +--- a/drivers/usb/cdns3/cdnsp-ring.c ++++ b/drivers/usb/cdns3/cdnsp-ring.c +@@ -2475,7 +2475,8 @@ void cdnsp_queue_halt_endpoint(struct cdnsp_device *pdev, unsigned int ep_index) + { + cdnsp_queue_command(pdev, 0, 0, 0, TRB_TYPE(TRB_HALT_ENDPOINT) | + SLOT_ID_FOR_TRB(pdev->slot_id) | +- EP_ID_FOR_TRB(ep_index)); ++ EP_ID_FOR_TRB(ep_index) | ++ (!ep_index ? TRB_ESP : 0)); + } + + void cdnsp_force_header_wakeup(struct cdnsp_device *pdev, int intf_num) +-- +2.39.5 + diff --git a/queue-5.15/usb-cdnsp-remove-trb_flush_endpoint-command.patch b/queue-5.15/usb-cdnsp-remove-trb_flush_endpoint-command.patch new file mode 100644 index 0000000000..65c4f194bc --- /dev/null +++ b/queue-5.15/usb-cdnsp-remove-trb_flush_endpoint-command.patch @@ -0,0 +1,147 @@ +From 82ed8d1a525cd63dd32a41d3a5dc387314ca8dc2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 09:37:37 +0200 +Subject: usb:cdnsp: remove TRB_FLUSH_ENDPOINT command + +From: Pawel Laszczak + +[ Upstream commit 2998874736bca1031ca84b0a3235a2cd09dfa426 ] + +Patch removes TRB_FLUSH_ENDPOINT command from driver. +This command is not supported by controller and +USBSSP returns TRB Error completion code for it. + +Signed-off-by: Pawel Laszczak +Acked-by: Peter Chen +Link: https://lore.kernel.org/r/20231026073737.165450-1-pawell@cadence.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 2831a81077f5 ("usb: cdnsp: Fix issue with CV Bad Descriptor test") +Signed-off-by: Sasha Levin +--- + drivers/usb/cdns3/cdnsp-debug.h | 3 --- + drivers/usb/cdns3/cdnsp-gadget.c | 6 +----- + drivers/usb/cdns3/cdnsp-gadget.h | 5 ----- + drivers/usb/cdns3/cdnsp-ring.c | 24 ------------------------ + 4 files changed, 1 insertion(+), 37 deletions(-) + +diff --git a/drivers/usb/cdns3/cdnsp-debug.h b/drivers/usb/cdns3/cdnsp-debug.h +index f0ca865cce2a0..ad617b7455b9c 100644 +--- a/drivers/usb/cdns3/cdnsp-debug.h ++++ b/drivers/usb/cdns3/cdnsp-debug.h +@@ -131,8 +131,6 @@ static inline const char *cdnsp_trb_type_string(u8 type) + return "Endpoint Not ready"; + case TRB_HALT_ENDPOINT: + return "Halt Endpoint"; +- case TRB_FLUSH_ENDPOINT: +- return "FLush Endpoint"; + default: + return "UNKNOWN"; + } +@@ -328,7 +326,6 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0, + break; + case TRB_RESET_EP: + case TRB_HALT_ENDPOINT: +- case TRB_FLUSH_ENDPOINT: + ret = snprintf(str, size, + "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c", + cdnsp_trb_type_string(type), +diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c +index 1e9aee824eb7d..1de82fb9dcb48 100644 +--- a/drivers/usb/cdns3/cdnsp-gadget.c ++++ b/drivers/usb/cdns3/cdnsp-gadget.c +@@ -1061,10 +1061,8 @@ static int cdnsp_gadget_ep_disable(struct usb_ep *ep) + pep->ep_state |= EP_DIS_IN_RROGRESS; + + /* Endpoint was unconfigured by Reset Device command. */ +- if (!(pep->ep_state & EP_UNCONFIGURED)) { ++ if (!(pep->ep_state & EP_UNCONFIGURED)) + cdnsp_cmd_stop_ep(pdev, pep); +- cdnsp_cmd_flush_ep(pdev, pep); +- } + + /* Remove all queued USB requests. */ + while (!list_empty(&pep->pending_list)) { +@@ -1464,8 +1462,6 @@ static void cdnsp_stop(struct cdnsp_device *pdev) + { + u32 temp; + +- cdnsp_cmd_flush_ep(pdev, &pdev->eps[0]); +- + /* Remove internally queued request for ep0. */ + if (!list_empty(&pdev->eps[0].pending_list)) { + struct cdnsp_request *req; +diff --git a/drivers/usb/cdns3/cdnsp-gadget.h b/drivers/usb/cdns3/cdnsp-gadget.h +index 2998548177aba..48336e121ed6f 100644 +--- a/drivers/usb/cdns3/cdnsp-gadget.h ++++ b/drivers/usb/cdns3/cdnsp-gadget.h +@@ -1138,8 +1138,6 @@ union cdnsp_trb { + #define TRB_HALT_ENDPOINT 54 + /* Doorbell Overflow Event. */ + #define TRB_DRB_OVERFLOW 57 +-/* Flush Endpoint Command. */ +-#define TRB_FLUSH_ENDPOINT 58 + + #define TRB_TYPE_LINK(x) (((x) & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK)) + #define TRB_TYPE_LINK_LE32(x) (((x) & cpu_to_le32(TRB_TYPE_BITMASK)) == \ +@@ -1552,8 +1550,6 @@ void cdnsp_queue_configure_endpoint(struct cdnsp_device *pdev, + void cdnsp_queue_reset_ep(struct cdnsp_device *pdev, unsigned int ep_index); + void cdnsp_queue_halt_endpoint(struct cdnsp_device *pdev, + unsigned int ep_index); +-void cdnsp_queue_flush_endpoint(struct cdnsp_device *pdev, +- unsigned int ep_index); + void cdnsp_force_header_wakeup(struct cdnsp_device *pdev, int intf_num); + void cdnsp_queue_reset_device(struct cdnsp_device *pdev); + void cdnsp_queue_new_dequeue_state(struct cdnsp_device *pdev, +@@ -1587,7 +1583,6 @@ void cdnsp_irq_reset(struct cdnsp_device *pdev); + int cdnsp_halt_endpoint(struct cdnsp_device *pdev, + struct cdnsp_ep *pep, int value); + int cdnsp_cmd_stop_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep); +-int cdnsp_cmd_flush_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep); + void cdnsp_setup_analyze(struct cdnsp_device *pdev); + int cdnsp_status_stage(struct cdnsp_device *pdev); + int cdnsp_reset_device(struct cdnsp_device *pdev); +diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c +index c9ad4280f4ba2..795668435c77e 100644 +--- a/drivers/usb/cdns3/cdnsp-ring.c ++++ b/drivers/usb/cdns3/cdnsp-ring.c +@@ -2157,19 +2157,6 @@ int cdnsp_cmd_stop_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep) + return ret; + } + +-int cdnsp_cmd_flush_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep) +-{ +- int ret; +- +- cdnsp_queue_flush_endpoint(pdev, pep->idx); +- cdnsp_ring_cmd_db(pdev); +- ret = cdnsp_wait_for_cmd_compl(pdev); +- +- trace_cdnsp_handle_cmd_flush_ep(pep->out_ctx); +- +- return ret; +-} +- + /* + * The transfer burst count field of the isochronous TRB defines the number of + * bursts that are required to move all packets in this TD. Only SuperSpeed +@@ -2491,17 +2478,6 @@ void cdnsp_queue_halt_endpoint(struct cdnsp_device *pdev, unsigned int ep_index) + EP_ID_FOR_TRB(ep_index)); + } + +-/* +- * Queue a flush endpoint request on the command ring. +- */ +-void cdnsp_queue_flush_endpoint(struct cdnsp_device *pdev, +- unsigned int ep_index) +-{ +- cdnsp_queue_command(pdev, 0, 0, 0, TRB_TYPE(TRB_FLUSH_ENDPOINT) | +- SLOT_ID_FOR_TRB(pdev->slot_id) | +- EP_ID_FOR_TRB(ep_index)); +-} +- + void cdnsp_force_header_wakeup(struct cdnsp_device *pdev, int intf_num) + { + u32 lo, mid; +-- +2.39.5 + diff --git a/queue-5.15/usb-cdnsp-replace-snprintf-with-the-safer-scnprintf-.patch b/queue-5.15/usb-cdnsp-replace-snprintf-with-the-safer-scnprintf-.patch new file mode 100644 index 0000000000..ab45595b37 --- /dev/null +++ b/queue-5.15/usb-cdnsp-replace-snprintf-with-the-safer-scnprintf-.patch @@ -0,0 +1,475 @@ +From 4954a3a5374321b4c7c9d0125e6b4f2575d03e77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Nov 2023 10:54:36 +0000 +Subject: usb: cdnsp: Replace snprintf() with the safer scnprintf() variant + +From: Lee Jones + +[ Upstream commit b385ef088c7aab20a2c0dc20d390d69a6620f0f3 ] + +There is a general misunderstanding amongst engineers that {v}snprintf() +returns the length of the data *actually* encoded into the destination +array. However, as per the C99 standard {v}snprintf() really returns +the length of the data that *would have been* written if there were +enough space for it. This misunderstanding has led to buffer-overruns +in the past. It's generally considered safer to use the {v}scnprintf() +variants in their place (or even sprintf() in simple cases). So let's +do that. + +The uses in this file all seem to assume that data *has been* written! + +Link: https://lwn.net/Articles/69419/ +Link: https://github.com/KSPP/linux/issues/105 +Cc: Pawel Laszczak +Cc: Greg Kroah-Hartman +Cc: linux-usb@vger.kernel.org +Signed-off-by: Lee Jones +Link: https://lore.kernel.org/r/20231130105459.3208986-3-lee@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 2831a81077f5 ("usb: cdnsp: Fix issue with CV Bad Descriptor test") +Signed-off-by: Sasha Levin +--- + drivers/usb/cdns3/cdnsp-debug.h | 354 ++++++++++++++++---------------- + 1 file changed, 177 insertions(+), 177 deletions(-) + +diff --git a/drivers/usb/cdns3/cdnsp-debug.h b/drivers/usb/cdns3/cdnsp-debug.h +index ad617b7455b9c..cd138acdcce16 100644 +--- a/drivers/usb/cdns3/cdnsp-debug.h ++++ b/drivers/usb/cdns3/cdnsp-debug.h +@@ -187,202 +187,202 @@ static inline const char *cdnsp_decode_trb(char *str, size_t size, u32 field0, + + switch (type) { + case TRB_LINK: +- ret = snprintf(str, size, +- "LINK %08x%08x intr %ld type '%s' flags %c:%c:%c:%c", +- field1, field0, GET_INTR_TARGET(field2), +- cdnsp_trb_type_string(type), +- field3 & TRB_IOC ? 'I' : 'i', +- field3 & TRB_CHAIN ? 'C' : 'c', +- field3 & TRB_TC ? 'T' : 't', +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "LINK %08x%08x intr %ld type '%s' flags %c:%c:%c:%c", ++ field1, field0, GET_INTR_TARGET(field2), ++ cdnsp_trb_type_string(type), ++ field3 & TRB_IOC ? 'I' : 'i', ++ field3 & TRB_CHAIN ? 'C' : 'c', ++ field3 & TRB_TC ? 'T' : 't', ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_TRANSFER: + case TRB_COMPLETION: + case TRB_PORT_STATUS: + case TRB_HC_EVENT: +- ret = snprintf(str, size, +- "ep%d%s(%d) type '%s' TRB %08x%08x status '%s'" +- " len %ld slot %ld flags %c:%c", +- ep_num, ep_id % 2 ? "out" : "in", +- TRB_TO_EP_INDEX(field3), +- cdnsp_trb_type_string(type), field1, field0, +- cdnsp_trb_comp_code_string(GET_COMP_CODE(field2)), +- EVENT_TRB_LEN(field2), TRB_TO_SLOT_ID(field3), +- field3 & EVENT_DATA ? 'E' : 'e', +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "ep%d%s(%d) type '%s' TRB %08x%08x status '%s'" ++ " len %ld slot %ld flags %c:%c", ++ ep_num, ep_id % 2 ? "out" : "in", ++ TRB_TO_EP_INDEX(field3), ++ cdnsp_trb_type_string(type), field1, field0, ++ cdnsp_trb_comp_code_string(GET_COMP_CODE(field2)), ++ EVENT_TRB_LEN(field2), TRB_TO_SLOT_ID(field3), ++ field3 & EVENT_DATA ? 'E' : 'e', ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_MFINDEX_WRAP: +- ret = snprintf(str, size, "%s: flags %c", +- cdnsp_trb_type_string(type), +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, "%s: flags %c", ++ cdnsp_trb_type_string(type), ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_SETUP: +- ret = snprintf(str, size, +- "type '%s' bRequestType %02x bRequest %02x " +- "wValue %02x%02x wIndex %02x%02x wLength %d " +- "length %ld TD size %ld intr %ld Setup ID %ld " +- "flags %c:%c:%c", +- cdnsp_trb_type_string(type), +- field0 & 0xff, +- (field0 & 0xff00) >> 8, +- (field0 & 0xff000000) >> 24, +- (field0 & 0xff0000) >> 16, +- (field1 & 0xff00) >> 8, +- field1 & 0xff, +- (field1 & 0xff000000) >> 16 | +- (field1 & 0xff0000) >> 16, +- TRB_LEN(field2), GET_TD_SIZE(field2), +- GET_INTR_TARGET(field2), +- TRB_SETUPID_TO_TYPE(field3), +- field3 & TRB_IDT ? 'D' : 'd', +- field3 & TRB_IOC ? 'I' : 'i', +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "type '%s' bRequestType %02x bRequest %02x " ++ "wValue %02x%02x wIndex %02x%02x wLength %d " ++ "length %ld TD size %ld intr %ld Setup ID %ld " ++ "flags %c:%c:%c", ++ cdnsp_trb_type_string(type), ++ field0 & 0xff, ++ (field0 & 0xff00) >> 8, ++ (field0 & 0xff000000) >> 24, ++ (field0 & 0xff0000) >> 16, ++ (field1 & 0xff00) >> 8, ++ field1 & 0xff, ++ (field1 & 0xff000000) >> 16 | ++ (field1 & 0xff0000) >> 16, ++ TRB_LEN(field2), GET_TD_SIZE(field2), ++ GET_INTR_TARGET(field2), ++ TRB_SETUPID_TO_TYPE(field3), ++ field3 & TRB_IDT ? 'D' : 'd', ++ field3 & TRB_IOC ? 'I' : 'i', ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_DATA: +- ret = snprintf(str, size, +- "type '%s' Buffer %08x%08x length %ld TD size %ld " +- "intr %ld flags %c:%c:%c:%c:%c:%c:%c", +- cdnsp_trb_type_string(type), +- field1, field0, TRB_LEN(field2), +- GET_TD_SIZE(field2), +- GET_INTR_TARGET(field2), +- field3 & TRB_IDT ? 'D' : 'i', +- field3 & TRB_IOC ? 'I' : 'i', +- field3 & TRB_CHAIN ? 'C' : 'c', +- field3 & TRB_NO_SNOOP ? 'S' : 's', +- field3 & TRB_ISP ? 'I' : 'i', +- field3 & TRB_ENT ? 'E' : 'e', +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "type '%s' Buffer %08x%08x length %ld TD size %ld " ++ "intr %ld flags %c:%c:%c:%c:%c:%c:%c", ++ cdnsp_trb_type_string(type), ++ field1, field0, TRB_LEN(field2), ++ GET_TD_SIZE(field2), ++ GET_INTR_TARGET(field2), ++ field3 & TRB_IDT ? 'D' : 'i', ++ field3 & TRB_IOC ? 'I' : 'i', ++ field3 & TRB_CHAIN ? 'C' : 'c', ++ field3 & TRB_NO_SNOOP ? 'S' : 's', ++ field3 & TRB_ISP ? 'I' : 'i', ++ field3 & TRB_ENT ? 'E' : 'e', ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_STATUS: +- ret = snprintf(str, size, +- "Buffer %08x%08x length %ld TD size %ld intr" +- "%ld type '%s' flags %c:%c:%c:%c", +- field1, field0, TRB_LEN(field2), +- GET_TD_SIZE(field2), +- GET_INTR_TARGET(field2), +- cdnsp_trb_type_string(type), +- field3 & TRB_IOC ? 'I' : 'i', +- field3 & TRB_CHAIN ? 'C' : 'c', +- field3 & TRB_ENT ? 'E' : 'e', +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "Buffer %08x%08x length %ld TD size %ld intr" ++ "%ld type '%s' flags %c:%c:%c:%c", ++ field1, field0, TRB_LEN(field2), ++ GET_TD_SIZE(field2), ++ GET_INTR_TARGET(field2), ++ cdnsp_trb_type_string(type), ++ field3 & TRB_IOC ? 'I' : 'i', ++ field3 & TRB_CHAIN ? 'C' : 'c', ++ field3 & TRB_ENT ? 'E' : 'e', ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_NORMAL: + case TRB_ISOC: + case TRB_EVENT_DATA: + case TRB_TR_NOOP: +- ret = snprintf(str, size, +- "type '%s' Buffer %08x%08x length %ld " +- "TD size %ld intr %ld " +- "flags %c:%c:%c:%c:%c:%c:%c:%c:%c", +- cdnsp_trb_type_string(type), +- field1, field0, TRB_LEN(field2), +- GET_TD_SIZE(field2), +- GET_INTR_TARGET(field2), +- field3 & TRB_BEI ? 'B' : 'b', +- field3 & TRB_IDT ? 'T' : 't', +- field3 & TRB_IOC ? 'I' : 'i', +- field3 & TRB_CHAIN ? 'C' : 'c', +- field3 & TRB_NO_SNOOP ? 'S' : 's', +- field3 & TRB_ISP ? 'I' : 'i', +- field3 & TRB_ENT ? 'E' : 'e', +- field3 & TRB_CYCLE ? 'C' : 'c', +- !(field3 & TRB_EVENT_INVALIDATE) ? 'V' : 'v'); ++ ret = scnprintf(str, size, ++ "type '%s' Buffer %08x%08x length %ld " ++ "TD size %ld intr %ld " ++ "flags %c:%c:%c:%c:%c:%c:%c:%c:%c", ++ cdnsp_trb_type_string(type), ++ field1, field0, TRB_LEN(field2), ++ GET_TD_SIZE(field2), ++ GET_INTR_TARGET(field2), ++ field3 & TRB_BEI ? 'B' : 'b', ++ field3 & TRB_IDT ? 'T' : 't', ++ field3 & TRB_IOC ? 'I' : 'i', ++ field3 & TRB_CHAIN ? 'C' : 'c', ++ field3 & TRB_NO_SNOOP ? 'S' : 's', ++ field3 & TRB_ISP ? 'I' : 'i', ++ field3 & TRB_ENT ? 'E' : 'e', ++ field3 & TRB_CYCLE ? 'C' : 'c', ++ !(field3 & TRB_EVENT_INVALIDATE) ? 'V' : 'v'); + break; + case TRB_CMD_NOOP: + case TRB_ENABLE_SLOT: +- ret = snprintf(str, size, "%s: flags %c", +- cdnsp_trb_type_string(type), +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, "%s: flags %c", ++ cdnsp_trb_type_string(type), ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_DISABLE_SLOT: +- ret = snprintf(str, size, "%s: slot %ld flags %c", +- cdnsp_trb_type_string(type), +- TRB_TO_SLOT_ID(field3), +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, "%s: slot %ld flags %c", ++ cdnsp_trb_type_string(type), ++ TRB_TO_SLOT_ID(field3), ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_ADDR_DEV: +- ret = snprintf(str, size, +- "%s: ctx %08x%08x slot %ld flags %c:%c", +- cdnsp_trb_type_string(type), field1, field0, +- TRB_TO_SLOT_ID(field3), +- field3 & TRB_BSR ? 'B' : 'b', +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "%s: ctx %08x%08x slot %ld flags %c:%c", ++ cdnsp_trb_type_string(type), field1, field0, ++ TRB_TO_SLOT_ID(field3), ++ field3 & TRB_BSR ? 'B' : 'b', ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_CONFIG_EP: +- ret = snprintf(str, size, +- "%s: ctx %08x%08x slot %ld flags %c:%c", +- cdnsp_trb_type_string(type), field1, field0, +- TRB_TO_SLOT_ID(field3), +- field3 & TRB_DC ? 'D' : 'd', +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "%s: ctx %08x%08x slot %ld flags %c:%c", ++ cdnsp_trb_type_string(type), field1, field0, ++ TRB_TO_SLOT_ID(field3), ++ field3 & TRB_DC ? 'D' : 'd', ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_EVAL_CONTEXT: +- ret = snprintf(str, size, +- "%s: ctx %08x%08x slot %ld flags %c", +- cdnsp_trb_type_string(type), field1, field0, +- TRB_TO_SLOT_ID(field3), +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "%s: ctx %08x%08x slot %ld flags %c", ++ cdnsp_trb_type_string(type), field1, field0, ++ TRB_TO_SLOT_ID(field3), ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_RESET_EP: + case TRB_HALT_ENDPOINT: +- ret = snprintf(str, size, +- "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c", +- cdnsp_trb_type_string(type), +- ep_num, ep_id % 2 ? "out" : "in", +- TRB_TO_EP_INDEX(field3), field1, field0, +- TRB_TO_SLOT_ID(field3), +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "%s: ep%d%s(%d) ctx %08x%08x slot %ld flags %c", ++ cdnsp_trb_type_string(type), ++ ep_num, ep_id % 2 ? "out" : "in", ++ TRB_TO_EP_INDEX(field3), field1, field0, ++ TRB_TO_SLOT_ID(field3), ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_STOP_RING: +- ret = snprintf(str, size, +- "%s: ep%d%s(%d) slot %ld sp %d flags %c", +- cdnsp_trb_type_string(type), +- ep_num, ep_id % 2 ? "out" : "in", +- TRB_TO_EP_INDEX(field3), +- TRB_TO_SLOT_ID(field3), +- TRB_TO_SUSPEND_PORT(field3), +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "%s: ep%d%s(%d) slot %ld sp %d flags %c", ++ cdnsp_trb_type_string(type), ++ ep_num, ep_id % 2 ? "out" : "in", ++ TRB_TO_EP_INDEX(field3), ++ TRB_TO_SLOT_ID(field3), ++ TRB_TO_SUSPEND_PORT(field3), ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_SET_DEQ: +- ret = snprintf(str, size, +- "%s: ep%d%s(%d) deq %08x%08x stream %ld slot %ld flags %c", +- cdnsp_trb_type_string(type), +- ep_num, ep_id % 2 ? "out" : "in", +- TRB_TO_EP_INDEX(field3), field1, field0, +- TRB_TO_STREAM_ID(field2), +- TRB_TO_SLOT_ID(field3), +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "%s: ep%d%s(%d) deq %08x%08x stream %ld slot %ld flags %c", ++ cdnsp_trb_type_string(type), ++ ep_num, ep_id % 2 ? "out" : "in", ++ TRB_TO_EP_INDEX(field3), field1, field0, ++ TRB_TO_STREAM_ID(field2), ++ TRB_TO_SLOT_ID(field3), ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_RESET_DEV: +- ret = snprintf(str, size, "%s: slot %ld flags %c", +- cdnsp_trb_type_string(type), +- TRB_TO_SLOT_ID(field3), +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, "%s: slot %ld flags %c", ++ cdnsp_trb_type_string(type), ++ TRB_TO_SLOT_ID(field3), ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + case TRB_ENDPOINT_NRDY: + temp = TRB_TO_HOST_STREAM(field2); + +- ret = snprintf(str, size, +- "%s: ep%d%s(%d) H_SID %x%s%s D_SID %lx flags %c:%c", +- cdnsp_trb_type_string(type), +- ep_num, ep_id % 2 ? "out" : "in", +- TRB_TO_EP_INDEX(field3), temp, +- temp == STREAM_PRIME_ACK ? "(PRIME)" : "", +- temp == STREAM_REJECTED ? "(REJECTED)" : "", +- TRB_TO_DEV_STREAM(field0), +- field3 & TRB_STAT ? 'S' : 's', +- field3 & TRB_CYCLE ? 'C' : 'c'); ++ ret = scnprintf(str, size, ++ "%s: ep%d%s(%d) H_SID %x%s%s D_SID %lx flags %c:%c", ++ cdnsp_trb_type_string(type), ++ ep_num, ep_id % 2 ? "out" : "in", ++ TRB_TO_EP_INDEX(field3), temp, ++ temp == STREAM_PRIME_ACK ? "(PRIME)" : "", ++ temp == STREAM_REJECTED ? "(REJECTED)" : "", ++ TRB_TO_DEV_STREAM(field0), ++ field3 & TRB_STAT ? 'S' : 's', ++ field3 & TRB_CYCLE ? 'C' : 'c'); + break; + default: +- ret = snprintf(str, size, +- "type '%s' -> raw %08x %08x %08x %08x", +- cdnsp_trb_type_string(type), +- field0, field1, field2, field3); ++ ret = scnprintf(str, size, ++ "type '%s' -> raw %08x %08x %08x %08x", ++ cdnsp_trb_type_string(type), ++ field0, field1, field2, field3); + } + +- if (ret >= size) +- pr_info("CDNSP: buffer overflowed.\n"); ++ if (ret == size - 1) ++ pr_info("CDNSP: buffer may be truncated.\n"); + + return str; + } +@@ -465,32 +465,32 @@ static inline const char *cdnsp_decode_portsc(char *str, size_t size, + { + int ret; + +- ret = snprintf(str, size, "%s %s %s Link:%s PortSpeed:%d ", +- portsc & PORT_POWER ? "Powered" : "Powered-off", +- portsc & PORT_CONNECT ? "Connected" : "Not-connected", +- portsc & PORT_PED ? "Enabled" : "Disabled", +- cdnsp_portsc_link_state_string(portsc), +- DEV_PORT_SPEED(portsc)); ++ ret = scnprintf(str, size, "%s %s %s Link:%s PortSpeed:%d ", ++ portsc & PORT_POWER ? "Powered" : "Powered-off", ++ portsc & PORT_CONNECT ? "Connected" : "Not-connected", ++ portsc & PORT_PED ? "Enabled" : "Disabled", ++ cdnsp_portsc_link_state_string(portsc), ++ DEV_PORT_SPEED(portsc)); + + if (portsc & PORT_RESET) +- ret += snprintf(str + ret, size - ret, "In-Reset "); ++ ret += scnprintf(str + ret, size - ret, "In-Reset "); + +- ret += snprintf(str + ret, size - ret, "Change: "); ++ ret += scnprintf(str + ret, size - ret, "Change: "); + if (portsc & PORT_CSC) +- ret += snprintf(str + ret, size - ret, "CSC "); ++ ret += scnprintf(str + ret, size - ret, "CSC "); + if (portsc & PORT_WRC) +- ret += snprintf(str + ret, size - ret, "WRC "); ++ ret += scnprintf(str + ret, size - ret, "WRC "); + if (portsc & PORT_RC) +- ret += snprintf(str + ret, size - ret, "PRC "); ++ ret += scnprintf(str + ret, size - ret, "PRC "); + if (portsc & PORT_PLC) +- ret += snprintf(str + ret, size - ret, "PLC "); ++ ret += scnprintf(str + ret, size - ret, "PLC "); + if (portsc & PORT_CEC) +- ret += snprintf(str + ret, size - ret, "CEC "); +- ret += snprintf(str + ret, size - ret, "Wake: "); ++ ret += scnprintf(str + ret, size - ret, "CEC "); ++ ret += scnprintf(str + ret, size - ret, "Wake: "); + if (portsc & PORT_WKCONN_E) +- ret += snprintf(str + ret, size - ret, "WCE "); ++ ret += scnprintf(str + ret, size - ret, "WCE "); + if (portsc & PORT_WKDISC_E) +- ret += snprintf(str + ret, size - ret, "WDE "); ++ ret += scnprintf(str + ret, size - ret, "WDE "); + + return str; + } +@@ -562,20 +562,20 @@ static inline const char *cdnsp_decode_ep_context(char *str, size_t size, + + avg = EP_AVG_TRB_LENGTH(tx_info); + +- ret = snprintf(str, size, "State %s mult %d max P. Streams %d %s", +- cdnsp_ep_state_string(ep_state), mult, +- max_pstr, lsa ? "LSA " : ""); ++ ret = scnprintf(str, size, "State %s mult %d max P. Streams %d %s", ++ cdnsp_ep_state_string(ep_state), mult, ++ max_pstr, lsa ? "LSA " : ""); + +- ret += snprintf(str + ret, size - ret, +- "interval %d us max ESIT payload %d CErr %d ", +- (1 << interval) * 125, esit, cerr); ++ ret += scnprintf(str + ret, size - ret, ++ "interval %d us max ESIT payload %d CErr %d ", ++ (1 << interval) * 125, esit, cerr); + +- ret += snprintf(str + ret, size - ret, +- "Type %s %sburst %d maxp %d deq %016llx ", +- cdnsp_ep_type_string(ep_type), hid ? "HID" : "", +- burst, maxp, deq); ++ ret += scnprintf(str + ret, size - ret, ++ "Type %s %sburst %d maxp %d deq %016llx ", ++ cdnsp_ep_type_string(ep_type), hid ? "HID" : "", ++ burst, maxp, deq); + +- ret += snprintf(str + ret, size - ret, "avg trb len %d", avg); ++ ret += scnprintf(str + ret, size - ret, "avg trb len %d", avg); + + return str; + } +-- +2.39.5 + diff --git a/queue-5.15/usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch b/queue-5.15/usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch new file mode 100644 index 0000000000..e22e7f6feb --- /dev/null +++ b/queue-5.15/usb-dwc3-abort-suspend-on-soft-disconnect-failure.patch @@ -0,0 +1,108 @@ +From 189e3511c1047aed0141cb54e588a6c33fd7ecac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 May 2025 18:03:11 +0800 +Subject: usb: dwc3: Abort suspend on soft disconnect failure + +From: Kuen-Han Tsai + +[ Upstream commit 630a1dec3b0eba2a695b9063f1c205d585cbfec9 ] + +When dwc3_gadget_soft_disconnect() fails, dwc3_suspend_common() keeps +going with the suspend, resulting in a period where the power domain is +off, but the gadget driver remains connected. Within this time frame, +invoking vbus_event_work() will cause an error as it attempts to access +DWC3 registers for endpoint disabling after the power domain has been +completely shut down. + +Abort the suspend sequence when dwc3_gadget_suspend() cannot halt the +controller and proceeds with a soft connect. + +Fixes: 9f8a67b65a49 ("usb: dwc3: gadget: fix gadget suspend/resume") +Cc: stable +Acked-by: Thinh Nguyen +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250528100315.2162699-1-khtsai@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc3/core.c | 9 +++++++-- + drivers/usb/dwc3/gadget.c | 22 +++++++++------------- + 2 files changed, 16 insertions(+), 15 deletions(-) + +diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c +index bb20d8dd18791..488cb16acd67e 100644 +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -1818,6 +1818,7 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc) + static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) + { + u32 reg; ++ int ret; + + if (!pm_runtime_suspended(dwc->dev) && !PMSG_IS_AUTO(msg)) { + dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) & +@@ -1836,7 +1837,9 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) + case DWC3_GCTL_PRTCAP_DEVICE: + if (pm_runtime_suspended(dwc->dev)) + break; +- dwc3_gadget_suspend(dwc); ++ ret = dwc3_gadget_suspend(dwc); ++ if (ret) ++ return ret; + synchronize_irq(dwc->irq_gadget); + dwc3_core_exit(dwc); + break; +@@ -1867,7 +1870,9 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) + break; + + if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) { +- dwc3_gadget_suspend(dwc); ++ ret = dwc3_gadget_suspend(dwc); ++ if (ret) ++ return ret; + synchronize_irq(dwc->irq_gadget); + } + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index a99e669468ee3..44bb3770f8bb2 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -4580,26 +4580,22 @@ int dwc3_gadget_suspend(struct dwc3 *dwc) + int ret; + + ret = dwc3_gadget_soft_disconnect(dwc); +- if (ret) +- goto err; +- +- spin_lock_irqsave(&dwc->lock, flags); +- if (dwc->gadget_driver) +- dwc3_disconnect_gadget(dwc); +- spin_unlock_irqrestore(&dwc->lock, flags); +- +- return 0; +- +-err: + /* + * Attempt to reset the controller's state. Likely no + * communication can be established until the host + * performs a port reset. + */ +- if (dwc->softconnect) ++ if (ret && dwc->softconnect) { + dwc3_gadget_soft_connect(dwc); ++ return -EAGAIN; ++ } + +- return ret; ++ spin_lock_irqsave(&dwc->lock, flags); ++ if (dwc->gadget_driver) ++ dwc3_disconnect_gadget(dwc); ++ spin_unlock_irqrestore(&dwc->lock, flags); ++ ++ return 0; + } + + int dwc3_gadget_resume(struct dwc3 *dwc) +-- +2.39.5 + diff --git a/queue-5.15/usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch b/queue-5.15/usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch new file mode 100644 index 0000000000..5d011840d6 --- /dev/null +++ b/queue-5.15/usb-xhci-quirk-for-data-loss-in-isoc-transfers.patch @@ -0,0 +1,120 @@ +From cd7487d6ce9a0122a9ed241cfc2166a9f5c950b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Jun 2025 17:41:19 +0300 +Subject: usb: xhci: quirk for data loss in ISOC transfers + +From: Raju Rangoju + +[ Upstream commit cbc889ab0122366f6cdbe3c28d477c683ebcebc2 ] + +During the High-Speed Isochronous Audio transfers, xHCI +controller on certain AMD platforms experiences momentary data +loss. This results in Missed Service Errors (MSE) being +generated by the xHCI. + +The root cause of the MSE is attributed to the ISOC OUT endpoint +being omitted from scheduling. This can happen when an IN +endpoint with a 64ms service interval either is pre-scheduled +prior to the ISOC OUT endpoint or the interval of the ISOC OUT +endpoint is shorter than that of the IN endpoint. Consequently, +the OUT service is neglected when an IN endpoint with a service +interval exceeding 32ms is scheduled concurrently (every 64ms in +this scenario). + +This issue is particularly seen on certain older AMD platforms. +To mitigate this problem, it is recommended to adjust the service +interval of the IN endpoint to not exceed 32ms (interval 8). This +adjustment ensures that the OUT endpoint will not be bypassed, +even if a smaller interval value is utilized. + +Cc: stable +Signed-off-by: Raju Rangoju +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250627144127.3889714-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-mem.c | 4 ++++ + drivers/usb/host/xhci-pci.c | 25 +++++++++++++++++++++++++ + drivers/usb/host/xhci.h | 1 + + 3 files changed, 30 insertions(+) + +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index db22ab0d88893..149128b89100b 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1462,6 +1462,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, + /* Periodic endpoint bInterval limit quirk */ + if (usb_endpoint_xfer_int(&ep->desc) || + usb_endpoint_xfer_isoc(&ep->desc)) { ++ if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_9) && ++ interval >= 9) { ++ interval = 8; ++ } + if ((xhci->quirks & XHCI_LIMIT_ENDPOINT_INTERVAL_7) && + udev->speed >= USB_SPEED_HIGH && + interval >= 7) { +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index 5c46e85cc2d7c..9c7491ac28f2f 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -65,12 +65,22 @@ + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed + #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI 0x54ed + ++#define PCI_DEVICE_ID_AMD_ARIEL_TYPEC_XHCI 0x13ed ++#define PCI_DEVICE_ID_AMD_ARIEL_TYPEA_XHCI 0x13ee ++#define PCI_DEVICE_ID_AMD_STARSHIP_XHCI 0x148c ++#define PCI_DEVICE_ID_AMD_FIREFLIGHT_15D4_XHCI 0x15d4 ++#define PCI_DEVICE_ID_AMD_FIREFLIGHT_15D5_XHCI 0x15d5 ++#define PCI_DEVICE_ID_AMD_RAVEN_15E0_XHCI 0x15e0 ++#define PCI_DEVICE_ID_AMD_RAVEN_15E1_XHCI 0x15e1 ++#define PCI_DEVICE_ID_AMD_RAVEN2_XHCI 0x15e5 + #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 + #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 + #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba + #define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb + #define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc + ++#define PCI_DEVICE_ID_ATI_NAVI10_7316_XHCI 0x7316 ++ + #define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042 + #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 + #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 +@@ -168,6 +178,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + if (pdev->vendor == PCI_VENDOR_ID_NEC) + xhci->quirks |= XHCI_NEC_HOST; + ++ if (pdev->vendor == PCI_VENDOR_ID_AMD && ++ (pdev->device == PCI_DEVICE_ID_AMD_ARIEL_TYPEC_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_ARIEL_TYPEA_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_STARSHIP_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_FIREFLIGHT_15D4_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_FIREFLIGHT_15D5_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_RAVEN_15E0_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_RAVEN_15E1_XHCI || ++ pdev->device == PCI_DEVICE_ID_AMD_RAVEN2_XHCI)) ++ xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_9; ++ ++ if (pdev->vendor == PCI_VENDOR_ID_ATI && ++ pdev->device == PCI_DEVICE_ID_ATI_NAVI10_7316_XHCI) ++ xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_9; ++ + if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version == 0x96) + xhci->quirks |= XHCI_AMD_0x96_HOST; + +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index b71e02ed9f0b3..cc332de73d813 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1669,6 +1669,7 @@ struct xhci_hcd { + #define XHCI_ZHAOXIN_HOST BIT_ULL(46) + #define XHCI_WRITE_64_HI_LO BIT_ULL(47) + #define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48) ++#define XHCI_LIMIT_ENDPOINT_INTERVAL_9 BIT_ULL(49) + + unsigned int num_active_eps; + unsigned int limit_active_eps; +-- +2.39.5 + diff --git a/queue-5.15/virtio-net-ensure-the-received-length-does-not-excee.patch b/queue-5.15/virtio-net-ensure-the-received-length-does-not-excee.patch new file mode 100644 index 0000000000..58443b6ef4 --- /dev/null +++ b/queue-5.15/virtio-net-ensure-the-received-length-does-not-excee.patch @@ -0,0 +1,130 @@ +From 29f104243e7d9ed9bd19f2ff75ed1127c3b0dec4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 11 Jul 2025 23:52:02 -0400 +Subject: virtio-net: ensure the received length does not exceed allocated size + +From: Bui Quang Minh + +[ Upstream commit 315dbdd7cdf6aa533829774caaf4d25f1fd20e73 ] + +In xdp_linearize_page, when reading the following buffers from the ring, +we forget to check the received length with the true allocate size. This +can lead to an out-of-bound read. This commit adds that missing check. + +Cc: +Fixes: 4941d472bf95 ("virtio-net: do not reset during XDP set") +Signed-off-by: Bui Quang Minh +Acked-by: Jason Wang +Link: https://patch.msgid.link/20250630144212.48471-2-minhquangbui99@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/virtio_net.c | 44 ++++++++++++++++++++++++++++++++++------ + 1 file changed, 38 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index d8138ad4f865a..ed27dd5c7fc8d 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -394,6 +394,26 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx) + return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1); + } + ++static int check_mergeable_len(struct net_device *dev, void *mrg_ctx, ++ unsigned int len) ++{ ++ unsigned int headroom, tailroom, room, truesize; ++ ++ truesize = mergeable_ctx_to_truesize(mrg_ctx); ++ headroom = mergeable_ctx_to_headroom(mrg_ctx); ++ tailroom = headroom ? sizeof(struct skb_shared_info) : 0; ++ room = SKB_DATA_ALIGN(headroom + tailroom); ++ ++ if (len > truesize - room) { ++ pr_debug("%s: rx error: len %u exceeds truesize %lu\n", ++ dev->name, len, (unsigned long)(truesize - room)); ++ dev->stats.rx_length_errors++; ++ return -1; ++ } ++ ++ return 0; ++} ++ + /* Called from bottom half context */ + static struct sk_buff *page_to_skb(struct virtnet_info *vi, + struct receive_queue *rq, +@@ -672,8 +692,9 @@ static unsigned int virtnet_get_headroom(struct virtnet_info *vi) + * across multiple buffers (num_buf > 1), and we make sure buffers + * have enough headroom. + */ +-static struct page *xdp_linearize_page(struct receive_queue *rq, +- u16 *num_buf, ++static struct page *xdp_linearize_page(struct net_device *dev, ++ struct receive_queue *rq, ++ int *num_buf, + struct page *p, + int offset, + int page_off, +@@ -692,18 +713,27 @@ static struct page *xdp_linearize_page(struct receive_queue *rq, + memcpy(page_address(page) + page_off, page_address(p) + offset, *len); + page_off += *len; + ++ /* Only mergeable mode can go inside this while loop. In small mode, ++ * *num_buf == 1, so it cannot go inside. ++ */ + while (--*num_buf) { + unsigned int buflen; + void *buf; ++ void *ctx; + int off; + +- buf = virtqueue_get_buf(rq->vq, &buflen); ++ buf = virtqueue_get_buf_ctx(rq->vq, &buflen, &ctx); + if (unlikely(!buf)) + goto err_buf; + + p = virt_to_head_page(buf); + off = buf - page_address(p); + ++ if (check_mergeable_len(dev, ctx, buflen)) { ++ put_page(p); ++ goto err_buf; ++ } ++ + /* guard against a misconfigured or uncooperative backend that + * is sending packet larger than the MTU. + */ +@@ -771,14 +801,14 @@ static struct sk_buff *receive_small(struct net_device *dev, + if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) { + int offset = buf - page_address(page) + header_offset; + unsigned int tlen = len + vi->hdr_len; +- u16 num_buf = 1; ++ int num_buf = 1; + + xdp_headroom = virtnet_get_headroom(vi); + header_offset = VIRTNET_RX_PAD + xdp_headroom; + headroom = vi->hdr_len + header_offset; + buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +- xdp_page = xdp_linearize_page(rq, &num_buf, page, ++ xdp_page = xdp_linearize_page(dev, rq, &num_buf, page, + offset, header_offset, + &tlen); + if (!xdp_page) +@@ -949,10 +979,12 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, + if (unlikely(num_buf > 1 || + headroom < virtnet_get_headroom(vi))) { + /* linearize data for XDP */ +- xdp_page = xdp_linearize_page(rq, &num_buf, ++ int _num_buf = num_buf; ++ xdp_page = xdp_linearize_page(dev, rq, &_num_buf, + page, offset, + VIRTIO_XDP_HEADROOM, + &len); ++ num_buf = _num_buf; + frame_sz = PAGE_SIZE; + + if (!xdp_page) +-- +2.39.5 + diff --git a/queue-5.15/vt-add-missing-notification-when-switching-back-to-t.patch b/queue-5.15/vt-add-missing-notification-when-switching-back-to-t.patch new file mode 100644 index 0000000000..df1ccefefd --- /dev/null +++ b/queue-5.15/vt-add-missing-notification-when-switching-back-to-t.patch @@ -0,0 +1,35 @@ +From e3580b9a4b66bf0de0de8f7aad5602a9b3d9dc28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Jun 2025 21:41:44 -0400 +Subject: vt: add missing notification when switching back to text mode + +From: Nicolas Pitre + +[ Upstream commit ff78538e07fa284ce08cbbcb0730daa91ed16722 ] + +Programs using poll() on /dev/vcsa to be notified when VT changes occur +were missing one case: the switch from gfx to text mode. + +Signed-off-by: Nicolas Pitre +Link: https://lore.kernel.org/r/9o5ro928-0pp4-05rq-70p4-ro385n21n723@onlyvoer.pbz +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/vt/vt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index a6e0c803e96ec..a10b7ebbbe918 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -4443,6 +4443,7 @@ void do_unblank_screen(int leaving_gfx) + set_palette(vc); + set_cursor(vc); + vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num); ++ notify_update(vc); + } + EXPORT_SYMBOL(do_unblank_screen); + +-- +2.39.5 + diff --git a/queue-5.15/wifi-zd1211rw-fix-potential-null-pointer-dereference.patch b/queue-5.15/wifi-zd1211rw-fix-potential-null-pointer-dereference.patch new file mode 100644 index 0000000000..c02b9c28bb --- /dev/null +++ b/queue-5.15/wifi-zd1211rw-fix-potential-null-pointer-dereference.patch @@ -0,0 +1,68 @@ +From fbceddfbd77555e7275ccdc706bdc6cab867f791 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Jun 2025 14:46:19 +0300 +Subject: wifi: zd1211rw: Fix potential NULL pointer dereference in + zd_mac_tx_to_dev() + +From: Daniil Dulov + +[ Upstream commit 74b1ec9f5d627d2bdd5e5b6f3f81c23317657023 ] + +There is a potential NULL pointer dereference in zd_mac_tx_to_dev(). For +example, the following is possible: + + T0 T1 +zd_mac_tx_to_dev() + /* len == skb_queue_len(q) */ + while (len > ZD_MAC_MAX_ACK_WAITERS) { + + filter_ack() + spin_lock_irqsave(&q->lock, flags); + /* position == skb_queue_len(q) */ + for (i=1; itype == NL80211_IFTYPE_AP) + skb = __skb_dequeue(q); + spin_unlock_irqrestore(&q->lock, flags); + + skb_dequeue() -> NULL + +Since there is a small gap between checking skb queue length and skb being +unconditionally dequeued in zd_mac_tx_to_dev(), skb_dequeue() can return NULL. +Then the pointer is passed to zd_mac_tx_status() where it is dereferenced. + +In order to avoid potential NULL pointer dereference due to situations like +above, check if skb is not NULL before passing it to zd_mac_tx_status(). + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 459c51ad6e1f ("zd1211rw: port to mac80211") +Signed-off-by: Daniil Dulov +Link: https://patch.msgid.link/20250626114619.172631-1-d.dulov@aladdin.ru +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/zydas/zd1211rw/zd_mac.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c +index 3ef8533205f91..0a7f368f0d99c 100644 +--- a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c ++++ b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c +@@ -583,7 +583,11 @@ void zd_mac_tx_to_dev(struct sk_buff *skb, int error) + + skb_queue_tail(q, skb); + while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) { +- zd_mac_tx_status(hw, skb_dequeue(q), ++ skb = skb_dequeue(q); ++ if (!skb) ++ break; ++ ++ zd_mac_tx_status(hw, skb, + mac->ack_pending ? mac->ack_signal : 0, + NULL); + mac->ack_pending = 0; +-- +2.39.5 + diff --git a/queue-5.15/xhci-allow-rpm-on-the-usb-controller-1022-43f7-by-de.patch b/queue-5.15/xhci-allow-rpm-on-the-usb-controller-1022-43f7-by-de.patch new file mode 100644 index 0000000000..b689b55828 --- /dev/null +++ b/queue-5.15/xhci-allow-rpm-on-the-usb-controller-1022-43f7-by-de.patch @@ -0,0 +1,46 @@ +From 5d5d795127441ad524b077738d869cfdf757706b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Mar 2024 11:13:27 +0530 +Subject: xhci: Allow RPM on the USB controller (1022:43f7) by default + +From: Basavaraj Natikar + +[ Upstream commit 28cbed496059fe1868203b76e9e0ef285733524d ] + +Enable runtime PM by default for older AMD 1022:43f7 xHCI 1.1 host as it +is proven to work. +Driver enables runtime PM by default for newer xHCI 1.2 host. + +Link: https://lore.kernel.org/all/12335218.O9o76ZdvQC@natalenko.name/ +Cc: Mario Limonciello +Tested-by: Oleksandr Natalenko +Signed-off-by: Basavaraj Natikar +Acked-by: Mathias Nyman +Link: https://lore.kernel.org/r/20240304054327.2564500-1-Basavaraj.Natikar@amd.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: cbc889ab0122 ("usb: xhci: quirk for data loss in ISOC transfers") +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-pci.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c +index 18200d3662fe6..5c46e85cc2d7c 100644 +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -191,8 +191,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) + xhci->quirks |= XHCI_RESET_ON_RESUME; + } + +- if (pdev->vendor == PCI_VENDOR_ID_AMD) ++ if (pdev->vendor == PCI_VENDOR_ID_AMD) { + xhci->quirks |= XHCI_TRUST_TX_LENGTH; ++ if (pdev->device == 0x43f7) ++ xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; ++ } + + if ((pdev->vendor == PCI_VENDOR_ID_AMD) && + ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) || +-- +2.39.5 + diff --git a/queue-5.15/xhci-disable-stream-for-xhc-controller-with-xhci_bro.patch b/queue-5.15/xhci-disable-stream-for-xhc-controller-with-xhci_bro.patch new file mode 100644 index 0000000000..5a43834013 --- /dev/null +++ b/queue-5.15/xhci-disable-stream-for-xhc-controller-with-xhci_bro.patch @@ -0,0 +1,39 @@ +From 8c4c15ad6dd645161bc3fbd01c20b5d0f104e90a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Jun 2025 17:41:20 +0300 +Subject: xhci: Disable stream for xHC controller with XHCI_BROKEN_STREAMS + +From: Hongyu Xie + +[ Upstream commit cd65ee81240e8bc3c3119b46db7f60c80864b90b ] + +Disable stream for platform xHC controller with broken stream. + +Fixes: 14aec589327a6 ("storage: accept some UAS devices if streams are unavailable") +Cc: stable +Signed-off-by: Hongyu Xie +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250627144127.3889714-3-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/xhci-plat.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c +index 83c7dffa945c3..daf93bee7669b 100644 +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -361,7 +361,8 @@ static int xhci_plat_probe(struct platform_device *pdev) + if (ret) + goto disable_usb_phy; + +- if (HCC_MAX_PSA(xhci->hcc_params) >= 4) ++ if (HCC_MAX_PSA(xhci->hcc_params) >= 4 && ++ !(xhci->quirks & XHCI_BROKEN_STREAMS)) + xhci->shared_hcd->can_do_streams = 1; + + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); +-- +2.39.5 +