* [PATCH 7.2 001/281] bnxt_en: fix DMA mapping length for padded small packets
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 002/281] fs: Free any excess xarray nodes in clear_inode() Greg Kroah-Hartman
` (286 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefan Fleischmann, Eric Dumazet,
Michael Chan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@kernel.org>
[ Upstream commit a51d233ccd4889aadb71dace863525cc2b00271e ]
Stefan Fleischmann reported Intel IOMMU DMA Read faults on BCM57412
NetXtreme-E NICs when transmitting packets on VLAN/macvlan interfaces:
DMAR: [DMA Read NO_PASID] Request device [18:00.0] fault addr 0xfc499000
[fault reason 0x06] PTE Read access is not set
bnxt_en 0000:18:00.0 eno1np0: Abandoning msg {0xb4 0x41a} len: 0 due to firmware status: 0x2000001
...
NETDEV WATCHDOG: eno1np0 (bnxt_en): transmit queue 0 timed out
The fault address (0xfc499000) is on an exact 4KB page boundary,
pointing to a DMA read buffer overrun.
In bnxt_start_xmit(), packets smaller than BNXT_MIN_PKT_SIZE (52 bytes),
such as 42-byte untagged ARP frames, are padded:
if (length < BNXT_MIN_PKT_SIZE) {
pad = BNXT_MIN_PKT_SIZE - length;
if (skb_pad(skb, pad))
goto tx_kick_pending;
length = BNXT_MIN_PKT_SIZE;
}
mapping = dma_map_single(&pdev->dev, skb->data, len, DMA_TO_DEVICE);
...
dma_unmap_len_set(tx_buf, len, len);
However, 'len' was initialized earlier to skb_headlen(skb) (e.g. 42 bytes)
and is left unadjusted after padding. Consequently, dma_map_single() and
dma_unmap_len_set() map and track only 42 bytes.
Later, the hardware TX buffer descriptor is programmed with the padded length:
txbd->tx_bd_len_flags_type =
cpu_to_le32(((len + pad) << TX_BD_LEN_SHIFT) | flags |
TX_BD_FLAGS_PACKET_END);
The NIC DMA engine is thus instructed to read 52 bytes from a region where
only 42 bytes were DMA-mapped. If skb->data ends near the boundary of a 4KB
page (within 'pad' bytes of the next page), the hardware DMA read overruns
into the unmapped adjacent page, triggering an IOMMU fault.
This issue was exposed after commit 447cbe95ebb9 ("vlan: fix skb_under_panic
and races when toggling HW VLAN offload") because reserving extra VLAN
headroom rounded LL_RESERVED_SPACE from 48 up to 64 bytes, shifting skb->data
offsets and potentially causing small frames to land right against page
boundaries.
Fix this by using skb_put_padto(skb, BNXT_MIN_PKT_SIZE) in
bnxt_start_xmit(), before skb_shinfo(skb)->nr_frags is sampled,
because padding might linearize the skb.
This ensures skb->len and skb_headlen(skb) reflect the padded size so
that dma_map_single() maps the full buffer and the descriptor length is
consistent. This also removes the temporary 'pad' variable and masking logic.
The padding is done after the SW USO branch, otherwise
bnxt_sw_udp_gso_xmit() would account the padding as UDP payload
and send it in extra segments.
Note that SW USO segments are still not padded: with IPv4, a segment
carrying less than 10 bytes of UDP payload (small gso_size, or a short
last segment) is sent as a frame shorter than BNXT_MIN_PKT_SIZE.
This is a separate issue, left for a followup patch.
Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.")
Cc: stable@vger.kernel.org
Reported-by: Stefan Fleischmann <sfle@kth.se>
Closes: https://lore.kernel.org/netdev/20261004122616.56714cbd@nargothrond/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20261007051747.455273-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 25 +++++++++++------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index ced998399efc3..cad3bbe1b12f0 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -486,7 +486,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct netdev_queue *txq;
int i;
dma_addr_t mapping;
- unsigned int length, pad = 0;
+ unsigned int length;
u32 len, free_size, vlan_tag_flags, cfa_action, flags;
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
struct pci_dev *pdev = bp->pdev;
@@ -536,6 +536,16 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
return rc < 0 ? NETDEV_TX_BUSY : NETDEV_TX_OK;
}
+ /* Pad after the SW USO branch: bnxt_sw_udp_gso_xmit() would
+ * otherwise account the padding as UDP payload.
+ * Must be done before skb_shinfo(skb)->nr_frags is sampled,
+ * because skb_put_padto() might linearize the skb.
+ */
+ if (skb_put_padto(skb, BNXT_MIN_PKT_SIZE)) {
+ /* SKB already freed. */
+ goto tx_kick_pending;
+ }
+
free_size = bnxt_tx_avail(bp, txr);
if (unlikely(free_size < skb_shinfo(skb)->nr_frags + 2)) {
/* We must have raced with NAPI cleanup */
@@ -672,14 +682,6 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
normal_tx:
- if (length < BNXT_MIN_PKT_SIZE) {
- pad = BNXT_MIN_PKT_SIZE - length;
- if (skb_pad(skb, pad))
- /* SKB already freed. */
- goto tx_kick_pending;
- length = BNXT_MIN_PKT_SIZE;
- }
-
mapping = dma_map_single(&pdev->dev, skb->data, len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(&pdev->dev, mapping)))
@@ -759,10 +761,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbd->tx_bd_len_flags_type = cpu_to_le32(flags);
}
- flags &= ~TX_BD_LEN;
- txbd->tx_bd_len_flags_type =
- cpu_to_le32(((len + pad) << TX_BD_LEN_SHIFT) | flags |
- TX_BD_FLAGS_PACKET_END);
+ txbd->tx_bd_len_flags_type |= cpu_to_le32(TX_BD_FLAGS_PACKET_END);
netdev_tx_sent_queue(txq, skb->len);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 002/281] fs: Free any excess xarray nodes in clear_inode()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 001/281] bnxt_en: fix DMA mapping length for padded small packets Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 003/281] net/mlx5e: Prevent stale XSK buffer release on refill retry Greg Kroah-Hartman
` (285 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rik van Riel, Zi Yan, Jinjiang Tu,
Dave Jones, Matthew Wilcox (Oracle), Christian Brauner (Amutable),
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) <willy@infradead.org>
[ Upstream commit ee3f011250104129893d8e9599147e457d4d7280 ]
For many years we've had a hard to hit leak of xarray nodes. Hugh
documented it well in commit 786b31121a2c. Recently people and
syzbot have found ways to force it to happen with madvise. Rather
than fix the leaks where they happen, just call xa_destroy() which
has the side-effect of cycling the i_pages lock.
Cc: Rik van Riel <riel@surriel.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: Jinjiang Tu <tujinjiang@huawei.com>
Cc: Dave Jones <davej@codemonkey.org.uk>
Link: https://lore.kernel.org/all/20260121062243.1893129-1-tujinjiang@huawei.com/
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Link: https://patch.msgid.link/20260623192850.1595958-1-willy@infradead.org
Reviewed-by: Rik van Riel <riel@surriel.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/inode.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/fs/inode.c b/fs/inode.c
index c6b08e8c5f627..efa801f3eb110 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -763,21 +763,18 @@ void clear_inode(struct inode *inode)
fsverity_cleanup_inode(inode);
/*
- * We have to cycle the i_pages lock here because reclaim can be in the
- * process of removing the last page (in __filemap_remove_folio())
- * and we must not free the mapping under it.
+ * We have to cycle the i_pages lock here because reclaim
+ * can be in the process of removing the last page (in
+ * __filemap_remove_folio()) and we must not free the mapping
+ * under it. We also remove nodes which are empty; these
+ * can occur in two different ways. The first is that radix
+ * tree expansion can fail partway and the second is that THP
+ * collapse_file() can allocate some temporary nodes and not
+ * clean them up.
*/
- xa_lock_irq(&inode->i_data.i_pages);
+ xa_destroy(&inode->i_data.i_pages);
+
BUG_ON(inode->i_data.nrpages);
- /*
- * Almost always, mapping_empty(&inode->i_data) here; but there are
- * two known and long-standing ways in which nodes may get left behind
- * (when deep radix-tree node allocation failed partway; or when THP
- * collapse_file() failed). Until those two known cases are cleaned up,
- * or a cleanup function is called here, do not BUG_ON(!mapping_empty),
- * nor even WARN_ON(!mapping_empty).
- */
- xa_unlock_irq(&inode->i_data.i_pages);
BUG_ON(!(inode_state_read_once(inode) & I_FREEING));
BUG_ON(inode_state_read_once(inode) & I_CLEAR);
BUG_ON(!list_empty(&inode->i_wb_list));
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 003/281] net/mlx5e: Prevent stale XSK buffer release on refill retry
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 001/281] bnxt_en: fix DMA mapping length for padded small packets Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 002/281] fs: Free any excess xarray nodes in clear_inode() Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 004/281] net/mlx5e: Prevent stale XSK buffer release on MPWQE " Greg Kroah-Hartman
` (284 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daniel Borkmann, Dragos Tatulea,
Jerome Tollet, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Tollet <jtollet@cisco.com>
[ Upstream commit e01620844c5c88b6fcf819d171df8e3976a0e76f ]
When an XDP redirect to an AF_XDP socket fails because its RX ring is
full, the XSK core frees the buffer. During the subsequent batched refill
of a legacy cyclic RQ, mlx5e also releases the WQE's XSK buffer before
allocating a replacement. If that refill succeeds only partially, a WQE
left without a replacement retains its old buffer pointer.
The buffer can meanwhile be allocated to another WQE. A later refill
retry can then free the live buffer through the stale pointer and publish
the same UMEM frame twice.
Mark the WQE as released immediately after the driver-side free. The flag
is already cleared when a replacement buffer is assigned, so refill
retries no longer release stale pointers.
The failure is silent and produces no kernel warning or splat. A
standalone legacy cyclic-RQ zero-copy libxsk reproducer, using 64-byte UDP
traffic offered at 12 Mpps, detected it: stock stopped after 2,854,914
packets in 4.094 seconds, with 4,542 xdp_rx_ring_full events and 64
ownership/double-publication errors. With this change it processed
356,904,225 packets in 30 seconds despite 571,405 xdp_rx_ring_full events,
with no ownership or data errors.
Fixes: 3f93f82988bc ("net/mlx5e: RX, Defer page release in legacy rq for better recycling")
Cc: stable@vger.kernel.org
Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Jerome Tollet <jtollet@cisco.com>
Link: https://patch.msgid.link/20260824141645.23700-2-jtollet@cisco.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 6fc6605d20549..7967a27372981 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -410,8 +410,11 @@ static inline void mlx5e_free_rx_wqe(struct mlx5e_rq *rq,
static void mlx5e_xsk_free_rx_wqe(struct mlx5e_wqe_frag_info *wi)
{
- if (!(wi->flags & BIT(MLX5E_WQE_FRAG_SKIP_RELEASE)))
- xsk_buff_free(*wi->xskp);
+ if (wi->flags & BIT(MLX5E_WQE_FRAG_SKIP_RELEASE))
+ return;
+
+ xsk_buff_free(*wi->xskp);
+ wi->flags |= BIT(MLX5E_WQE_FRAG_SKIP_RELEASE);
}
static void mlx5e_dealloc_rx_wqe(struct mlx5e_rq *rq, u16 ix)
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 004/281] net/mlx5e: Prevent stale XSK buffer release on MPWQE refill retry
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (2 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 003/281] net/mlx5e: Prevent stale XSK buffer release on refill retry Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 005/281] ipv6: Fix redirect exception creation for UDP/RAW sockets Greg Kroah-Hartman
` (283 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jerome Tollet, Dragos Tatulea,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Tollet <jtollet@cisco.com>
[ Upstream commit 63811edf512584c946e5e96b100e9e280703bbb5 ]
With AF_XDP on a striding RQ, mlx5e defers releasing XSK buffers until
an MPWQE is refilled. If XSK allocation then returns -ENOMEM,
actual_wq_head is not advanced and a later NAPI poll retries the same
WQE.
mlx5e_free_rx_mpwqe() leaves each released slot marked as releasable. On
retry it can therefore call xsk_buff_free() again through stale pointers
after the frames have returned to the XSK pool and been reallocated.
Set all skip_release_bitmap bits in the common error path of
mlx5e_xsk_alloc_rx_mpwqe(). This matches mlx5e_alloc_rx_mpwqe(). A
successful allocation already clears the bitmap after replacing every
buffer, so retries become idempotent without changing the success path.
Fault injection forced three consecutive failures for one selected MPWQE.
Both an early allocation failure and a partial 8-of-16-buffer unwind
released the original 16 XSK buffers only once. Each error left a full
bitmap, the following NAPI retry skipped the release, and a later
successful allocation cleared it. A 20-second AF_XDP zero-copy pressure
run exercised 1,575,262 buffer allocation failures without invalid
descriptors, WQE errors, or kernel warnings.
Fixes: 4c2a13236807 ("net/mlx5e: RX, Defer page release in striding rq for better recycling")
Cc: stable@vger.kernel.org
Signed-off-by: Jerome Tollet <jtollet@cisco.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Link: https://patch.msgid.link/20260824141645.23700-3-jtollet@cisco.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c
index 4f984f6a2cb95..55ec6387ab28d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/rx.c
@@ -3,6 +3,7 @@
#include "rx.h"
#include "en/xdp.h"
+#include <linux/bitmap.h>
#include <net/xdp_sock_drv.h>
#include <linux/filter.h>
@@ -156,6 +157,7 @@ int mlx5e_xsk_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
xsk_buff_free(xsk_buffs[batch]);
err:
+ bitmap_fill(wi->skip_release_bitmap, rq->mpwqe.pages_per_wqe);
rq->stats->buff_alloc_err++;
return -ENOMEM;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 005/281] ipv6: Fix redirect exception creation for UDP/RAW sockets
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (3 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 004/281] net/mlx5e: Prevent stale XSK buffer release on MPWQE " Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 006/281] ipv4: udp: Create exceptions before socket matching Greg Kroah-Hartman
` (282 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, David Ahern,
Ido Schimmel, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit cd51b74bdd0b75aedf255dc67306a16dd057f7ee ]
When an ICMP Redirect Message is matched to a socket, both IPv4 and IPv6
verify that the source IP of the ICMP packet is the current gateway for
the quoted packet. Both also pass the socket's bound device as the
expected nexthop device.
The difference is that IPv4 treats "oif=0" as "any", whereas IPv6 always
requires an exact match (see ip6_redirect_nh_match()), since the gateway
address is usually a link-local address.
Therefore, when an IPv6 UDP/RAW socket is not bound to a device, the
above verification fails and an exception is not created. This also
happens when the socket is bound to a VRF, as l3mdev_update_flow()
resets the oif to 0.
Fix this by passing the ifindex of the ingress device as the expected
nexthop device. This is consistent with the existing callers of
ip6_redirect(). Note that for ICMPv6 Redirect Message packets the VRF
driver does not reset skb->dev to the VRF device, so skb->dev is
correct, even when it is a VRF port.
Fixes: b55b76b22144 ("ipv6:introduce function to find route for redirect")
Cc: stable@vger.kernel.org
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828192344.2596928-2-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/route.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 8fddcc631fcb6..f58c670588def 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3261,7 +3261,7 @@ void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif)
void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk)
{
- ip6_redirect(skb, sock_net(sk), sk->sk_bound_dev_if,
+ ip6_redirect(skb, sock_net(sk), skb->dev->ifindex,
READ_ONCE(sk->sk_mark), sk_uid(sk));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 006/281] ipv4: udp: Create exceptions before socket matching
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (4 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 005/281] ipv6: Fix redirect exception creation for UDP/RAW sockets Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 007/281] ipv6: " Greg Kroah-Hartman
` (281 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amit Klein, Noam Caspi, Ido Schimmel,
David Ahern, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit 4c3499f79f8c7e8561266bcc220a18538cec0458 ]
Currently, when ICMP Fragmentation Needed and Redirect Message packets
are locally delivered and quote a UDP packet, a FIB nexthop exception
(FNHE) is only created if the kernel can match the UDP packet to an
existing socket.
This behavior allows off-path attackers to conduct a side-channel attack
on the FNHE cache in order to discover the ephemeral port used by a
connected UDP socket.
Commit 6457378fe796 ("ipv4: use siphash instead of Jenkins in
fnhe_hashfun()") and commit 67d6d681e15b ("ipv4: make exception cache
less predictible") tried to mitigate such attacks by making it harder
for attackers to discover hash collisions in the FNHE cache and by
randomizing the number of exceptions a hash bucket can hold,
respectively. Unfortunately, both of the mitigations can be bypassed.
Instead, mitigate such attacks by always creating a FNHE, even before
trying to find a matching socket. Do that by calling ipv4_update_pmtu()
and ipv4_redirect(), the helpers used when the quoted packet did not
originate from a socket.
This means that guesses (right or wrong) from an off-path attacker will
always result in a FNHE being created or updated in the cache that the
attacker can observe.
Pass an oif of 0, in a similar fashion to icmp_err(). This is also the
oif used by the socket path for sockets that are not bound to a device.
Note that this does not allow attackers to create FNHEs that they could
not create before, as both helpers can already be reached with little to
no validation. For example, by sending an ICMP error that quotes an ICMP
Echo Reply or one that quotes a UDP source port that matches a wildcard
socket.
Also note that in the good case (matched socket) the above scheme comes
at the cost of an extra route lookup, as the no socket helpers perform
their own lookup before the one performed by ipv4_sk_update_pmtu() /
ipv4_sk_redirect(). When the two resolve to different nexthops, it also
results in two exceptions being created for the same destination IP. One
in the FNHE cache of the nexthop resolved by the no socket helpers and
another in the FNHE cache of the nexthop used by the socket.
Fixes: 4895c771c7f0 ("ipv4: Add FIB nexthop exceptions.")
Cc: stable@vger.kernel.org
Reported-by: Amit Klein <aksecurity@gmail.com>
Reported-by: Noam Caspi <noam.caspi@mail.huji.ac.il>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20260828192344.2596928-3-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/udp.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 59afce196079a..a50dccfbf4205 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -908,6 +908,15 @@ static struct sock *__udp4_lib_err_encap(struct net *net,
return sk;
}
+static void udp_err_update_exception(struct net *net, struct sk_buff *skb,
+ int type, int code, u32 info)
+{
+ if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
+ ipv4_update_pmtu(skb, net, info, 0, IPPROTO_UDP);
+ else if (type == ICMP_REDIRECT)
+ ipv4_redirect(skb, net, 0, IPPROTO_UDP);
+}
+
/*
* This routine is called by the ICMP module when it gets some
* sort of error condition. If err < 0 then the socket should
@@ -931,6 +940,8 @@ int udp_err(struct sk_buff *skb, u32 info)
int harderr;
int err;
+ udp_err_update_exception(net, skb, type, code, info);
+
uh = (struct udphdr *)(skb->data + (iph->ihl << 2));
sk = __udp4_lib_lookup(net, iph->daddr, uh->dest,
iph->saddr, uh->source, skb->dev->ifindex,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 007/281] ipv6: udp: Create exceptions before socket matching
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (5 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 006/281] ipv4: udp: Create exceptions before socket matching Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 008/281] ipv4: validate checksum_start before completing checksum Greg Kroah-Hartman
` (280 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amit Klein, Noam Caspi, Ido Schimmel,
David Ahern, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit ac76cab50e899a7346408b8d3c3a4192c2eefb9f ]
Currently, when ICMPv6 Packet Too Big and Redirect Message packets are
locally delivered and quote a UDP packet, an exception is only created
in the IPv6 exception cache if the kernel can match the UDP packet to an
existing socket.
This behavior allows off-path attackers to conduct a side-channel attack
on the exception cache in order to discover the ephemeral port used by a
connected UDP socket.
Commit 4785305c05b2 ("ipv6: use siphash in rt6_exception_hash()") and
commit a00df2caffed ("ipv6: make exception cache less predictible") tried
to mitigate such attacks by making it harder for attackers to discover
hash collisions in the exception cache and by randomizing the number of
exceptions a hash bucket can hold, respectively. Unfortunately, both of
the mitigations can be bypassed.
Instead, mitigate such attacks by always creating an exception, even
before trying to find a matching socket. Do that by calling
ip6_update_pmtu() and ip6_redirect(), the helpers used when the quoted
packet did not originate from a socket.
This means that guesses (right or wrong) from an off-path attacker will
always result in an exception being created or updated in the cache that
the attacker can observe.
Pass the ifindex of the ingress device and the default uid, in a similar
fashion to icmpv6_err(). Unlike IPv4, an oif of 0 would not match any
nexthop in ip6_redirect_nh_match() and no exception would be created in
response to a Redirect Message.
Note that this does not allow attackers to create exceptions that they
could not create before, as both helpers can already be reached with
little to no validation. For example, by sending an ICMPv6 error that
quotes an ICMPv6 Echo Reply or one that quotes a UDP source port that
matches a wildcard socket.
Also note that in the good case (matched socket) the above scheme comes
at the cost of an extra route lookup, as the no socket helpers perform
their own lookup before the one performed by ip6_sk_update_pmtu() /
ip6_sk_redirect(). When the two resolve to different nexthops, it also
results in two exceptions being created for the same destination IP. One
in the exception cache of the nexthop resolved by the no socket helpers
and another in the exception cache of the nexthop used by the socket.
Fixes: 2b760fcf5cfb ("ipv6: hook up exception table to store dst cache")
Cc: stable@vger.kernel.org
Reported-by: Amit Klein <aksecurity@gmail.com>
Reported-by: Noam Caspi <noam.caspi@mail.huji.ac.il>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20260828192344.2596928-4-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/udp.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 15e032194eccc..b73cf02ac1b6e 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -690,6 +690,17 @@ static struct sock *__udp6_lib_err_encap(struct net *net,
return sk;
}
+static void udpv6_err_update_exception(struct net *net, struct sk_buff *skb,
+ u8 type, __be32 info)
+{
+ if (type == ICMPV6_PKT_TOOBIG)
+ ip6_update_pmtu(skb, net, info, skb->dev->ifindex, 0,
+ sock_net_uid(net, NULL));
+ else if (type == NDISC_REDIRECT)
+ ip6_redirect(skb, net, skb->dev->ifindex, 0,
+ sock_net_uid(net, NULL));
+}
+
static int udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
u8 type, u8 code, int offset, __be32 info)
{
@@ -703,6 +714,8 @@ static int udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
int harderr;
int err;
+ udpv6_err_update_exception(net, skb, type, info);
+
daddr = seg6_get_daddr(skb, opt) ? : &hdr->daddr;
saddr = &hdr->saddr;
sk = __udp6_lib_lookup(net, daddr, uh->dest, saddr, uh->source,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 008/281] ipv4: validate checksum_start before completing checksum
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (6 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 007/281] ipv6: " Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 009/281] rust_binder: reschedule node refcount update on thread exit Greg Kroah-Hartman
` (279 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paulos Yibelo, Michael S. Tsirkin,
Willem de Bruijn, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael S. Tsirkin <mst@redhat.com>
commit 6785011f8b16abf40b1e9d8b2e332232b3e68822 upstream.
If a packet with bad checksum metadata gets into the ipv4 stack,
skb_checksum_help can corrupt the network header and cause a bunch of
mischief.
This was discovered and reported by Paulos, and has been reporoduced
by others independently since.
We really shouldn't allow such packets in, but as a defence
in depth measure, let's also check before we complete the checksum.
A more complete validation at input is forthcoming, but needs more work.
Cc: stable@vger.kernel.org
Fixes: f43798c27684 ("tun: Allow GSO using virtio_net_hdr")
Fixes: bfd5f4a3d605 ("packet: Add GSO/csum offload support.")
Reported-by: Paulos Yibelo <habte.yibelo@gmail.com>
Closes: https://lore.kernel.org/netdev/20260922030310.8684-2-habte.yibelo@gmail.com/
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/0a012b4923e189c4c593ef4f471e5ff0edbe9030.1791412497.git.mst@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/net/ip.h | 7 +++++++
net/bridge/netfilter/nf_conntrack_bridge.c | 10 +++++++---
net/ipv4/ip_output.c | 10 +++++++---
net/netfilter/nfnetlink_queue.c | 7 +++++++
net/netfilter/xt_CHECKSUM.c | 6 +++++-
net/xfrm/xfrm_output.c | 16 +++++++++++-----
6 files changed, 44 insertions(+), 12 deletions(-)
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -74,6 +74,13 @@ static inline unsigned int ip_hdrlen(con
return ip_hdr(skb)->ihl * 4;
}
+static inline int ip_check_csum_start(const struct sk_buff *skb)
+{
+ if (unlikely(skb->csum_start < skb->network_header + ip_hdrlen(skb)))
+ return -EINVAL;
+ return 0;
+}
+
struct ipcm_cookie {
struct sockcm_cookie sockc;
__be32 addr;
--- a/net/bridge/netfilter/nf_conntrack_bridge.c
+++ b/net/bridge/netfilter/nf_conntrack_bridge.c
@@ -39,9 +39,13 @@ static int nf_br_ip_fragment(struct net
int err = 0;
/* for offloaded checksums cleanup checksum before fragmentation */
- if (skb->ip_summed == CHECKSUM_PARTIAL &&
- (err = skb_checksum_help(skb)))
- goto blackhole;
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ err = ip_check_csum_start(skb);
+ if (!err)
+ err = skb_checksum_help(skb);
+ if (err)
+ goto blackhole;
+ }
iph = ip_hdr(skb);
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -771,9 +771,13 @@ int ip_do_fragment(struct net *net, stru
int err = 0;
/* for offloaded checksums cleanup checksum before fragmentation */
- if (skb->ip_summed == CHECKSUM_PARTIAL &&
- (err = skb_checksum_help(skb)))
- goto fail;
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ err = ip_check_csum_start(skb);
+ if (!err)
+ err = skb_checksum_help(skb);
+ if (err)
+ goto fail;
+ }
/*
* Point into the IP datagram header.
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -33,6 +33,7 @@
#include <linux/rhashtable.h>
#include <linux/jhash.h>
#include <net/gso.h>
+#include <net/ip.h>
#include <net/sock.h>
#include <net/tcp_states.h>
#include <net/netfilter/nf_queue.h>
@@ -667,6 +668,12 @@ nla_put_failure:
static int nf_queue_checksum_help(struct sk_buff *entskb)
{
+ if (entskb->protocol == htons(ETH_P_IP)) {
+ if (!pskb_network_may_pull(entskb, sizeof(struct iphdr)) ||
+ ip_check_csum_start(entskb))
+ return -EINVAL;
+ }
+
if (skb_csum_is_sctp(entskb))
return skb_crc32c_csum_help(entskb);
--- a/net/netfilter/xt_CHECKSUM.c
+++ b/net/netfilter/xt_CHECKSUM.c
@@ -15,6 +15,7 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <net/ip.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Michael S. Tsirkin <mst@redhat.com>");
@@ -25,8 +26,11 @@ MODULE_ALIAS("ip6t_CHECKSUM");
static unsigned int
checksum_tg(struct sk_buff *skb, const struct xt_action_param *par)
{
- if (skb->ip_summed == CHECKSUM_PARTIAL && !skb_is_gso(skb))
+ if (skb->ip_summed == CHECKSUM_PARTIAL && !skb_is_gso(skb)) {
+ if (xt_family(par) == NFPROTO_IPV4 && ip_check_csum_start(skb))
+ return NF_DROP;
skb_checksum_help(skb);
+ }
return XT_CONTINUE;
}
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -823,16 +823,22 @@ int xfrm_output(struct sock *sk, struct
}
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- err = skb_checksum_help(skb);
- if (err) {
- XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
- kfree_skb(skb);
- return err;
+ if (skb->protocol == htons(ETH_P_IP)) {
+ err = ip_check_csum_start(skb);
+ if (err)
+ goto error;
}
+ err = skb_checksum_help(skb);
+ if (err)
+ goto error;
}
out:
return xfrm_output2(net, sk, skb);
+error:
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
+ kfree_skb(skb);
+ return err;
}
EXPORT_SYMBOL_GPL(xfrm_output);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 009/281] rust_binder: reschedule node refcount update on thread exit
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (7 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 008/281] ipv4: validate checksum_start before completing checksum Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 010/281] ipv4: stop PMTU walk when nexthop group shrinks Greg Kroah-Hartman
` (278 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Alice Ryhl, Miguel Ojeda
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alice Ryhl <aliceryhl@google.com>
commit 2a74ccd1bcc170e66525f34e9de8652b57e2cf3d upstream.
When a thread exits via BINDER_THREAD_EXIT, its pending work items are
cancelled. If a thread exits while holding a pending node refcount
increment (e.g. pushed as deferred work to that thread), the refcount
increment was previously dropped because Node::cancel() and
NodeWrapper::cancel() were no-ops.
Dropping the refcount update leaves the node's delivery state and count
state desynchronized, and userspace will not receive the notification,
which can cause the node to never be freed from the process's nodes tree
when all external references are dropped.
Fix this by implementing DeliverToRead::cancel() for Node and NodeWrapper
to move the pending refcount update to the process's work queue on thread
exit so another thread can deliver it to userspace.
Cc: stable <stable@kernel.org>
Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver")
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260903-binder-thread-exit-node-v1-1-be09ff14f6a4@google.com
[ Dropped first argument in calls to `push_work()` to adjust to the
existing form without mainline commit dbb17c9ea756 ("rust_binder: move
(e)poll wait queue to Process"). - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/android/binder/node.rs | 20 ++++++++++++++++---
drivers/android/binder/node/wrapper.rs | 34 ++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 4 deletions(-)
--- a/drivers/android/binder/node.rs
+++ b/drivers/android/binder/node.rs
@@ -49,9 +49,9 @@ pub(crate) struct CouldNotDeliverCritica
/// about to drop the weak reference, then the strong increment could be processed after the
/// other thread has already exited, which would be too late.
///
-/// Note that trying to create a `ListArc` to the node can succeed even if `has_normal_push` is
+/// Note that trying to create a `ListArc` to the node can succeed even if `has_pushed_node` is
/// set. This is because another thread might just have popped the node from a todo list, but not
-/// yet called `do_work`. However, if `has_normal_push` is false, then creating a `ListArc` should
+/// yet called `do_work`. However, if `has_pushed_node` is false, then creating a `ListArc` should
/// always succeed.
///
/// Like the other fields in `NodeInner`, the delivery state is protected by the process lock.
@@ -733,7 +733,21 @@ impl DeliverToRead for Node {
self.do_work_locked(writer, owner_inner)
}
- fn cancel(self: DArc<Self>) {}
+ fn cancel(self: DArc<Self>) {
+ let _drop_outside_lock;
+ let mut owner_inner = self.owner.inner.lock();
+
+ // We only do something on BINDER_THREAD_EXIT, not process exit.
+ if owner_inner.is_dead {
+ return;
+ }
+
+ // If BINDER_THREAD_EXIT is invoked on a thread with a pending node refcount update, we
+ // should move ourselves to ensure the refcount update is still delivered.
+ if let Some(node) = ListArc::try_from_arc_borrow(self.as_arc_borrow()) {
+ _drop_outside_lock = owner_inner.push_work(node);
+ }
+ }
fn should_sync_wakeup(&self) -> bool {
false
--- a/drivers/android/binder/node/wrapper.rs
+++ b/drivers/android/binder/node/wrapper.rs
@@ -57,7 +57,39 @@ impl DeliverToRead for NodeWrapper {
node.do_work_locked(writer, owner_inner)
}
- fn cancel(self: DArc<Self>) {}
+ fn cancel(self: DArc<Self>) {
+ let _drop_outside_lock;
+ let node = &self.node;
+ let mut owner_inner = node.owner.inner.lock();
+
+ // We only do something on BINDER_THREAD_EXIT, not process exit.
+ if owner_inner.is_dead {
+ return;
+ }
+
+ // We transfer the responsibility of the node refcount update to the scheduled Node because
+ // NodeWrapper has no way to re-create the ListArc.
+ let inner = node.inner.access_mut(&mut owner_inner);
+
+ let ds = &mut inner.delivery_state;
+ assert!(ds.has_pushed_wrapper);
+ assert!(ds.has_strong_zero2one);
+ ds.has_pushed_wrapper = false;
+
+ // We are changing the state to one where the Node is the strong zero2one update instead of
+ // the wrapper.
+ ds.has_weak_zero2one = false;
+
+ if !ds.has_pushed_node {
+ if let Some(node2) = ListArc::try_from_arc_borrow(node.as_arc_borrow()) {
+ ds.has_pushed_node = true;
+ _drop_outside_lock = owner_inner.push_work(node2);
+ } else {
+ // This can't actually happen.
+ ds.has_strong_zero2one = false;
+ }
+ }
+ }
fn should_sync_wakeup(&self) -> bool {
false
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 010/281] ipv4: stop PMTU walk when nexthop group shrinks
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (8 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 009/281] rust_binder: reschedule node refcount update on thread exit Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 011/281] ipv4: stop exception dump " Greg Kroah-Hartman
` (277 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Ido Schimmel,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit 6619e01855e65ef35723685a557e3eb106f4ecf5 upstream.
Commit 7d3f3b4367f3 ("net: ipv4: Cache pmtu for all packet paths if
multipath enabled") made __ip_rt_update_pmtu() update every path.
For nexthop objects, fib_info_num_path() and fib_info_nhc()
independently load nh->nh_grp. RCU protects each group's lifetime but
does not make the loads observe the same group. If replacement shrinks
the group after the loop accepts an index, fib_info_nhc() returns NULL
and update_or_create_fnhe() dereferences it.
A deterministic probe only widened the existing window between the real
operations. On v7.2, an RTM_NEWNEXTHOP replacement published a
one-member group after the PMTU reader accepted index 1 from a two-member
group, producing:
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
RIP: update_or_create_fnhe+0x45/0x15b0
Stop when the indexed path is absent. Groups are dense, so no later
index exists in that snapshot. The same real-writer window completed
114,423 PMTU iterations without an oops with this check. A reproducer
is available on request.
Replacement requires CAP_NET_ADMIN in the network namespace. Where
unprivileged user namespaces are permitted, a local user can obtain it
in a new user and network namespace.
Fixes: 7d3f3b4367f3 ("net: ipv4: Cache pmtu for all packet paths if multipath enabled")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/4fb87ed994dfc067178fc845cdd8bc9b5446b039.1790915964.git.4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/route.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1080,6 +1080,8 @@ static void __ip_rt_update_pmtu(struct r
for (nhsel = 0; nhsel < fib_info_num_path(res.fi); nhsel++) {
nhc = fib_info_nhc(res.fi, nhsel);
+ if (!nhc)
+ break;
update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock,
jiffies + net->ipv4.ip_rt_mtu_expires);
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 011/281] ipv4: stop exception dump when nexthop group shrinks
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (9 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 010/281] ipv4: stop PMTU walk when nexthop group shrinks Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 012/281] ipv4: stop route notification sizing " Greg Kroah-Hartman
` (276 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Daehyeon Ko,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit 4f4afc07dcb2edd4f9afa36595373f8cdb9b58c2 upstream.
Commit 4ce5dc9316de ("inet: switch inet_dump_fib() to RCU
protection") allowed IPv4 FIB dumps to run concurrently with nexthop
replacement.
fib_dump_info_fnhe() uses fib_info_num_path() as the loop bound,
then fib_info_nhc() independently reloads nh->nh_grp. If
RTM_NEWNEXTHOP replaces a group with fewer paths between those loads,
fib_info_nhc() returns NULL and the dump dereferences it through
nhc_flags.
Stop the walk when the indexed path is absent. Nexthop groups are
dense, so the current snapshot has no later path.
Fixes: 4ce5dc9316de ("inet: switch inet_dump_fib() to RCU protection")
Reported-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/netdev/20261001170513.GA1657889@shredder/
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/5bb7bd97411eb9db454464bf449107395e760f26.1790915964.git.4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/route.c | 3 +++
1 file changed, 3 insertions(+)
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -3165,6 +3165,9 @@ int fib_dump_info_fnhe(struct sk_buff *s
struct fnhe_hash_bucket *bucket;
int err;
+ if (!nhc)
+ break;
+
if (nhc->nhc_flags & RTNH_F_DEAD)
continue;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 012/281] ipv4: stop route notification sizing when nexthop group shrinks
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (10 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 011/281] ipv4: stop exception dump " Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 013/281] ipv4: do not warn on route notification size race Greg Kroah-Hartman
` (275 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Ido Schimmel,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit d3daa33c7af92e38f2274bbd2576f58bfbaf89e6 upstream.
Commit 680aea08e78c ("net: ipv4: Emit notification when fib
hardware flags are changed") added an RCU-only fib_nlmsg_size() call
for asynchronous hardware flag notifications.
fib_nlmsg_size() checks fib_info_num_path() before each iteration,
then fib_info_nhc() independently reloads nh->nh_grp. If
RTM_NEWNEXTHOP replaces a group with fewer paths between those loads,
fib_info_nhc() returns NULL and fib_nexthop_nlmsg_size() dereferences
it.
Stop sizing when the indexed path is absent. Nexthop groups are
dense, so the current snapshot has no later path.
Fixes: 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/1054fa46165bba1b473782fa41367804aa908e86.1790915964.git.4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/fib_semantics.c | 3 +++
1 file changed, 3 insertions(+)
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -542,6 +542,9 @@ size_t fib_nlmsg_size(struct fib_info *f
struct fib_nh_common *nhc = fib_info_nhc(fi, i);
size_t nhsize;
+ if (!nhc)
+ break;
+
nhsize = fib_nexthop_nlmsg_size(nhc, nhs != 1);
if (nhs != 1)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 013/281] ipv4: do not warn on route notification size race
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (11 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 012/281] ipv4: stop route notification sizing " Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 014/281] ipv6: " Greg Kroah-Hartman
` (274 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Daehyeon Ko,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit e02a5b6588161673ef75a4bc5cdfb62bd493374d upstream.
Commit 680aea08e78c ("net: ipv4: Emit notification when fib hardware
flags are changed") added asynchronous route notifications for hardware
flag changes.
fib_alias_hw_flags_set() sizes the skb with fib_nlmsg_size() and later
fills it with fib_dump_info() while holding only RCU. With nexthop
compatibility mode enabled, a concurrent replacement can grow the group
between these independent snapshots. fib_dump_info() can then
legitimately return -EMSGSIZE, so the warning does not prove a sizing bug.
Remove the warning. The existing error path still frees the skb and
reports the error to listeners.
Fixes: 680aea08e78c ("net: ipv4: Emit notification when fib hardware flags are changed")
Reported-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/netdev/20261004082043.GB92032@shredder/
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Link: https://patch.msgid.link/b7e203fc5867651cb67ef84aa03e082f0f76008e.1791423190.git.4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/fib_trie.c | 2 --
1 file changed, 2 deletions(-)
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1079,8 +1079,6 @@ void fib_alias_hw_flags_set(struct net *
err = fib_dump_info(skb, 0, 0, RTM_NEWROUTE, fri, 0);
if (err < 0) {
- /* -EMSGSIZE implies BUG in fib_nlmsg_size() */
- WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 014/281] ipv6: do not warn on route notification size race
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (12 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 013/281] ipv4: do not warn on route notification size race Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 015/281] Input: ati_remote2 - fix type confusion in device attribute handlers Greg Kroah-Hartman
` (273 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Daehyeon Ko,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit c97426ec649d99596d8969e1a052c16b14b7b485 upstream.
fib6_info_hw_flags_set() sizes the skb with rt6_nlmsg_size() and later
fills it with rt6_fill_node(). With nexthop compatibility mode enabled,
a concurrent replacement can grow the group between these independent
snapshots. rt6_fill_node() can then legitimately return -EMSGSIZE, so
the warning does not prove a sizing bug.
Remove the warning. The existing error path still frees the skb and
reports the error to listeners.
Fixes: 907eea486888 ("net: ipv6: Emit notification when fib hardware flags are changed")
Reported-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/netdev/20261007114003.GA1011260@shredder/
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Link: https://patch.msgid.link/4012604727e5ba80b69ccd4d08796511397ddaef.1791423190.git.4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/route.c | 2 --
1 file changed, 2 deletions(-)
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -6474,8 +6474,6 @@ void fib6_info_hw_flags_set(struct net *
err = rt6_fill_node(net, skb, f6i, NULL, NULL, NULL, 0, RTM_NEWROUTE, 0,
0, 0);
if (err < 0) {
- /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
- WARN_ON(err == -EMSGSIZE);
kfree_skb(skb);
goto errout;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 015/281] Input: ati_remote2 - fix type confusion in device attribute handlers
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (13 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 014/281] ipv6: " Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 016/281] Input: xpad - add support for 8BitDo Pro 2 Wired Controller for Xbox Greg Kroah-Hartman
` (272 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Haotian Zhang, Dmitry Torokhov
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <vulab@iscas.ac.cn>
commit f321cc430c49b6c1be0d53f2ef19d8342d8029cc upstream.
Previously, the channel_mask and mode_mask attributes were registered on
the parent usb_device via sysfs_create_group(). When commit b20d6bf8014b
("Input: ati-remote2 - use driver core to instantiate device
attributes") converted the driver to let the driver core manage them via
dev_groups in struct usb_driver, the attributes moved to the bound
usb_interface devices, but the show and store callbacks were not updated
accordingly.
As a result, the callbacks still invoked to_usb_device() on a device
pointer belonging to a struct usb_interface, producing an invalid
usb_device pointer.
Use to_usb_interface() directly in the attribute handlers to obtain the
interface and its driver data.
Fixes: b20d6bf8014b ("Input: ati-remote2 - use driver core to instantiate device attributes")
Assisted-by: DeepSeek-V4.1-Flash
Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20261009040302.3087205-1-vulab@iscas.ac.cn
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/misc/ati_remote2.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -672,8 +672,7 @@ static ssize_t ati_remote2_show_channel_
struct device_attribute *attr,
char *buf)
{
- struct usb_device *udev = to_usb_device(dev);
- struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct usb_interface *intf = to_usb_interface(dev);
struct ati_remote2 *ar2 = usb_get_intfdata(intf);
return sprintf(buf, "0x%04x\n", ar2->channel_mask);
@@ -683,8 +682,7 @@ static ssize_t ati_remote2_store_channel
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct usb_device *udev = to_usb_device(dev);
- struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct usb_interface *intf = to_usb_interface(dev);
struct ati_remote2 *ar2 = usb_get_intfdata(intf);
unsigned int mask;
int r;
@@ -720,8 +718,7 @@ static ssize_t ati_remote2_show_mode_mas
struct device_attribute *attr,
char *buf)
{
- struct usb_device *udev = to_usb_device(dev);
- struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct usb_interface *intf = to_usb_interface(dev);
struct ati_remote2 *ar2 = usb_get_intfdata(intf);
return sprintf(buf, "0x%02x\n", ar2->mode_mask);
@@ -731,8 +728,7 @@ static ssize_t ati_remote2_store_mode_ma
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct usb_device *udev = to_usb_device(dev);
- struct usb_interface *intf = usb_ifnum_to_if(udev, 0);
+ struct usb_interface *intf = to_usb_interface(dev);
struct ati_remote2 *ar2 = usb_get_intfdata(intf);
unsigned int mask;
int err;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 016/281] Input: xpad - add support for 8BitDo Pro 2 Wired Controller for Xbox
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (14 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 015/281] Input: ati_remote2 - fix type confusion in device attribute handlers Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 017/281] Input: xpad - add support for Corsair Novablade Pro Greg Kroah-Hartman
` (271 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bihaan Sen, Dmitry Torokhov
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bihaan Sen <stevewholikesthings@gmail.com>
commit 41363c27b8509bd4efcba244803edac9ba25d1b5 upstream.
The 8BitDo Pro 2 Wired Controller for Xbox is already matched by the
vendor-wide XPAD_XBOXONE_VENDOR(0x2dc8) entry, but a later hardware
revision reports product ID 0x201e, which has no entry in the
xpad_device table. The device therefore binds and functions but is
exposed to userspace as "Generic X-Box pad".
Add the VID/PID pair so the controller is named correctly, and set
MAP_SHARE_BUTTON to expose the share button as KEY_RECORD.
Signed-off-by: Bihaan Sen <stevewholikesthings@gmail.com>
Link: https://patch.msgid.link/20260925114459.110253-1-stevewholikesthings@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/joystick/xpad.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -379,6 +379,7 @@ static const struct xpad_device {
{ 0x2993, 0x2001, "TECNO Pocket Go", 0, XTYPE_XBOX360 },
{ 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE },
{ 0x2dc8, 0x200f, "8BitDo Ultimate 3-mode Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
+ { 0x2dc8, 0x201e, "8BitDo Pro 2 Wired Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
{ 0x2dc8, 0x3106, "8BitDo Ultimate Wireless / Pro 2 Wired Controller", 0, XTYPE_XBOX360 },
{ 0x2dc8, 0x3109, "8BitDo Ultimate Wireless Bluetooth", 0, XTYPE_XBOX360 },
{ 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 },
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 017/281] Input: xpad - add support for Corsair Novablade Pro
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (15 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 016/281] Input: xpad - add support for 8BitDo Pro 2 Wired Controller for Xbox Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 018/281] ALSA: ctxfi: Fix memory leakage when clearing DAO input mappers Greg Kroah-Hartman
` (270 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Krzysztof Furman, Dmitry Torokhov
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Furman <krisfur@proton.me>
commit f9282b8aa85a8c97c50d656db75feb6d76fc7cbe upstream.
Add device IDs for the Corsair Novablade Pro leverless fight controller
in both wired (0x2b1f) and 2.4 GHz receiver (0x2b2b) modes, and add
Corsair's vendor ID to the Xbox 360 vendor match list.
Outside of its PS4/PS5 modes the controller uses the Xbox 360 protocol
(vendor-specific class, subclass 93, protocol 1) on interface 0, which
xpad does not currently bind, so no gamepad device is created. The
PS4/PS5 modes present a standard HID gamepad and already work with
hid-generic.
Tested on 7.2.5 with the 2.4 GHz receiver and wired.
Assisted-by: Claude Opus 5.5
Signed-off-by: Krzysztof Furman <krisfur@proton.me>
Link: https://patch.msgid.link/20261009-xpad-corsair-novablade-v1-1-e58746bef99f@proton.me
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/input/joystick/xpad.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -302,6 +302,8 @@ static const struct xpad_device {
{ 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 },
{ 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 },
{ 0x1a86, 0xe310, "Legion Go S", 0, XTYPE_XBOX360 },
+ { 0x1b1c, 0x2b1f, "Corsair Novablade Pro (Wired)", 0, XTYPE_XBOX360 },
+ { 0x1b1c, 0x2b2b, "Corsair Novablade Pro (2.4 GHz Receiver)", 0, XTYPE_XBOX360 },
{ 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 },
{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x1bad, 0x0130, "Ion Drum Rocker", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
@@ -546,6 +548,7 @@ static const struct usb_device_id xpad_t
XPAD_XBOX360_VENDOR(0x17ef), /* Lenovo */
XPAD_XBOX360_VENDOR(0x1949), /* Amazon controllers */
XPAD_XBOX360_VENDOR(0x1a86), /* Nanjing Qinheng Microelectronics (WCH) */
+ XPAD_XBOX360_VENDOR(0x1b1c), /* Corsair controllers */
XPAD_XBOX360_VENDOR(0x1bad), /* Harmonix Rock Band guitar and drums */
XPAD_XBOX360_VENDOR(0x1ee9), /* ZOTAC Technology Limited */
XPAD_XBOX360_VENDOR(0x20bc), /* BETOP wireless dongles */
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 018/281] ALSA: ctxfi: Fix memory leakage when clearing DAO input mappers
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (16 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 017/281] Input: xpad - add support for Corsair Novablade Pro Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 019/281] ALSA: hda/tas2781: Accept V1 calibration data without CRC Greg Kroah-Hartman
` (269 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Harin Lee, Takashi Iwai
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harin Lee <me@harin.net>
commit 593d46fc6af9a0178a46e77d6d24b20d2314165f upstream.
Commit e576e7843c0d ("ALSA: ctxfi: Simplify dao_clear_{left,right}_input() functions")
centralized the DAO input mapper clearing logic in
dao_clear_input(), but omitted the kfree() calls.
It removes the mapper entries from the list and sets their pointers
to NULL without freeing the allocated array. This leaks memory each
time dao_clear_input() is called.
Store the base pointer of the allocation before clearing the mapper
entries and free the array after removing entries from the list.
Fixes: e576e7843c0d ("ALSA: ctxfi: Simplify dao_clear_{left,right}_input() functions")
Cc: stable@vger.kernel.org
Signed-off-by: Harin Lee <me@harin.net>
Link: https://patch.msgid.link/20261001144501.3050667-2-me@harin.net
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/pci/ctxfi/ctdaio.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/sound/pci/ctxfi/ctdaio.c
+++ b/sound/pci/ctxfi/ctdaio.c
@@ -221,14 +221,18 @@ static int dao_set_right_input(struct da
static int dao_clear_input(struct dao *dao, unsigned int start, unsigned int end)
{
+ struct imapper *entry;
unsigned int i;
- if (!dao->imappers[start])
+ entry = dao->imappers[start];
+ if (!entry)
return 0;
+
for (i = start; i < end; i++) {
dao->mgr->imap_delete(dao->mgr, dao->imappers[i]);
dao->imappers[i] = NULL;
}
+ kfree(entry);
return 0;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 019/281] ALSA: hda/tas2781: Accept V1 calibration data without CRC
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (17 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 018/281] ALSA: ctxfi: Fix memory leakage when clearing DAO input mappers Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 020/281] arm64: irq: exclude the softirq stack switch from KCOV Greg Kroah-Hartman
` (268 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Mohamed Yassine Jebabli,
Takashi Iwai
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohamed Yassine Jebabli <med.jebabli@gmail.com>
commit 408249089c48df1a4d23f60b831be3f3c311e6d1 upstream.
Some Lenovo BIOSes (e.g. Legion Pro 7 16IRX9H, SSID 17aa:38cd) store
valid V1 calibration data in the CALI_DATA EFI variable but leave the
TimeStamp and CRC fields zeroed. The driver rejects such data, so the
amplifiers always run with default parameters on these machines.
The rejection was silent until
commit 4fe238513407 ("ALSA: hda/tas2781: Move and unified the
calibrated-data getting function for SPI and I2C into the tas2781_hda lib")
turned it into "V1 CRC error".
The stored values are consistent (R0 = 3.82/3.83 ohm, 1/R0 matching
within 1e-4), so accept V1 data when both TimeStamp and CRC are zero
and the first device entry is non-zero, and emit a warning.
Fixes: 5be27f1e3ec9 ("ALSA: hda/tas2781: Add tas2781 HDA driver")
Cc: stable@vger.kernel.org
Signed-off-by: Mohamed Yassine Jebabli <med.jebabli@gmail.com>
Link: https://patch.msgid.link/20261001-tas2781-v1-nocrc-v1-1-ff0c1032ce76@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/hda/codecs/side-codecs/tas2781_hda.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
--- a/sound/hda/codecs/side-codecs/tas2781_hda.c
+++ b/sound/hda/codecs/side-codecs/tas2781_hda.c
@@ -139,9 +139,21 @@ static void tas2781_apply_calib(struct t
*/
crc = crc32(~0, data, 84) ^ ~0;
if (crc != tmp_val[21]) {
- cali_data->total_sz = 0;
- dev_err(p->dev, "%s: V1 CRC error\n", __func__);
- return;
+ /*
+ * Some Lenovo BIOSes (e.g. Legion Pro 7 16IRX9H,
+ * SSID 17aa:38cd) store valid V1 calibration data
+ * but leave TimeStamp and CRC zeroed.
+ */
+ if (!tmp_val[20] && !tmp_val[21] &&
+ tmp_val[0] && tmp_val[1]) {
+ dev_warn(p->dev,
+ "%s: V1 data without CRC, accepting\n",
+ __func__);
+ } else {
+ cali_data->total_sz = 0;
+ dev_err(p->dev, "%s: V1 CRC error\n", __func__);
+ return;
+ }
}
for (j = p->ndev - 1; j >= 0; j--) {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 020/281] arm64: irq: exclude the softirq stack switch from KCOV
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (18 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 019/281] ALSA: hda/tas2781: Accept V1 calibration data without CRC Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 021/281] ASoC: amd: yc: Add DMI quirk for Acer Aspire Go 15 (AG15-21P) Greg Kroah-Hartman
` (267 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Will Deacon
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
commit a9cd14bfb0c113f1cd77be4349784663bec71bb4 upstream.
On IRQ exit, __irq_exit_rcu() drops HARDIRQ_OFFSET before calling
invoke_softirq(). The arm64 do_softirq_own_stack() wrapper and its
____do_softirq() trampoline run before __do_softirq() establishes
softirq context, so KCOV records their PCs in the interrupted task's
coverage buffer. They also run outside softirq accounting when
local_bh_enable() reaches do_softirq().
The IRQ-exit coverage makes the KCOV boot selftest fail even after
the scheduler and timer coverage leaks are suppressed. The generic
softirq.o is already excluded from KCOV, but that exclusion does not
cover the separately compiled arm64 wrappers.
Exclude irq.o from KCOV instrumentation, as is already done for the
arm64 entry code. This covers both wrappers even with compilers that
lack the no_sanitize_coverage attribute. The softirq action functions
remain instrumented for explicit remote coverage.
Fixes: 8eb858c44b98 ("arm64: run softirqs on the per-CPU IRQ stack")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/kernel/Makefile | 3 +++
1 file changed, 3 insertions(+)
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -25,6 +25,9 @@ KASAN_SANITIZE_stacktrace.o := n
KCOV_INSTRUMENT_entry-common.o := n
KCOV_INSTRUMENT_idle.o := n
+# Softirq stack switching can run outside interrupt context.
+KCOV_INSTRUMENT_irq.o := n
+
# Object file lists.
obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
entry-common.o process.o ptrace.o \
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 021/281] ASoC: amd: yc: Add DMI quirk for Acer Aspire Go 15 (AG15-21P)
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (19 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 020/281] arm64: irq: exclude the softirq stack switch from KCOV Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 022/281] ata: libata-scsi: do not lose CHECK CONDITION for failed ATAPI commands Greg Kroah-Hartman
` (266 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Michael Garland, Mark Brown
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Garland <minimelkav@gmail.com>
commit d0cb7a7b2a490c381ad97f53155d02a748b60dea upstream.
The Acer Aspire Go 15 (AG15-21P, board MDC Herbag2_MDU) has two PDM
DMICs connected to the ACP. The BIOS does not set the AcpDmicConnected
_DSD property, so the acp6x machine driver never registers the DMIC
card. The existing Herbag_MDU entry does not match this board name, so
add a DMI quirk for it.
Tested on BIOS V1.11: the acp6x DMIC capture device is registered and
records audio on both channels.
Cc: stable@vger.kernel.org
Signed-off-by: Michael Garland <minimelkav@gmail.com>
Link: https://patch.msgid.link/20261005-acp6x-herbag2-quirk-v1-1-a1f2683d758f@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/soc/amd/yc/acp6x-mach.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/sound/soc/amd/yc/acp6x-mach.c
+++ b/sound/soc/amd/yc/acp6x-mach.c
@@ -762,6 +762,13 @@ static const struct dmi_system_id yc_acp
{
.driver_data = &acp6x_card,
.matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "MDC"),
+ DMI_MATCH(DMI_BOARD_NAME, "Herbag2_MDU"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "System76"),
DMI_MATCH(DMI_PRODUCT_VERSION, "pang12"),
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 022/281] ata: libata-scsi: do not lose CHECK CONDITION for failed ATAPI commands
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (20 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 021/281] ASoC: amd: yc: Add DMI quirk for Acer Aspire Go 15 (AG15-21P) Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 023/281] btrfs: scrub: fix local_root reference leak in scrub_print_warning_inode() Greg Kroah-Hartman
` (265 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Niklas Cassel, Hengyu Liang,
Damien Le Moal
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengyu Liang <hengyul@cs.unc.edu>
commit bc8ce2cea5f77c4bd1a5184705e300e83546c0c4 upstream.
Since commit 2e1d2e65e773 ("ata: libata-scsi: terminate deferred commands
on time out"), atapi_qc_complete() sets SAM_STAT_CHECK_CONDITION for a
failed command only if cmd->result is zero, so that the DID_TIME_OUT or
DID_REQUEUE host byte of a terminated command is preserved.
However, cmd->result can also be non-zero for a regular failed ATAPI
command completed through libata EH: ata_eh_analyze_tf() calls
ata_eh_decide_disposition(), that is, scsi_check_sense(), on the sense
data obtained with REQUEST SENSE, and scsi_check_sense() sets the SCSI
midlayer internal byte of the result for some sense codes, e.g.
SCSIML_STAT_TGT_FAILURE for ILLEGAL REQUEST with ASC 0x20 (INVALID
COMMAND OPERATION CODE) or 0x24 (INVALID FIELD IN CDB), or
SCSIML_STAT_MED_ERROR for MEDIUM ERROR with ASC 0x11 (UNRECOVERED READ
ERROR). For such commands, atapi_qc_complete() keeps the result as is and
the command completes with a GOOD status byte, even though it failed and
valid sense data is available.
As a result, passthrough users see these failed ATAPI commands as
successful. For example, with the emulated IDE CD-ROM drive of QEMU and
no medium loaded, a PLAY AUDIO MSF command issued with SG_IO completes
with status 0x00 (and no DRIVER_SENSE) instead of 0x02 (CHECK CONDITION)
with sense key ILLEGAL REQUEST, ASC/ASCQ 0x20/0x00, and the CDROM ioctls
CDROMPLAYTRKIND, CDROMSUBCHNL, CDROMPAUSE, CDROMRESUME, CDROMPLAYMSF and
CDROM_GET_MCN return 0 instead of -ENOMEDIUM or -EOPNOTSUPP.
Fix this by setting the status byte to SAM_STAT_CHECK_CONDITION whenever
the host byte is not set. Use set_status_byte() rather than overwriting
the whole result, so that the SCSI midlayer internal byte set by
scsi_check_sense() is preserved, as ata_scsi_qc_complete() already does
for ATA commands.
Fixes: 2e1d2e65e773 ("ata: libata-scsi: terminate deferred commands on time out")
Cc: stable@vger.kernel.org
Suggested-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Hengyu Liang <hengyul@cs.unc.edu>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Link: https://lore.kernel.org/r/20260929164135.266708-1-hengyul@cs.unc.edu
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/ata/libata-scsi.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3026,10 +3026,15 @@ static void atapi_qc_complete(struct ata
if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev)
qc->dev->sdev->locked = 0;
- if (cmd->result)
- ata_scsi_qc_done(qc, false, 0);
- else
- ata_scsi_qc_done(qc, true, SAM_STAT_CHECK_CONDITION);
+ /*
+ * Report CHECK CONDITION unless the command was terminated
+ * with a host byte set. Only set the status byte, so that the
+ * SCSI midlayer internal byte, which scsi_check_sense() may
+ * have set from the sense data, is preserved.
+ */
+ if (get_host_byte(cmd) == DID_OK)
+ set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);
+ ata_scsi_qc_done(qc, false, 0);
goto schedule_deferred;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 023/281] btrfs: scrub: fix local_root reference leak in scrub_print_warning_inode()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (21 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 022/281] ata: libata-scsi: do not lose CHECK CONDITION for failed ATAPI commands Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 024/281] can: dev: init_can_skb(): restore skb header initialization Greg Kroah-Hartman
` (264 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Wentao Liang,
David Sterba
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit 1fd742c7479961da6d0bb794ef8ac6b7b9442847 upstream.
When paths_from_inode() fails, scrub_print_warning_inode() jumps to err
without dropping the reference taken by btrfs_get_fs_root(), leaking a
reference to the root every time path resolution fails while printing
scrub warnings. Every other error and success path of the function
drops the reference.
Drop the reference on the paths_from_inode() failure path too.
Fixes: 558540c17771 ("btrfs scrub: print paths of corrupted files")
CC: stable@vger.kernel.org
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/btrfs/scrub.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -550,8 +550,10 @@ static int scrub_print_warning_inode(u64
}
ret = paths_from_inode(inum, ipath);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_put_root(local_root);
goto err;
+ }
/*
* we deliberately ignore the bit ipath might have been too small to
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 024/281] can: dev: init_can_skb(): restore skb header initialization
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (22 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 023/281] btrfs: scrub: fix local_root reference leak in scrub_print_warning_inode() Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 025/281] can: fix unique skb identifier regression under RPS Greg Kroah-Hartman
` (263 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oliver Hartkopp, zjamg, Quchaosheng,
Shaunak Datar, Marc Kleine-Budde
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: zjamg <ndaugoing@gmail.com>
commit 0a04c0cb8606ff88399489d03ef255afe90d0d5f upstream.
Commit 9f10374bb024 ("can: remove private CAN skb headroom infrastructure")
removed the skb_reset_mac_header()/skb_reset_network_header()/
skb_reset_transport_header() calls from init_can_skb(). As a result, RX
skbs from alloc_can_skb() and friends again carry mac_header = 0xFFFF.
When such an skb reaches packet_rcv_spkt() (SOCK_PACKET), the push length
calculation overflows and triggers skb_under_panic -> kernel BUG -> full
machine panic.
The same issue was originally reported in 2014 on linux-can and fixed by
commit 969439016d2c ("can: add missing initialisations in CAN related
skbuffs"). packet_rcv_spkt() itself has never been hardened: only
packet_rcv() and tpacket_rcv() gained dev_has_header() checks in
commit d549699048b4 ("net/packet: fix packet receive on L3 devices
without visible hard header").
Fixes: 9f10374bb024 ("can: remove private CAN skb headroom infrastructure")
Cc: stable@vger.kernel.org
Reviewed-by: Oliver Hartkopp <socketcan@hartkopp.net>
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: zjamg <ndaugoing@gmail.com>
Tested-by: Quchaosheng <quchaosheng000406@163.com>
Link: https://patch.msgid.link/20260917123716.63116-1-ndaugoing@gmail.com
Reported-by: Shaunak Datar <shaunakkdatar@gmail.com>
Closes: https://lore.kernel.org/all/20260918151606.765490-1-shaunakkdatar@gmail.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/can/dev/skb.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -210,6 +210,10 @@ static void init_can_skb(struct sk_buff
{
skb->pkt_type = PACKET_BROADCAST;
skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
+ skb_reset_transport_header(skb);
}
struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 025/281] can: fix unique skb identifier regression under RPS
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (23 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 024/281] can: dev: init_can_skb(): restore skb header initialization Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 026/281] cgroup/cpuset: Handle cpu hotplug race in guarantee_active_cpus() Greg Kroah-Hartman
` (262 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joerg Willmann, Oliver Hartkopp,
Marc Kleine-Budde
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
commit 7093c3b8314a4ef7405c4066a2521398c455efe7 upstream.
Commit d4fb6514ff8e ("can: use skb hash instead of private variable in
headroom") moved the per-skb unique identifier used for raw_rcv()
duplicate detection into skb->hash.
With RPS enabled, get_rps_cpu() calls skb_get_hash() before the frame
reaches the CAN subsystem. Since CAN skbs have no L3/L4 headers, the
flow dissector assigns every CAN frame the same non-zero software
hash. can_set_skb_uid() only generated a new identifier when
skb->hash was 0, so it kept this constant hash. When the SLAB
allocator later reused the same skb address, raw_rcv() mistook the
next legitimate frame for a duplicate and dropped it.
Fix this by storing the CAN UID in the CAN skb extension
(struct can_skb_ext::can_skb_uid) instead of skb->hash, decoupling it
from any hash the network stack may compute. can_set_skb_uid() keeps
its "assign only if unset" behaviour, which preserves UIDs set before
transmission (e.g. by isotp to identify echo frames) across the local
loopback path.
Frames whose extension is shared with another clone (e.g. via tc mirred
or netem duplicate) are given a private extension copy before the UID
is assigned, so that independently received skb clones from real CAN
interfaces (can_skb_uid = 0) don't end up with the same UID.
The limitation that tc mirred/netem skb duplicates might be dropped in
raw_rcv for looped back isotp echo frame skbs is accepted. There is no
valid use-case for tc mirred or netem together with isotp which is not
capable to operate on different CAN interfaces simultaneously.
For routing and modifying CAN frames together with isotp use can-gw.
can-gw and vxcan additionally clear the UID of forwarded/duplicated
frames so each newly routed frame gets its own unique identifier.
Fixes: d4fb6514ff8e ("can: use skb hash instead of private variable in headroom")
Reported-by: Joerg Willmann <joe@clnt.de>
Closes: https://lore.kernel.org/linux-can/2859AD3D-C805-41A0-9036-C5E8EE152419@clnt.de/
Cc: stable@vger.kernel.org
Tested-by: Oliver Hartkopp <socketcan@hartkopp.net>
Tested-by: Joerg Willmann <joe@clnt.de>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20261001115724.27192-1-socketcan@hartkopp.net
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/can/vxcan.c | 3 +++
include/linux/can/core.h | 3 ++-
include/linux/can/skb.h | 4 +++-
include/net/can.h | 2 ++
net/can/af_can.c | 47 ++++++++++++++++++++++++++++++++++++-----------
net/can/gw.c | 3 +++
net/can/isotp.c | 16 ++++++++++------
net/can/raw.c | 10 +++++++---
8 files changed, 66 insertions(+), 22 deletions(-)
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -78,6 +78,9 @@ static netdev_tx_t vxcan_xmit(struct sk_
/* reset CAN GW hop counter */
csx->can_gw_hops = 0;
+ /* start with new CAN skb UID in the other namespace */
+ csx->can_skb_uid = 0;
+
skb->pkt_type = PACKET_BROADCAST;
skb->dev = peer;
skb->ip_summed = CHECKSUM_UNNECESSARY;
--- a/include/linux/can/core.h
+++ b/include/linux/can/core.h
@@ -17,6 +17,7 @@
#include <linux/can.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <net/can.h>
#define DNAME(dev) ((dev) ? (dev)->name : "any")
@@ -58,7 +59,7 @@ extern void can_rx_unregister(struct net
void *data);
extern int can_send(struct sk_buff *skb, int loop);
-void can_set_skb_uid(struct sk_buff *skb);
+void can_set_skb_uid(struct can_skb_ext *csx);
void can_sock_destruct(struct sock *sk);
#endif /* !_CAN_CORE_H */
--- a/include/linux/can/skb.h
+++ b/include/linux/can/skb.h
@@ -43,8 +43,10 @@ static inline struct can_skb_ext *can_sk
struct can_skb_ext *csx = skb_ext_add(skb, SKB_EXT_CAN);
/* skb_ext_add() returns uninitialized space */
- if (csx)
+ if (csx) {
csx->can_gw_hops = 0;
+ csx->can_skb_uid = 0;
+ }
return csx;
}
--- a/include/net/can.h
+++ b/include/net/can.h
@@ -17,12 +17,14 @@
* @can_framelen: cached echo CAN frame length for bql
* @can_gw_hops: can-gw CAN frame time-to-live counter
* @can_ext_flags: CAN skb extensions flags
+ * @can_skb_uid: CAN skb UID for raw_rcv and isotp echo handling
*/
struct can_skb_ext {
int can_iif;
u16 can_framelen;
u8 can_gw_hops;
u8 can_ext_flags;
+ u32 can_skb_uid;
};
#endif /* _NET_CAN_H */
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -641,13 +641,10 @@ static int can_rcv_filter(struct can_dev
return matches;
}
-void can_set_skb_uid(struct sk_buff *skb)
+void can_set_skb_uid(struct can_skb_ext *csx)
{
- /* create non-zero unique skb identifier together with *skb */
- while (!(skb->hash))
- skb->hash = atomic_inc_return(&skbcounter);
-
- skb->sw_hash = 1;
+ while (!(csx->can_skb_uid))
+ csx->can_skb_uid = atomic_inc_return(&skbcounter);
}
EXPORT_SYMBOL(can_set_skb_uid);
@@ -662,8 +659,6 @@ static void can_receive(struct sk_buff *
atomic_long_inc(&pkg_stats->rx_frames);
atomic_long_inc(&pkg_stats->rx_frames_delta);
- can_set_skb_uid(skb);
-
rcu_read_lock();
/* deliver the packet to sockets listening on all devices */
@@ -687,8 +682,10 @@ static void can_receive(struct sk_buff *
static int can_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
+ struct can_skb_ext *csx = can_skb_ext_find(skb);
+
if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) ||
- !can_skb_ext_find(skb) || !can_is_can_skb(skb))) {
+ !csx || !can_is_can_skb(skb))) {
pr_warn_once("PF_CAN: dropped non conform CAN skbuff: dev type %d, len %d\n",
dev->type, skb->len);
@@ -696,6 +693,14 @@ static int can_rcv(struct sk_buff *skb,
return NET_RX_DROP;
}
+ /* create unshared CAN skb_extension for netem/mirred skb clones */
+ csx = skb_ext_add(skb, SKB_EXT_CAN);
+ if (unlikely(!csx)) {
+ kfree_skb_reason(skb, SKB_DROP_REASON_NOMEM);
+ return NET_RX_DROP;
+ }
+
+ can_set_skb_uid(csx);
can_receive(skb, dev);
return NET_RX_SUCCESS;
}
@@ -703,8 +708,10 @@ static int can_rcv(struct sk_buff *skb,
static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
+ struct can_skb_ext *csx = can_skb_ext_find(skb);
+
if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) ||
- !can_skb_ext_find(skb) || !can_is_canfd_skb(skb))) {
+ !csx || !can_is_canfd_skb(skb))) {
pr_warn_once("PF_CAN: dropped non conform CAN FD skbuff: dev type %d, len %d\n",
dev->type, skb->len);
@@ -712,6 +719,14 @@ static int canfd_rcv(struct sk_buff *skb
return NET_RX_DROP;
}
+ /* create unshared CAN skb_extension for netem/mirred skb clones */
+ csx = skb_ext_add(skb, SKB_EXT_CAN);
+ if (unlikely(!csx)) {
+ kfree_skb_reason(skb, SKB_DROP_REASON_NOMEM);
+ return NET_RX_DROP;
+ }
+
+ can_set_skb_uid(csx);
can_receive(skb, dev);
return NET_RX_SUCCESS;
}
@@ -719,8 +734,10 @@ static int canfd_rcv(struct sk_buff *skb
static int canxl_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
+ struct can_skb_ext *csx = can_skb_ext_find(skb);
+
if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) ||
- !can_skb_ext_find(skb) || !can_is_canxl_skb(skb))) {
+ !csx || !can_is_canxl_skb(skb))) {
pr_warn_once("PF_CAN: dropped non conform CAN XL skbuff: dev type %d, len %d\n",
dev->type, skb->len);
@@ -728,6 +745,14 @@ static int canxl_rcv(struct sk_buff *skb
return NET_RX_DROP;
}
+ /* create unshared CAN skb_extension for netem/mirred skb clones */
+ csx = skb_ext_add(skb, SKB_EXT_CAN);
+ if (unlikely(!csx)) {
+ kfree_skb_reason(skb, SKB_DROP_REASON_NOMEM);
+ return NET_RX_DROP;
+ }
+
+ can_set_skb_uid(csx);
can_receive(skb, dev);
return NET_RX_SUCCESS;
}
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -527,6 +527,9 @@ static void can_can_gw_rcv(struct sk_buf
/* put the incremented hop counter in the cloned skb */
ncsx->can_gw_hops = csx->can_gw_hops + 1;
+ /* force a new CAN UID generation for the routed frame */
+ ncsx->can_skb_uid = 0;
+
/* first processing of this CAN frame -> adjust to private hop limit */
if (gwj->limit_hops && ncsx->can_gw_hops == 1)
ncsx->can_gw_hops = max_hops - gwj->limit_hops + 1;
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -891,7 +891,7 @@ static void isotp_send_cframe(struct iso
csx->can_iif = dev->ifindex;
/* set uid in tx skb to identify CF echo frames */
- can_set_skb_uid(skb);
+ can_set_skb_uid(csx);
cf = (struct canfd_frame *)skb->data;
skb_put_zero(skb, so->ll.mtu);
@@ -917,7 +917,7 @@ static void isotp_send_cframe(struct iso
pr_notice_once("can-isotp: cfecho is %08X != 0\n", old_cfecho);
/* set consecutive frame echo tag */
- WRITE_ONCE(so->cfecho, skb->hash);
+ WRITE_ONCE(so->cfecho, csx->can_skb_uid);
/* send frame with local echo enabled */
can_send_ret = can_send(skb, 1);
@@ -969,18 +969,22 @@ static void isotp_rcv_echo(struct sk_buf
{
struct sock *sk = (struct sock *)data;
struct isotp_sock *so = isotp_sk(sk);
+ struct can_skb_ext *csx = can_skb_ext_find(skb);
/* only handle my own local echo CF/SF skb's (no FF!) */
if (skb->sk != sk)
return;
+ if (WARN_ON_ONCE(!csx))
+ return;
+
/* unlike isotp_rcv_fc()/isotp_rcv_cf(), not already under so->rx_lock
* (no isotp_rcv() caller here), so take it ourselves
*/
spin_lock(&so->rx_lock);
/* so->cfecho may since belong to a new transfer; recheck under lock */
- if (READ_ONCE(so->cfecho) != skb->hash)
+ if (READ_ONCE(so->cfecho) != csx->can_skb_uid)
goto out_unlock;
/* cancel local echo timeout */
@@ -1222,7 +1226,7 @@ static int isotp_sendmsg(struct socket *
csx->can_iif = dev->ifindex;
/* set uid in tx skb to identify CF echo frames */
- can_set_skb_uid(skb);
+ can_set_skb_uid(csx);
so->tx.len = size;
so->tx.idx = 0;
@@ -1261,7 +1265,7 @@ static int isotp_sendmsg(struct socket *
cf->data[ae] |= size;
/* set CF echo tag for isotp_rcv_echo() (SF-mode) */
- WRITE_ONCE(so->cfecho, skb->hash);
+ WRITE_ONCE(so->cfecho, csx->can_skb_uid);
} else {
/* send first frame */
@@ -1278,7 +1282,7 @@ static int isotp_sendmsg(struct socket *
so->txfc.bs = 0;
/* set CF echo tag for isotp_rcv_echo() (CF-mode) */
- WRITE_ONCE(so->cfecho, skb->hash);
+ WRITE_ONCE(so->cfecho, csx->can_skb_uid);
} else {
/* standard flow control check */
new_state = ISOTP_WAIT_FIRST_FC;
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -77,7 +77,7 @@ MODULE_ALIAS("can-proto-1");
struct uniqframe {
const struct sk_buff *skb;
- u32 hash;
+ u32 can_skb_uid;
unsigned int join_rx_count;
};
@@ -133,12 +133,16 @@ static void raw_rcv(struct sk_buff *oskb
enum skb_drop_reason reason;
struct sockaddr_can *addr;
struct sk_buff *skb;
+ struct can_skb_ext *csx = can_skb_ext_find(oskb);
unsigned int *pflags;
/* check the received tx sock reference */
if (!ro->recv_own_msgs && oskb->sk == sk)
return;
+ if (WARN_ON_ONCE(!csx))
+ return;
+
/* make sure to not pass oversized frames to the socket */
if (!ro->fd_frames && can_is_canfd_skb(oskb))
return;
@@ -165,7 +169,7 @@ static void raw_rcv(struct sk_buff *oskb
/* eliminate multiple filter matches for the same skb */
if (this_cpu_ptr(ro->uniq)->skb == oskb &&
- this_cpu_ptr(ro->uniq)->hash == oskb->hash) {
+ this_cpu_ptr(ro->uniq)->can_skb_uid == csx->can_skb_uid) {
if (!ro->join_filters)
return;
@@ -175,7 +179,7 @@ static void raw_rcv(struct sk_buff *oskb
return;
} else {
this_cpu_ptr(ro->uniq)->skb = oskb;
- this_cpu_ptr(ro->uniq)->hash = oskb->hash;
+ this_cpu_ptr(ro->uniq)->can_skb_uid = csx->can_skb_uid;
this_cpu_ptr(ro->uniq)->join_rx_count = 1;
/* drop first frame to check all enabled filters? */
if (ro->join_filters && ro->count > 1)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 026/281] cgroup/cpuset: Handle cpu hotplug race in guarantee_active_cpus()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (24 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 025/281] can: fix unique skb identifier regression under RPS Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 027/281] cipso: adjust cached option offsets when removing CIPSO Greg Kroah-Hartman
` (261 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Farhad Alemi, Waiman Long, Tejun Heo
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <longman@redhat.com>
commit 23b1ab15ca91f2cffaf149d9bb0fafeb700c7db2 upstream.
With commit 2125c0034c5d ("cgroup/cpuset: Make cpuset hotplug processing
synchronous"), the cpuset hotplug operation becomes synchronous. That
commit also removes the code that handles race between cpuset_hotplug_work
and cpu hotplug notifier with the assumption that race is now gone.
Later commit 7a0aabd9ce69 ("cgroup/cpuset: Always use cpu_active_mask")
updates the cpuset code to always use cpu_active_mask instead of
cpu_online_mask in some places including guarantee_online_cpus() which
is renamed to guarantee_active_cpus() in that commit.
In the case of CPU offline operation, cpu_active_mask is updated
first in sched_cpu_deactivate() to remove the offline CPU before
cpuset_handle_hotplug() is called to update the effective_cpus of the
affected cpusets. The cpu_online_mask is updated after that near the end
of the offline operation to remove the offline CPU. As a result, the race
comes back and the top cpuset may not have any active CPU leading to NULL
pointer dereference during the race window when guarantee_active_cpus()
is called after cpu_active_mask is updated to remove the CPU to be torn
down but before cpuset_handle_hotplug() is able to properly update the
effective_cpus of the top cpuset.
Fix this by adding back the NULL cs check to avoid this problem.
Fixes: 7a0aabd9ce69 ("cgroup/cpuset: Always use cpu_active_mask")
Cc: stable@vger.kernel.org # v6.16+
Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Link: https://lore.kernel.org/lkml/CA+0ovChh3VjsKN1g+ZGjwwY2fGTpP7uD+aCCByLj5Qbymw=bfQ@mail.gmail.com
Signed-off-by: Waiman Long <longman@redhat.com>
Tested-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/cgroup/cpuset.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -478,10 +478,26 @@ static void guarantee_active_cpus(struct
rcu_read_lock();
cs = task_cs(tsk);
- while (!cpumask_intersects(cs->effective_cpus, pmask))
+ while (!cpumask_intersects(cs->effective_cpus, pmask)) {
cs = parent_cs(cs);
-
+ if (unlikely(!cs)) {
+ /*
+ * The top cpuset doesn't have any active cpu as a
+ * consequence of a race between its caller and the cpu
+ * hotplug operation where cpu_active_mask is updated
+ * asynchronously before cpuset_handle_hotplug() is
+ * being called to adjust the effective_cpus of the
+ * affected cpusets. But we know the top cpuset's
+ * effective_cpus is on its way to be identical to
+ * cpu_active_mask minus the exclusive CPUs dedicated
+ * to other valid cpuset partitions. Just pass back
+ * the filtered cpu_active_mask in this case.
+ */
+ goto out_unlock;
+ }
+ }
cpumask_and(pmask, pmask, cs->effective_cpus);
+out_unlock:
rcu_read_unlock();
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 027/281] cipso: adjust cached option offsets when removing CIPSO
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (25 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 026/281] cgroup/cpuset: Handle cpu hotplug race in guarantee_active_cpus() Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 028/281] dm ioctl: dont let data_start run past the buffer Greg Kroah-Hartman
` (260 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ondrej Mosnáček,
Daehyeon Ko, Paul Moore, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit 6d25ffca055a77787c21a36b66c253f76239411b upstream.
cipso_v4_skbuff_delattr() removes the CIPSO bytes but does not adjust
cached offsets for options that follow them.
For example, with a valid 10-byte CIPSO option followed by a seven-byte
RR option, parsing records rr at offset 30. Removing CIPSO moves RR to
offset 20, while the cached offset remains 30. Consumers such as
ip_forward_options() and __ip_options_echo() then access the wrong bytes;
the latter may interpret packet data as the option length and copy it into
fixed-size option storage.
Mirror cipso_v4_delopt() and subtract cipso_len from the srr, rr, ts and
router_alert offsets when they follow CIPSO. cipso_len is the distance
the first memmove() shifts those options. The later header move and
network-header reset relocate the bytes and their offset base together.
Fixes: 89aa3619d141 ("cipso: make cipso_v4_skbuff_delattr() fully remove the CIPSO options")
Cc: stable@vger.kernel.org
Reviewed-by: Ondrej Mosnáček <omosnacek@gmail.com>
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Link: https://patch.msgid.link/20261006035108.3101440-1-4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/cipso_ipv4.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -2287,6 +2287,14 @@ int cipso_v4_skbuff_delattr(struct sk_bu
new_hdr_len - new_hdr_len_actual);
opt->optlen -= hdr_len_delta;
+ if (opt->srr > opt->cipso)
+ opt->srr -= cipso_len;
+ if (opt->rr > opt->cipso)
+ opt->rr -= cipso_len;
+ if (opt->ts > opt->cipso)
+ opt->ts -= cipso_len;
+ if (opt->router_alert > opt->cipso)
+ opt->router_alert -= cipso_len;
opt->cipso = 0;
opt->is_changed = 1;
if (hdr_len_delta != 0) {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 028/281] dm ioctl: dont let data_start run past the buffer
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (26 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 027/281] cipso: adjust cached option offsets when removing CIPSO Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 029/281] usb: f81604: fix struct f81604_int_data size mismatch Greg Kroah-Hartman
` (259 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+48d935cf48a4a76be346,
Palla Raghunath, Mikulas Patocka
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Palla Raghunath <raghunathpalla.0209@gmail.com>
commit 9b3fcf519d370df94a56f3b272d9eddffffa5be8 upstream.
struct dm_ioctl has seven bytes of trailing padding, so the smallest
buffer userspace is allowed to ask for, offsetof(struct dm_ioctl, data),
is seven bytes shorter than sizeof(struct dm_ioctl).
get_result_buffer() sets data_start to sizeof(struct dm_ioctl) without
looking at how big the buffer actually is. Ask for the minimum and
data_start ends up seven bytes past the end. Callers add it to
data_size, and ctl_ioctl() copies that much back to userspace:
BUG: KASAN: slab-out-of-bounds in _copy_to_user+0xad/0xd0
Read of size 312 at addr ffff8880169e4c00 by task repro-dm/140
ctl_ioctl+0x5e3/0xcb0
dm_ctl_ioctl+0x25/0x40
allocated 305-byte region [ffff8880169e4c00, ffff8880169e4d31)
A DM_LIST_DEVICES with data_size set to 305 is enough to hit it, and the
seven bytes that leak are whatever sat next to the allocation.
Clamp data_start to the buffer size.
Note that this is not a security bug because the out-of-bounds read can
only be triggered by root.
Reported-by: syzbot+48d935cf48a4a76be346@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=48d935cf48a4a76be346
Fixes: 76c072b48e39 ("dm ioctl: move compat code")
Cc: stable@vger.kernel.org
Signed-off-by: Palla Raghunath <raghunathpalla.0209@gmail.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/md/dm-ioctl.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -658,10 +658,16 @@ static void *get_result_buffer(struct dm
{
param->data_start = align_ptr(param + 1) - (void *) param;
- if (param->data_start < param_size)
+ if (param->data_start < param_size) {
*len = param_size - param->data_start;
- else
+ } else {
+ /*
+ * The buffer can be as small as offsetof(*param, data), which
+ * is less than sizeof(*param), so don't run off the end of it.
+ */
*len = 0;
+ param->data_start = param_size;
+ }
return ((void *) param) + param->data_start;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 029/281] usb: f81604: fix struct f81604_int_data size mismatch
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (27 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 028/281] dm ioctl: dont let data_start run past the buffer Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 030/281] vsock/virtio: account only unread bytes in read_skb() Greg Kroah-Hartman
` (258 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dynetrex, Admin,
Ji-Ze Hong (Peter Hong), Drew Willey, Marc Kleine-Budde
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ji-Ze Hong (Peter Hong) <peter_hong@fintek.com.tw>
commit 7f85d1170575645f9f327062d78017a23b2714eb upstream.
The struct f81604_int_data defines 9 bytes of interrupt data:
- Byte 0: Status register (sr)
- Byte 1: Interrupt register (isrc)
- Byte 2: Interrupt enable register (ier)
- Byte 3: Arbitration lost capture (alc)
- Byte 4: Error code capture (ecc)
- Byte 5: Error warning limit register (ewlr)
- Byte 6: RX error counter (rxerr)
- Byte 7: TX error counter (txerr)
- Byte 8: Reserved (val)
The hardware sends exactly 9 bytes for the interrupt endpoint.
However, the struct was defined with __aligned(4) attribute which
caused the compiler to pad the struct to 12 bytes.
This causes a problem in f81604_read_int_callback() where the short
URB check compares urb->actual_length against sizeof(*data). When
sizeof(struct f81604_int_data) is 12 but the hardware only sends 9
bytes, the check fails and valid interrupt messages are discarded.
This results in the driver only being able to transmit once because
the TX complete interrupt is never processed.
Fix this by removing the __aligned(4) attribute so the struct size
matches the actual hardware data size of 9 bytes.
Fixes: 7299b1b39a25 ("can: usb: f81604: handle short interrupt urb messages properly")
Cc: stable@vger.kernel.org
Reported-by: Dynetrex, Admin <admin@dynetrex.com>
Closes: https://lore.kernel.org/all/A3834A07-5639-4779-844F-C5843DFC3928@dynetrex.com/
Signed-off-by: Ji-Ze Hong (Peter Hong) <peter_hong@fintek.com.tw>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Tested-by: Drew Willey <dwilley@google.com>
Link: https://patch.msgid.link/20260824-f81604-fix-v2-1-fc9be5581394@fintek.com.tw
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/can/usb/f81604.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/can/usb/f81604.c
+++ b/drivers/net/can/usb/f81604.c
@@ -169,7 +169,7 @@ struct f81604_int_data {
u8 rxerr;
u8 txerr;
u8 val;
-} __packed __aligned(4);
+} __packed;
struct f81604_sff {
__be16 id;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 030/281] vsock/virtio: account only unread bytes in read_skb()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (28 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 029/281] usb: f81604: fix struct f81604_int_data size mismatch Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 031/281] wifi: brcmfmac: fix P2P device removal race in brcmf_detach() Greg Kroah-Hartman
` (257 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luigi Leonardi, Daehyeon Ko,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit a463f55c791b96cfd12df8b10ea737d45c80bb18 upstream.
After a partial stream receive, rx_bytes tracks the unread suffix while
buf_used and peer credit still cover the whole packet.
virtio_transport_read_skb() dequeues that packet but passes pkt_len for
both counters, underflowing rx_bytes.
On a connected CID_LOCAL stream with an SK_SKB verdict, a 40-byte read
from a 100-byte packet made SIOCINQ report -40, an empty recv return
ELOOP, and poll report the empty socket readable. After verdict detach,
receiving 40 bytes wrapped the counter to zero and hid those queued bytes
until one more byte arrived. The fixed run kept the counter balanced
and exposed all queued data immediately.
This was found during an LLM-assisted manual source audit of VSOCK
receive accounting while re-evaluating virtio_transport_read_skb() after
CVE-2024-50169.
Subtract only skb->len minus the VSOCK offset from rx_bytes. Retain the
full packet length for buf_used and peer credit.
Fixes: 45ca7e9f0730 ("vsock/virtio: fix `rx_bytes` accounting for stream sockets")
Cc: stable@vger.kernel.org
Reviewed-by: Luigi Leonardi <leonardi@redhat.com>
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Link: https://patch.msgid.link/20261001151310.4101006-1-4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/vmw_vsock/virtio_transport_common.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -1916,6 +1916,7 @@ int virtio_transport_read_skb(struct vso
struct sock *sk = sk_vsock(vsk);
struct virtio_vsock_hdr *hdr;
struct sk_buff *skb;
+ u32 bytes_read;
u32 pkt_len;
int off = 0;
int err;
@@ -1935,7 +1936,8 @@ int virtio_transport_read_skb(struct vso
vvs->msg_count--;
pkt_len = le32_to_cpu(hdr->len);
- virtio_transport_dec_rx_pkt(vvs, pkt_len, pkt_len);
+ bytes_read = skb->len - VIRTIO_VSOCK_SKB_CB(skb)->offset;
+ virtio_transport_dec_rx_pkt(vvs, bytes_read, pkt_len);
spin_unlock_bh(&vvs->rx_lock);
virtio_transport_send_credit_update(vsk);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 031/281] wifi: brcmfmac: fix P2P device removal race in brcmf_detach()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (29 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 030/281] vsock/virtio: account only unread bytes in read_skb() Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 032/281] wifi: mt76: mt7603: initialize global station WCID Greg Kroah-Hartman
` (256 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michele Dionisio, Arend van Spriel,
Johannes Berg
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michele Dionisio <michele.dionisio@gmail.com>
commit 08a3f02fea636e97a7422d1512f76dacdb5b0887 upstream.
When the driver is removed while the user space process that created
the P2P device (e.g. wpa_supplicant) is still exiting, the P2P device
interface is removed twice and the kernel crashes.
The two paths are:
- wpa_supplicant, on exit, sends NL80211_CMD_DEL_INTERFACE for the P2P
device. nl80211_del_interface() holds RTNL and the wiphy mutex and
calls brcmf_p2p_del_vif(), which disables discovery and waits up to
1.5 s for BRCMF_E_IF_DEL. Then it calls brcmf_remove_interface(),
which unregisters the wdev and frees the vif and the ifp.
- brcmf_detach() sets the bus down, so BRCMF_E_IF_DEL never arrives,
and calls brcmf_remove_interface(ifp, false) for the same ifp.
brcmf_p2p_ifp_removed() reads ifp->vif and then blocks on
rtnl_lock(). When brcmf_p2p_del_vif() releases RTNL, it calls
cfg80211_unregister_wdev() on the wdev that was already unregistered
and freed.
The second list_del_rcu() of wdev->list faults on LIST_POISON2:
brcmfmac: brcmf_p2p_del_vif delete P2P vif
brcmfmac: brcmf_p2p_deinit_discovery enter
brcmfmac: brcmf_p2p_del_vif P2P: GO_NEG_PHASE status cleared
brcmfmac: brcmf_detach Enter
brcmfmac: brcmf_bus_change_state 1 -> 0
brcmfmac: brcmf_remove_interface Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_del_if Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_p2p_ifp_removed P2P: device interface removed
[1.5 s later, brcmf_p2p_del_vif() timed out]
brcmfmac: brcmf_remove_interface Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_del_if Enter, bsscfgidx=1, ifidx=0
brcmfmac: brcmf_p2p_ifp_removed P2P: device interface removed
Unable to handle kernel paging request at virtual address dead000000000122
Internal error: Oops: 96000044 [#1] PREEMPT_RT SMP
pc : _cfg80211_unregister_wdev+0x6c/0x264 [cfg80211]
Call trace:
_cfg80211_unregister_wdev+0x6c/0x264 [cfg80211]
cfg80211_unregister_wdev+0x10/0x1c [cfg80211]
brcmf_p2p_ifp_removed+0x84/0xb0 [brcmfmac]
brcmf_remove_interface+0x1f4/0x254 [brcmfmac]
brcmf_detach+0x88/0x180 [brcmfmac]
brcmf_sdio_remove+0x90/0x7b0 [brcmfmac]
brcmf_sdiod_remove+0x20/0xa0 [brcmfmac]
brcmf_ops_sdio_remove+0xbc/0x12c [brcmfmac]
sdio_bus_remove+0x38/0x144
device_release_driver_internal+0x1e8/0x2c0
device_release_driver+0x14/0x20
brcmf_sdio_bus_remove+0x2c/0x40 [brcmfmac]
brcmf_fwvid_unregister_vendor+0xd8/0x170 [brcmfmac]
__exit_compat+0x18/0x418 [brcmfmac_cyw]
__arm64_sys_delete_module+0x1ac/0x244
The log was taken with debug=0x406 on an i.MX 8M Plus board with a
CYW55513 (Sona IF513) on SDIO. The driver is the Ezurio backport of
brcmfmac from v6.18.22 on a 5.4-rt kernel. The code involved is the same
in mainline.
To reproduce:
1. Start wpa_supplicant on wlan0 and let it associate. It creates the
P2P device (iw dev shows "type P2P-device").
2. Stop wpa_supplicant and remove the driver without waiting for
wpa_supplicant to exit:
kill $(pidof wpa_supplicant)
rmmod brcmfmac_cyw brcmfmac
The crash is reproducible on that board.
For the interface without a netdev (the P2P device), take RTNL and the
wiphy mutex in brcmf_detach() before reading iflist, and remove it with
locked=true. If brcmf_p2p_del_vif() runs first, brcmf_detach() finds the
slot empty. If brcmf_detach() runs first, nl80211 does not find the wdev
any more. The interfaces with a netdev are removed as before, because
brcmf_del_if() takes RTNL on its own for the primary interface.
Fixes: 9831bcb987df ("brcmfmac: Deleting of p2p device is leaking memory.")
Cc: stable@vger.kernel.org
Assisted-by: claude-opus-5-5
Signed-off-by: Michele Dionisio <michele.dionisio@gmail.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260924123027.4122909-2-michele.dionisio@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 27 ++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1489,8 +1489,31 @@ void brcmf_detach(struct device *dev)
brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);
/* make sure primary interface removed last */
for (i = BRCMF_MAX_IFS - 1; i > -1; i--) {
- if (drvr->iflist[i])
- brcmf_remove_interface(drvr->iflist[i], false);
+ struct brcmf_if *ifp = drvr->iflist[i];
+
+ if (!ifp)
+ continue;
+
+ if (ifp->ndev) {
+ brcmf_remove_interface(ifp, false);
+ continue;
+ }
+
+ /* The P2P device interface has no netdev. Its removal can
+ * race with NL80211_CMD_DEL_INTERFACE issued by a user space
+ * process that is exiting (e.g. wpa_supplicant), which ends
+ * in brcmf_p2p_del_vif() under RTNL and the wiphy mutex. If
+ * both paths remove the interface, the wdev is unregistered
+ * twice and the vif is used after being freed. Take the same
+ * locks and re-read iflist, so only one path removes it.
+ */
+ rtnl_lock();
+ wiphy_lock(drvr->wiphy);
+ ifp = drvr->iflist[i];
+ if (ifp)
+ brcmf_remove_interface(ifp, true);
+ wiphy_unlock(drvr->wiphy);
+ rtnl_unlock();
}
brcmf_bus_stop(drvr->bus_if);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 032/281] wifi: mt76: mt7603: initialize global station WCID
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (30 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 031/281] wifi: brcmfmac: fix P2P device removal race in brcmf_detach() Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 033/281] wifi: mt76: mt7996: fix uninitialized buf read in mt7996_variant_fem_init() Greg Kroah-Hartman
` (255 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Cristian Papa, Felix Fietkau
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Papa <pcristian292@gmail.com>
commit 456de496b53ae73e6e3020fec815dbdc88aa7c07 upstream.
mt7603 uses a driver-private global station WCID for frames that have
neither a station nor a vif, including frames injected through a monitor
interface. Unlike the core global WCID initialized by
mt76_register_device(), this WCID is published without ever being passed
to mt76_wcid_init().
Since commit 0335c034e726 ("wifi: mt76: fix race condition related to
checking tx queue fill status"), mt76_tx() queues every such frame on the
WCID's tx_pending or tx_offchannel queue and links its tx_list. The first
injected frame therefore reaches __skb_queue_tail() with an uninitialized
sk_buff_head and dereferences a NULL prev pointer.
Initialize the WCID before publishing it.
The fix was tested on an MT7603 PCIe device. Three wildcard probe requests
were injected through a monitor interface. The hardware queue head and tail
advanced from 0 to 3 and a second radio captured the third request over the
air. No oops or reset occurred. After restoring AP mode, a 150 MB transfer
also completed without a reset.
Fixes: 0335c034e726 ("wifi: mt76: fix race condition related to checking tx queue fill status")
Cc: stable@vger.kernel.org
Signed-off-by: Cristian Papa <pcristian292@gmail.com>
Link: https://patch.msgid.link/20260904010702.16306-1-pcristian292@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/mediatek/mt76/mt7603/init.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
@@ -230,6 +230,7 @@ mt7603_mac_init(struct mt7603_dev *dev)
eth_broadcast_addr(bc_addr);
mt7603_wtbl_init(dev, MT7603_WTBL_RESERVED, -1, bc_addr);
+ mt76_wcid_init(&dev->global_sta.wcid, 0);
dev->global_sta.wcid.idx = MT7603_WTBL_RESERVED;
rcu_assign_pointer(dev->mt76.wcid[MT7603_WTBL_RESERVED],
&dev->global_sta.wcid);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 033/281] wifi: mt76: mt7996: fix uninitialized buf read in mt7996_variant_fem_init()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (31 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 032/281] wifi: mt76: mt7603: initialize global station WCID Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 034/281] wireguard: queueing: preserve tstamp_type when encapsulating packet Greg Kroah-Hartman
` (254 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Lu Huang, Felix Fietkau
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Huang <huanglu@kylinos.cn>
commit 52f6a065e0810c739a5dabd33a58047f08100f50 upstream.
When the eFuse block covering MT7976C_EFUSE_OFFSET is invalid,
mt7996_mcu_get_eeprom() returns -EINVAL without writing buf, but
mt7996_variant_fem_init() tolerates -EINVAL and keeps running, so
buf[idx] == 0xc reads uninitialized stack memory. A stale 0x0c byte
misclassifies a 0x7976 aDie as 7976C, selects MT7996_FEM_INT and the
wrong default EEPROM, overriding valid calibration data. Only consult
the eFuse byte when the read succeeded; with an invalid eFuse, fall
back to the three explicit aDie version checks.
Fixes: e8cb33ad546a ("wifi: mt76: mt7996: add support for more variants")
Cc: stable@vger.kernel.org
Signed-off-by: Lu Huang <huanglu@kylinos.cn>
Link: https://patch.msgid.link/20260930085435.1424493-1-huanglu@kylinos.cn
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
@@ -1237,7 +1237,7 @@ static int mt7996_variant_fem_init(struc
adie_ver = u32_get_bits(regval, MT_ADIE_VERSION_MASK);
idx = MT7976C_EFUSE_OFFSET % MT7996_EEPROM_BLOCK_SIZE;
is_7976c = adie_ver == 0x8a10 || adie_ver == 0x8b00 ||
- adie_ver == 0x8c10 || buf[idx] == 0xc;
+ adie_ver == 0x8c10 || (!ret && buf[idx] == 0xc);
adie_id = u32_get_bits(regval, MT_ADIE_CHIP_ID_MASK);
if (adie_id == 0x7975 || adie_id == 0x7979 ||
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 034/281] wireguard: queueing: preserve tstamp_type when encapsulating packet
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (32 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 033/281] wifi: mt76: mt7996: fix uninitialized buf read in mt7996_variant_fem_init() Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 035/281] wireguard: noise: reject response consumption after intermediate initiation Greg Kroah-Hartman
` (253 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ramses de Norre,
Toke Høiland-Jørgensen, Eric Dumazet,
Jason A. Donenfeld, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ramses de Norre <ramses@well-founded.dev>
commit 65ab9de4bdd4c05d8277cfc20ae0b9f5aff60897 upstream.
Sending traffic through a wireguard tunnel on a host using the fq
qdisc fills the log with:
fq: likely mono tstamp with tstamp_type 0
An skb carries a timestamp in skb->tstamp and, separately, a
skb->tstamp_type field recording which clock that timestamp came from.
The two have to agree.
When wireguard encapsulates a packet it calls wg_reset_packet(), which
clears the fields that must not leak from the inner packet into the
tunnel packet. It does so in two steps:
skb_scrub_packet(skb, true);
memset(&skb->headers, 0, sizeof(skb->headers));
skb_scrub_packet() deliberately keeps skb->tstamp when it holds a
monotonic timestamp: that value is the time the packet is scheduled to
be sent, and the qdisc still needs it. The memset then zeroes
skb->tstamp_type, because that field sits inside the headers group
while skb->tstamp does not. The packet therefore leaves wireguard
carrying a monotonic timestamp labelled as a realtime one.
Nothing noticed until commit c4f796c4f16b ("net_sched: sch_fq: convert
skb->tstamp if not monotonic"): fq used to assume every timestamp was
monotonic. It now consults tstamp_type, spots the mismatch, warns, and
falls back to treating the value as monotonic. Pacing still ends up
correct, so the log spam is the actual problem.
Save tstamp_type before the memset and restore it when encapsulating,
next to the hash fields that are already carried over this way. When
decapsulating it stays zeroed, which is right: an incoming packet's
timestamp is a realtime receive timestamp.
Fixes: d98d58a00261 ("net: Set skb->mono_delivery_time and clear it after sch_handle_ingress()")
Signed-off-by: Ramses de Norre <ramses@well-founded.dev>
Reviewed-by: Toke Høiland-Jørgensen <toke@kernel.org>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Link: https://patch.msgid.link/20261008130124.724119-3-Jason@zx2c4.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireguard/queueing.h | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/net/wireguard/queueing.h
+++ b/drivers/net/wireguard/queueing.h
@@ -78,12 +78,14 @@ static inline void wg_reset_packet(struc
u8 l4_hash = skb->l4_hash;
u8 sw_hash = skb->sw_hash;
u32 hash = skb->hash;
+ u8 tstamp_type = skb->tstamp_type;
skb_scrub_packet(skb, true);
memset(&skb->headers, 0, sizeof(skb->headers));
if (encapsulating) {
skb->l4_hash = l4_hash;
skb->sw_hash = sw_hash;
skb->hash = hash;
+ skb->tstamp_type = tstamp_type;
}
skb->queue_mapping = 0;
skb->nohdr = 0;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 035/281] wireguard: noise: reject response consumption after intermediate initiation
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (33 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 034/281] wireguard: queueing: preserve tstamp_type when encapsulating packet Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 036/281] workqueue: Fix NULL current_pwq deref in chained work check Greg Kroah-Hartman
` (252 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jérémy Jean,
Jason A. Donenfeld, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason A. Donenfeld <Jason@zx2c4.com>
commit d0305f8d90029556260c6824b61c493c424eba9e upstream.
Two threads begin processing the identical response message, received
twice. The first thread, A, runs. While it's running, the second one,
B, gets partway through, and during that slow calculation, or even while
blocking on down_write(), A completes and then also a handshake
initiation that's already been queued up runs in thread C, which itself
takes that same down_write(). The handshake initiation creation
succeeds, and sets the state back to waiting-for-response, and calls
up_write(), at which point thread B resumes, because either its finished
its calculations or was finally allowed to acquire down_write(). Thread
B then copies the state back to the peer, and begins a new session,
using that state, which is the same session as the one made in thread A.
Thread A Thread B Thread C
down_read()
sA = handshake->state
memcpy(cA, handshake->crypto)
up_read()
if (sA != 1)
goto fail
slow_crypto(cA)
down_read()
sB = handshake->state
memcpy(cB, handshake->crypto)
up_read()
if (sB != 1)
goto fail
slow_crypto(cB)
down_write()
if (sA != handshake->state)
goto fail
memcpy(handshake->crypto, cA)
handshake->state = 2
up_write()
down_write()
if (handshake->state != 2)
goto fail
derive_session(handshake->crypto)
up_write()
down_write()
slow_crypto(handshake->crypto)
handshake->state = 1
up_write()
down_write()
if (sB != handshake->state)
goto fail
memcpy(handshake->crypto, cB)
handshake->state = 2
up_write()
down_write()
if (handshake->state != 2)
goto fail
derive_session(handshake->crypto)
up_write()
This seems basically impossible to hit in a meaningful way in practice,
but ensure that it absolutely cannot happen by comparing the ephemeral
private key that's on the stack with the latest one that the peer's
handshake state has.
Cc: stable@vger.kernel.org
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
Reported-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Link: https://patch.msgid.link/20261008130124.724119-4-Jason@zx2c4.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireguard/noise.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/net/wireguard/noise.c
+++ b/drivers/net/wireguard/noise.c
@@ -784,10 +784,11 @@ wg_noise_handshake_consume_response(stru
/* Success! Copy everything to peer */
down_write(&handshake->lock);
- /* It's important to check that the state is still the same, while we
- * have an exclusive lock.
+ /* Check that the state is the same and that this is still the
+ * initiation we started with, while we have an exclusive lock.
*/
- if (handshake->state != state) {
+ if (handshake->state != state ||
+ crypto_memneq(handshake->ephemeral_private, ephemeral_private, NOISE_PUBLIC_KEY_LEN)) {
up_write(&handshake->lock);
goto fail;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 036/281] workqueue: Fix NULL current_pwq deref in chained work check
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (34 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 035/281] wireguard: noise: reject response consumption after intermediate initiation Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 037/281] x86/CPU/AMD: Fix AMD TLBI Erratum #1718 Greg Kroah-Hartman
` (251 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Pavankumar Kondeti, Tejun Heo
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavankumar Kondeti <pavan.kondeti@oss.qualcomm.com>
commit 980db94e3eeefdd8a1c46f86412c33a7f7806f51 upstream.
current_wq_worker() only tells us that %current is a kworker. It does
not guarantee that the worker is currently executing a work item, as
worker->current_pwq is populated only while process_one_work() is running
the work function.
is_chained_work() can be reached while queueing on a draining or
destroying workqueue. If a kworker outside work-item execution reaches
that path, current_wq_worker() returns a worker but worker->current_pwq is
NULL, and the chained-work test can fault before it emits the intended
warning.
Guard the chained-work test with worker->current_pwq. A kworker without
current_pwq is not executing work on the target workqueue, so the helper
should return false and let the draining/destroying warning fire.
Fixes: 8d03ecfe4718 ("workqueue: reimplement is_chained_work() using current_wq_worker()")
Cc: stable@vger.kernel.org
Signed-off-by: Pavankumar Kondeti <pavan.kondeti@oss.qualcomm.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/workqueue.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -2244,7 +2244,7 @@ static bool is_chained_work(struct workq
* Return %true iff I'm a worker executing a work item on @wq. If
* I'm @worker, it's safe to dereference it without locking.
*/
- return worker && worker->current_pwq->wq == wq;
+ return worker && worker->current_pwq && worker->current_pwq->wq == wq;
}
/*
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 037/281] x86/CPU/AMD: Fix AMD TLBI Erratum #1718
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (35 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 036/281] workqueue: Fix NULL current_pwq deref in chained work check Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 038/281] xen/netfront: dont leak the skb when xennet_fill_frags() fails Greg Kroah-Hartman
` (250 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Borislav Petkov (AMD), Rik van Riel,
Lorenzo Stoakes (ARM), stable
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Borislav Petkov (AMD) <bp@alien8.de>
commit 87db7795cbaaf636ae22ae031f4906db7bb77803 upstream.
The processor may fail to invalidate a TLB entry while executing an
INVLPGB/TLBSYNC instruction pair.
Detect the erratum and apply a software workaround when a microcode fix
is not present.
Fixes: 82378c6c2f43 ("x86/mm: Use INVLPGB for kernel TLB flushes")
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Rik van Riel <riel@surriel.com>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Tested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Tested-by: Rik van Riel <riel@surriel.com>
Cc: stable@kernel.org
Link: https://patch.msgid.link/20261002211617.1001617-1-bp@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/include/asm/cpufeatures.h | 3 +++
arch/x86/include/asm/tlb.h | 6 ++++++
arch/x86/kernel/cpu/amd.c | 4 ++++
3 files changed, 13 insertions(+)
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -465,6 +465,8 @@
#define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* No Nested Data Breakpoints */
#define X86_FEATURE_WRMSR_XX_BASE_NS (20*32+ 1) /* WRMSR to {FS,GS,KERNEL_GS}_BASE is non-serializing */
#define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* LFENCE always serializing / synchronizes RDTSC */
+
+#define X86_FEATURE_TLBSYNC_SFW_NO (20*32+ 4) /* TLBI Erratum #1718 fixed in microcode */
#define X86_FEATURE_VERW_CLEAR (20*32+ 5) /* The memory form of VERW mitigates TSA */
#define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* Null Selector Clears Base */
@@ -575,4 +577,5 @@
#define X86_BUG_TSA X86_BUG( 1*32+ 9) /* "tsa" CPU is affected by Transient Scheduler Attacks */
#define X86_BUG_VMSCAPE X86_BUG( 1*32+10) /* "vmscape" CPU is affected by VMSCAPE attacks from guests */
#define X86_BUG_SEAMRET_INVD_VMCS X86_BUG( 1*32+11) /* "seamret_invd_vmcs" SEAMRET from P-SEAMLDR clears the current VMCS */
+#define X86_BUG_TLBI X86_BUG( 1*32+12) /* "tlbi" AMD TLBI Erratum #1718 */
#endif /* _ASM_X86_CPUFEATURES_H */
--- a/arch/x86/include/asm/tlb.h
+++ b/arch/x86/include/asm/tlb.h
@@ -110,6 +110,12 @@ static inline void __tlbsync(void)
/* TLBSYNC: supported in binutils >= 0.36. */
asm volatile(".byte 0x0f, 0x01, 0xff" ::: "memory");
+
+ if (!static_cpu_has_bug(X86_BUG_TLBI))
+ return;
+
+ /* TLBSYNC: supported in binutils >= 0.36. */
+ asm volatile(".byte 0x0f, 0x01, 0xff" ::: "memory");
}
#else
/* Some compilers (I'm looking at you clang!) simply can't do DCE */
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -1047,6 +1047,10 @@ static void init_amd_zen5(struct cpuinfo
msr_clear_bit(MSR_AMD64_CPUID_FN_7, 18);
pr_emerg_once("RDSEED32 is broken. Disabling the corresponding CPUID bit.\n");
}
+
+ if (cpu_has(c, X86_FEATURE_INVLPGB) &&
+ !cpu_has(c, X86_FEATURE_TLBSYNC_SFW_NO))
+ set_cpu_bug(c, X86_BUG_TLBI);
}
static void init_amd(struct cpuinfo_x86 *c)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 038/281] xen/netfront: dont leak the skb when xennet_fill_frags() fails
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (36 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 037/281] x86/CPU/AMD: Fix AMD TLBI Erratum #1718 Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 039/281] tee: shm: reject zero-sized allocations in tee_dyn_shm_alloc_helper() Greg Kroah-Hartman
` (249 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Juergen Gross,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
commit 93ccaf1c26e2133396173b76a071e59024daa622 upstream.
When a response chain has more slots than fit in the skb's frags,
xennet_fill_frags() returns an error and xennet_poll() jumps to its
error path. That path moves what's left on tmpq to errq to be freed,
but the skb being filled was already dequeued from tmpq, so it's never
freed. Each chain that overflows leaks the skb and the pages attached
to it as frags, and the backend decides how many slots it sends.
Put the skb back on tmpq before taking the error path, like the
xennet_set_skb_gso() failure just above it does.
Fixes: ad4f15dc2c70 ("xen/netfront: don't bug in case of too many frags")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Link: https://patch.msgid.link/20261007-b4-xen-netfront-fill-frags-leak-v1-1-a8a01ff9cd52@toxicpanda.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/xen-netfront.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1346,8 +1346,10 @@ err:
skb->data_len = rx->status;
skb->len += rx->status;
- if (unlikely(xennet_fill_frags(queue, skb, &tmpq)))
+ if (unlikely(xennet_fill_frags(queue, skb, &tmpq))) {
+ __skb_queue_head(&tmpq, skb);
goto err;
+ }
if (rx->flags & XEN_NETRXF_csum_blank)
skb->ip_summed = CHECKSUM_PARTIAL;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 039/281] tee: shm: reject zero-sized allocations in tee_dyn_shm_alloc_helper()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (37 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 038/281] xen/netfront: dont leak the skb when xennet_fill_frags() fails Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 040/281] strparser: make sure __strp_recv isnt running before tearing down the parser Greg Kroah-Hartman
` (248 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, lvc-project, Georgiy Osokin,
Sumit Garg, Jens Wiklander
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Georgiy Osokin <g.osokin@auroraos.dev>
commit b7f925fd5226deb953c8dcdc9677d3fcc2717c00 upstream.
tee_dyn_shm_alloc_helper() derives nr_pages from a caller-supplied size
and passes it to alloc_pages_exact() without checking it. For size == 0
nr_pages is 0, and alloc_pages_exact(0) calls get_order(0), which is
documented as undefined and returns BITS_PER_LONG - PAGE_SHIFT. The page
allocator then trips its order > MAX_PAGE_ORDER warning and fails the
allocation; on a panic_on_warn kernel that ends the boot.
This can be triggered by TEE_IOC_SHM_ALLOC with struct
tee_ioctl_shm_alloc_data where size is 0.
Reject a zero page count, as register_shm_helper() already does for the
register path.
Fixes: cf4441503e20 ("tee: optee: Move pool_op helper functions")
Cc: stable@vger.kernel.org
Cc: lvc-project@linuxtesting.org
Signed-off-by: Georgiy Osokin <g.osokin@auroraos.dev>
Reviewed-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
Signed-off-by: Jens Wiklander <jens.wiklander@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tee/tee_shm.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/tee/tee_shm.c
+++ b/drivers/tee/tee_shm.c
@@ -343,6 +343,10 @@ int tee_dyn_shm_alloc_helper(struct tee_
unsigned int i;
int rc = 0;
+ /* get_order(0) is undefined and exceeds MAX_PAGE_ORDER. */
+ if (!nr_pages)
+ return -EINVAL;
+
/*
* Ignore alignment since this is already going to be page aligned
* and there's no need for any larger alignment.
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 040/281] strparser: make sure __strp_recv isnt running before tearing down the parser
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (38 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 039/281] tee: shm: reject zero-sized allocations in tee_dyn_shm_alloc_helper() Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 041/281] swiotlb: fix default_swiotlb_limit() for non-growable default pool Greg Kroah-Hartman
` (247 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyunwoo Kim, Sabrina Dubroca,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <sd@queasysnail.net>
commit 0984ebc631792acf8fff105112ee74a6b8f1efcc upstream.
The comment above strp_done() claims that if strp is stopped,
strp_recv will no longer be called. That's only true if the caller has
a mechanism (eg locking) to guarantee that strp_recv() calls that
started before strp_stop() have completed by the time we call
strp_done().
This adds a dummy lock_sock/release_sock pair to guarantee that any
in-flight strp_recv() (which runs under either bh_lock_sock or
lock_sock, depending if it's called from ->sk_data_ready or strp_work)
has completed.
Only espintcp can be affected by this race condition, but this patch
makes sure no future user of strp can have the bug.
This could crash on strp->sk ("general mode" of strp), but this mode
has been here for 9 years and has never been used. It'll be gone soon,
no point worrying about it.
Switch the stopped/paused/etc bits to u8's to avoid races between
strp_stop() and strp_pause/unpause().
A reproducer has been published and turns the possible UAF into an
exploit [1].
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Link: https://lore.kernel.org/all/aZLn2Faeg1FB7XOf@v4bel/
Link: https://lore.kernel.org/all/aZgpkyTDU3aXe_V0@v4bel/
Link: https://github.com/m0x41nos/RustyTux [1]
Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
Cc: stable@vger.kernel.org
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Hyunwoo Kim <imv4bel@gmail.com>
Link: https://patch.msgid.link/425d9d926709b542ed5331110c19fee4aee1f28d.1791206940.git.sd@queasysnail.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Documentation/networking/strparser.rst | 2 +-
include/net/strparser.h | 10 +++++-----
net/strparser/strparser.c | 6 +++++-
3 files changed, 11 insertions(+), 7 deletions(-)
--- a/Documentation/networking/strparser.rst
+++ b/Documentation/networking/strparser.rst
@@ -77,7 +77,7 @@ Functions
strp_done is called to release any resources held by the stream
parser instance. This must be called after the stream processor
- has been stopped.
+ has been stopped. The socket lock must not be held.
::
--- a/include/net/strparser.h
+++ b/include/net/strparser.h
@@ -91,11 +91,11 @@ static inline struct strp_msg *strp_msg(
struct strparser {
struct sock *sk;
- u32 stopped : 1;
- u32 paused : 1;
- u32 aborted : 1;
- u32 interrupted : 1;
- u32 unrecov_intr : 1;
+ u8 stopped;
+ u8 paused;
+ u8 aborted;
+ u8 interrupted;
+ u8 unrecov_intr;
struct sk_buff **skb_nextp;
struct sk_buff *skb_head;
--- a/net/strparser/strparser.c
+++ b/net/strparser/strparser.c
@@ -505,12 +505,16 @@ void strp_unpause(struct strparser *strp
EXPORT_SYMBOL_GPL(strp_unpause);
/* strp must already be stopped so that strp_recv will no longer be called.
- * Note that strp_done is not called with the lower socket held.
+ * Note that strp_done must not be called with the lower socket held.
*/
void strp_done(struct strparser *strp)
{
WARN_ON(!strp->stopped);
+ lock_sock(strp->sk);
+ /* sync with pending strp_recv */
+ release_sock(strp->sk);
+
cancel_delayed_work_sync(&strp->msg_timer_work);
cancel_work_sync(&strp->work);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 041/281] swiotlb: fix default_swiotlb_limit() for non-growable default pool
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (39 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 040/281] strparser: make sure __strp_recv isnt running before tearing down the parser Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 042/281] tcp: reject net_iov in zerocopy receive mapping hints Greg Kroah-Hartman
` (246 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andreas Greve, James Dingwall,
Marek Szyprowski, Claude Opus 5.5 (1M context)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <m.szyprowski@samsung.com>
commit 911655ab1dfb9d526978a75df3b210132620d30a upstream.
Commit ad96ce3252db ("swiotlb: determine potential physical address
limit") changed default_swiotlb_limit() to return the maximum physical
address that could ever be used by dynamically allocated pools, so that
the value stays constant when CONFIG_SWIOTLB_DYNAMIC=y. However,
io_tlb_default_mem.phys_limit is returned even when the default pool
cannot grow, e.g. when swiotlb_init_remap() is called with a remap
callback.
This breaks Xen dom0 on x86: pci_xen_swiotlb_init() passes SWIOTLB_ANY
and xen_swiotlb_fixup(), so phys_limit is set to the top of dom0 memory,
although xen_swiotlb_fixup() makes the default pool below the 32-bit
boundary. xen_swiotlb_dma_supported() then rejects 32-bit DMA masks,
even though the bounce buffer is perfectly usable by such devices.
Return phys_limit only if the default pool can actually grow, otherwise
report the real end of the default pool, like in the
!CONFIG_SWIOTLB_DYNAMIC case.
Reported-by: Andreas Greve <andreas.greve@a-greve.de>
Reported-by: James Dingwall <james@dingwall.me.uk>
Fixes: ad96ce3252db ("swiotlb: determine potential physical address limit")
Closes: https://lore.kernel.org/xen-devel/f74668db-52fd-4575-8372-7bfdf10d62ac@a-greve.de/
Cc: stable@vger.kernel.org
Assisted-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Tested-by: James Dingwall <james@dingwall.me.uk>
Link: https://lore.kernel.org/all/20261005070518.1590097-1-m.szyprowski@samsung.com/
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/dma/swiotlb.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -1680,10 +1680,10 @@ phys_addr_t default_swiotlb_base(void)
phys_addr_t default_swiotlb_limit(void)
{
#ifdef CONFIG_SWIOTLB_DYNAMIC
- return io_tlb_default_mem.phys_limit;
-#else
- return io_tlb_default_mem.defpool.end - 1;
+ if (io_tlb_default_mem.can_grow)
+ return io_tlb_default_mem.phys_limit;
#endif
+ return io_tlb_default_mem.defpool.end - 1;
}
#ifdef CONFIG_DEBUG_FS
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 042/281] tcp: reject net_iov in zerocopy receive mapping hints
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (40 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 041/281] swiotlb: fix default_swiotlb_limit() for non-growable default pool Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:35 ` [PATCH 7.2 043/281] tipc: destroy topsrv workqueues before closing connections Greg Kroah-Hartman
` (245 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Mina Almasry,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit 8b1f0af1fd5fd113432233ed8a3862ee7c30a84f upstream.
After copying a readable prefix, receive_fallback_to_copy() asks
tcp_zerocopy_set_hint_for_skb() where page mapping can resume. If the
next skb is unreadable, find_next_mappable_frag() passes its net_iov
fragment to can_map_frag().
skb_frag_page() returns NULL for a net_iov, but can_map_frag()
dereferences it in PageCompound(). A v7.2 KASAN run on a connected TCP
socket with 64 readable bytes followed by a 4096-byte NET_IOV_DMABUF
fragment reported:
BUG: KASAN: null-ptr-deref in can_map_frag
tcp_zerocopy_receive -> can_map_frag
Kernel panic - not syncing: KASAN: panic_on_warn set
The diagnostic inserted the net_iov directly because the test host has
no devmem-capable NIC. Hardware end-to-end reachability remains untested
and requires CONFIG_NET_DEVMEM plus a supported DMA-buf-bound RX queue.
Reject all net_iov fragments before skb_frag_page(). This covers both
DMABUF and IOURING net_iov types while leaving page-backed checks
unchanged. With the guard, the same queue copied the readable prefix,
returned a 4096-byte skip hint, and completed without a fault.
Fixes: 9f6b619edf2e ("net: support non paged skb frags")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20260930102524.1659847-1-4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/tcp.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1908,6 +1908,8 @@ static bool can_map_frag(const skb_frag_
if (skb_frag_size(frag) != PAGE_SIZE || skb_frag_off(frag))
return false;
+ if (skb_frag_is_net_iov(frag))
+ return false;
page = skb_frag_page(frag);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 043/281] tipc: destroy topsrv workqueues before closing connections
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (41 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 042/281] tcp: reject net_iov in zerocopy receive mapping hints Greg Kroah-Hartman
@ 2026-10-13 11:35 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 044/281] tipc: hold a reference to nodes found by link name Greg Kroah-Hartman
` (244 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:35 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Vega, Yuqi Xu, Ren Wei,
David S. Miller
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuqi Xu <xuyuqiabc@gmail.com>
commit 3acdd44385bc7e2e57605e073691ce69cc5a960d upstream.
tipc_topsrv_stop() closed subscriber connections while the topology
server's send and receive workqueues were still running. Socket
callbacks and subscription events could then queue more work, and
in-flight send/recv work could drop the last connection reference
during the conn_idr walk.
That race produced several teardown failures: refcount_t addition on
0 from conn_get() on a connection whose release was blocked on
idr_lock, a subsequent use-after-free in tipc_conn_close(),
queue_work() on an already destroyed workqueue from the listener
data-ready callback, and an RCU stall in tipc_topsrv_exit_net()
while the walk spun under idr_lock.
Clear srv->listener under idr_lock so it acts as a shutdown flag,
skip queue_work() once it is NULL, destroy the workqueues to flush
in-flight work, and only then close the remaining connections.
Refuse tipc_conn_lookup() after that flag is cleared, and drop
idr_lock when the teardown walk finds no connection, so an
in-flight subscription event cannot pin idr_in_use while the
walk holds the lock.
v3 supersedes the narrower in-thread diff Tung Quang Nguyen
posted on 2026-09-23. It keeps his teardown order and adds the
lookup refusal and the empty-idr unlock.
Fixes: c5fa7b3cf3cb ("tipc: introduce new TIPC server infrastructure")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Reviewed-by: Ren Wei <weir@nebusec.ai>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/tipc/topsrv.c | 80 +++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 65 insertions(+), 15 deletions(-)
--- a/net/tipc/topsrv.c
+++ b/net/tipc/topsrv.c
@@ -55,7 +55,7 @@
/**
* struct tipc_topsrv - TIPC server structure
* @conn_idr: identifier set of connection
- * @idr_lock: protect the connection identifier set
+ * @idr_lock: protect the connection identifier set and listener
* @idr_in_use: amount of allocated identifier entry
* @net: network namespace instance
* @awork: accept work item
@@ -218,6 +218,10 @@ static struct tipc_conn *tipc_conn_looku
struct tipc_conn *con;
spin_lock_bh(&s->idr_lock);
+ if (!s->listener) {
+ spin_unlock_bh(&s->idr_lock);
+ return NULL;
+ }
con = idr_find(&s->conn_idr, conid);
if (!connected(con) || !kref_get_unless_zero(&con->kref))
con = NULL;
@@ -301,10 +305,20 @@ static void tipc_conn_send_to_sock(struc
static void tipc_conn_send_work(struct work_struct *work)
{
struct tipc_conn *con = container_of(work, struct tipc_conn, swork);
+ struct tipc_topsrv *srv;
+
+ srv = con->server;
+ spin_lock_bh(&srv->idr_lock);
+ if (!srv->listener) {
+ spin_unlock_bh(&srv->idr_lock);
+ goto out;
+ }
+ spin_unlock_bh(&srv->idr_lock);
if (connected(con))
tipc_conn_send_to_sock(con);
+out:
conn_put(con);
}
@@ -334,8 +348,14 @@ void tipc_topsrv_queue_evt(struct net *n
list_add_tail(&e->list, &con->outqueue);
spin_unlock_bh(&con->outqueue_lock);
- if (queue_work(srv->send_wq, &con->swork))
- return;
+ spin_lock_bh(&srv->idr_lock);
+ if (srv->listener) {
+ if (queue_work(srv->send_wq, &con->swork)) {
+ spin_unlock_bh(&srv->idr_lock);
+ return;
+ }
+ }
+ spin_unlock_bh(&srv->idr_lock);
err:
conn_put(con);
}
@@ -346,14 +366,20 @@ err:
*/
static void tipc_conn_write_space(struct sock *sk)
{
+ struct tipc_topsrv *srv;
struct tipc_conn *con;
read_lock_bh(&sk->sk_callback_lock);
con = sk->sk_user_data;
if (connected(con)) {
- conn_get(con);
- if (!queue_work(con->server->send_wq, &con->swork))
- conn_put(con);
+ srv = con->server;
+ spin_lock_bh(&srv->idr_lock);
+ if (srv->listener) {
+ conn_get(con);
+ if (!queue_work(srv->send_wq, &con->swork))
+ conn_put(con);
+ }
+ spin_unlock_bh(&srv->idr_lock);
}
read_unlock_bh(&sk->sk_callback_lock);
}
@@ -418,8 +444,17 @@ static int tipc_conn_rcv_from_sock(struc
static void tipc_conn_recv_work(struct work_struct *work)
{
struct tipc_conn *con = container_of(work, struct tipc_conn, rwork);
+ struct tipc_topsrv *srv;
int count = 0;
+ srv = con->server;
+ spin_lock_bh(&srv->idr_lock);
+ if (!srv->listener) {
+ spin_unlock_bh(&srv->idr_lock);
+ goto out;
+ }
+ spin_unlock_bh(&srv->idr_lock);
+
while (connected(con)) {
if (tipc_conn_rcv_from_sock(con))
break;
@@ -430,6 +465,7 @@ static void tipc_conn_recv_work(struct w
count = 0;
}
}
+out:
conn_put(con);
}
@@ -438,6 +474,7 @@ static void tipc_conn_recv_work(struct w
*/
static void tipc_conn_data_ready(struct sock *sk)
{
+ struct tipc_topsrv *srv;
struct tipc_conn *con;
trace_sk_data_ready(sk);
@@ -445,9 +482,14 @@ static void tipc_conn_data_ready(struct
read_lock_bh(&sk->sk_callback_lock);
con = sk->sk_user_data;
if (connected(con)) {
- conn_get(con);
- if (!queue_work(con->server->rcv_wq, &con->rwork))
- conn_put(con);
+ srv = con->server;
+ spin_lock_bh(&srv->idr_lock);
+ if (srv->listener) {
+ conn_get(con);
+ if (!queue_work(srv->rcv_wq, &con->rwork))
+ conn_put(con);
+ }
+ spin_unlock_bh(&srv->idr_lock);
}
read_unlock_bh(&sk->sk_callback_lock);
}
@@ -503,8 +545,12 @@ static void tipc_topsrv_listener_data_re
read_lock_bh(&sk->sk_callback_lock);
srv = sk->sk_user_data;
- if (srv)
- queue_work(srv->rcv_wq, &srv->awork);
+ if (srv) {
+ spin_lock_bh(&srv->idr_lock);
+ if (srv->listener)
+ queue_work(srv->rcv_wq, &srv->awork);
+ spin_unlock_bh(&srv->idr_lock);
+ }
read_unlock_bh(&sk->sk_callback_lock);
}
@@ -701,22 +747,26 @@ static void tipc_topsrv_stop(struct net
int id;
spin_lock_bh(&srv->idr_lock);
+ srv->listener = NULL;
+ spin_unlock_bh(&srv->idr_lock);
+ tipc_topsrv_work_stop(srv);
+
+ spin_lock_bh(&srv->idr_lock);
for (id = 0; srv->idr_in_use; id++) {
con = idr_find(&srv->conn_idr, id);
if (con) {
- conn_get(con);
spin_unlock_bh(&srv->idr_lock);
tipc_conn_close(con);
- conn_put(con);
spin_lock_bh(&srv->idr_lock);
+ continue;
}
+ spin_unlock_bh(&srv->idr_lock);
+ spin_lock_bh(&srv->idr_lock);
}
__module_get(lsock->ops->owner);
__module_get(lsock->sk->sk_prot_creator->owner);
- srv->listener = NULL;
spin_unlock_bh(&srv->idr_lock);
- tipc_topsrv_work_stop(srv);
sock_release(lsock);
idr_destroy(&srv->conn_idr);
kfree(srv);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 044/281] tipc: hold a reference to nodes found by link name
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (42 preceding siblings ...)
2026-10-13 11:35 ` [PATCH 7.2 043/281] tipc: destroy topsrv workqueues before closing connections Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 045/281] Revert "wifi: libertas: reject short monitor TX frames" Greg Kroah-Hartman
` (243 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 17e73bae400f6a434dc006e3bee92c94cf781954 upstream.
tipc_node_find_by_name() returns a node after dropping its RCU read lock
without taking a reference. The LINK_SET, LINK_GET and LINK_RESET_STATS
handlers then lock and access the node, racing with timer-driven cleanup of
a down peer. Generic netlink serialization does not exclude the node
timer.
The following interleaving can leave a handler using a freed node:
CPU 0: find the node under RCU and release the node read lock
CPU 1: tipc_node_timeout() clears the links and unlinks the down node
CPU 1: drop the list and timer references, queuing tipc_node_free()
CPU 0: leave the RCU read-side critical section
CPU 1: complete the grace period and free the node
CPU 0: acquire the node lock through the stale pointer
LINK_SET also uses the node's media address after releasing the node lock,
when passing queued packets to tipc_bearer_xmit().
KASAN on v7.3-rc5 reported:
BUG: KASAN: slab-use-after-free in _raw_read_lock_bh
Write of size 4 at addr ffff88807e06f008 by task poc/92
Call Trace:
_raw_read_lock_bh kernel/locking/spinlock.c:287
tipc_nl_node_set_link net/tipc/node.c:2475
genl_family_rcv_msg_doit net/netlink/genetlink.c:1114
genl_rcv_msg net/netlink/genetlink.c:1209
netlink_rcv_skb net/netlink/af_netlink.c:2575
Allocated by task 0:
tipc_node_create net/tipc/node.c:539
tipc_node_check_dest net/tipc/node.c:1196
tipc_disc_rcv net/tipc/discover.c:252
Freed by task 92:
kfree mm/slub.c:6801
rcu_core kernel/rcu/tree.c:2919
Last potentially related work creation:
__call_rcu_common.constprop.0 kernel/rcu/tree.c:3181
tipc_node_timeout net/tipc/node.c:814
Acquire a reference to the selected node with kref_get_unless_zero() before
leaving RCU, returning NULL if the node has already been released. Release
that reference on every caller exit after the last node access, including
transmission in LINK_SET. Keep the existing link lookup order and locking
so concurrent link removal still takes the existing error paths.
Fixes: 6a939f365bdb ("tipc: Auto removal of peer down node instance")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Link: https://patch.msgid.link/20260928161246.1895273-1-nicoyip.dev@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/tipc/node.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -2419,8 +2419,11 @@ static struct tipc_node *tipc_node_find_
}
}
tipc_node_read_unlock(n);
- if (found_node)
+ if (found_node) {
+ if (!kref_get_unless_zero(&found_node->kref))
+ found_node = NULL;
break;
+ }
}
rcu_read_unlock();
@@ -2505,6 +2508,7 @@ out:
tipc_node_read_unlock(node);
tipc_bearer_xmit(net, bearer_id, &xmitq, &node->links[bearer_id].maddr,
NULL);
+ tipc_node_put(node);
return res;
}
@@ -2556,12 +2560,14 @@ int tipc_nl_node_get_link(struct sk_buff
link = node->links[bearer_id].link;
if (!link) {
tipc_node_read_unlock(node);
+ tipc_node_put(node);
err = -EINVAL;
goto err_free;
}
err = __tipc_nl_add_link(net, &msg, link, 0);
tipc_node_read_unlock(node);
+ tipc_node_put(node);
if (err)
goto err_free;
}
@@ -2632,11 +2638,13 @@ int tipc_nl_node_reset_link_stats(struct
if (!link) {
spin_unlock_bh(&le->lock);
tipc_node_read_unlock(node);
+ tipc_node_put(node);
return -EINVAL;
}
tipc_link_reset_stats(link);
spin_unlock_bh(&le->lock);
tipc_node_read_unlock(node);
+ tipc_node_put(node);
return 0;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 045/281] Revert "wifi: libertas: reject short monitor TX frames"
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (43 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 044/281] tipc: hold a reference to nodes found by link name Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 046/281] RISC-V: Clear HSTATUS.HU on CPU initialization Greg Kroah-Hartman
` (242 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Johannes Berg
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
commit 9727d1c4e1c971fc42b049b645fdda6852758835 upstream.
This reverts commit 13ff543e0b2c713aedeaadadde686686e949dc78.
The 'goto free' just made things worse, causing a spinlock
to be handled incorrectly. Revert this for now.
Reported-by: Takashi Iwai <tiwai@suse.de>
Cc: stable@vger.kernel.org
Fixes: 13ff543e0b2c ("wifi: libertas: reject short monitor TX frames")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/wireless/marvell/libertas/tx.c | 7 -------
1 file changed, 7 deletions(-)
--- a/drivers/net/wireless/marvell/libertas/tx.c
+++ b/drivers/net/wireless/marvell/libertas/tx.c
@@ -117,13 +117,6 @@ netdev_tx_t lbs_hard_start_xmit(struct s
if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data;
- if (skb->len < sizeof(*rtap_hdr) + 4 + ETH_ALEN) {
- lbs_deb_tx("tx err: short monitor frame %u\n", skb->len);
- dev->stats.tx_dropped++;
- dev->stats.tx_errors++;
- goto free;
- }
-
/* set txpd fields from the radiotap header */
txpd->tx_control = cpu_to_le32(convert_radiotap_rate_to_mv(rtap_hdr->rate));
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 046/281] RISC-V: Clear HSTATUS.HU on CPU initialization
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (44 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 045/281] Revert "wifi: libertas: reject short monitor TX frames" Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 13:05 ` Miguel Ojeda
2026-10-13 11:36 ` [PATCH 7.2 047/281] selinux: fix data race on AVC latest_notif Greg Kroah-Hartman
` (241 subsequent siblings)
287 siblings, 1 reply; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yong-Xuan Wang, Samuel Holland,
Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
commit 6694612317e5225086e39ca1ba97ada2b1942e48 upstream.
The RISC-V privileged specification does not mandate HSTATUS reset
values, leaving the HU bit potentially set after hardware reset.
When HU=1, hypervisor instructions (HLV/HLVX/HSV) can execute in
U-mode to access guest memory, which may cause unintended behavior
if not explicitly controlled.
Clear HSTATUS.HU during CPU initialization to ensure hypervisor
instructions are only available in HS-mode, preventing unexpected
guest memory access from U-mode code.
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Link: https://patch.msgid.link/20260924-hstatus_hu-v2-1-7e970f5f1d8d@sifive.com
Cc: stable@vger.kernel.org
[pjw@kernel.org: capitalized RISCV_ISA_EXT_h to fix build; added stable cc]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/include/asm/cpufeature.h | 2 ++
arch/riscv/kernel/cpufeature.c | 12 ++++++++++++
arch/riscv/kernel/setup.c | 2 ++
arch/riscv/kernel/smpboot.c | 2 ++
arch/riscv/kernel/suspend.c | 2 ++
5 files changed, 20 insertions(+)
--- a/arch/riscv/include/asm/cpufeature.h
+++ b/arch/riscv/include/asm/cpufeature.h
@@ -40,6 +40,8 @@ extern u32 thead_vlenb_of;
void __init riscv_user_isa_enable(void);
+void riscv_clear_hypervisor_csr(void);
+
#define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) { \
.name = #_name, \
.property = #_name, \
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -1184,6 +1184,18 @@ void __init riscv_user_isa_enable(void)
pr_warn("Zicbop disabled as it is unavailable on some harts\n");
}
+void riscv_clear_hypervisor_csr(void)
+{
+ if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_H))
+ return;
+
+ /*
+ * Clear HSTATUS.HU to restrict hypervisor instructions to HS-mode.
+ * This prevents user-mode from executing HLV/HSV instructions.
+ */
+ csr_clear(CSR_HSTATUS, HSTATUS_HU);
+}
+
#ifdef CONFIG_RISCV_ALTERNATIVE
/*
* Alternative patch sites consider 48 bits when determining when to patch
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -364,6 +364,8 @@ void __init setup_arch(char **cmdline_p)
if (!IS_ENABLED(CONFIG_RISCV_ISA_ZBB) || !riscv_isa_extension_available(NULL, ZBB))
static_branch_disable(&efficient_ffs_key);
+
+ riscv_clear_hypervisor_csr();
}
bool arch_cpu_is_hotpluggable(int cpu)
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -244,6 +244,8 @@ asmlinkage __visible void smp_callin(voi
numa_add_cpu(curr_cpuid);
+ riscv_clear_hypervisor_csr();
+
pr_debug("CPU%u: Booted secondary hartid %lu\n", curr_cpuid,
cpuid_to_hartid_map(curr_cpuid));
--- a/arch/riscv/kernel/suspend.c
+++ b/arch/riscv/kernel/suspend.c
@@ -43,6 +43,8 @@ void suspend_save_csrs(struct suspend_co
void suspend_restore_csrs(struct suspend_context *context)
{
+ riscv_clear_hypervisor_csr();
+
csr_write(CSR_SCRATCH, 0);
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_XLINUXENVCFG))
csr_write(CSR_ENVCFG, context->envcfg);
^ permalink raw reply [flat|nested] 291+ messages in thread* Re: [PATCH 7.2 046/281] RISC-V: Clear HSTATUS.HU on CPU initialization
2026-10-13 11:36 ` [PATCH 7.2 046/281] RISC-V: Clear HSTATUS.HU on CPU initialization Greg Kroah-Hartman
@ 2026-10-13 13:05 ` Miguel Ojeda
0 siblings, 0 replies; 291+ messages in thread
From: Miguel Ojeda @ 2026-10-13 13:05 UTC (permalink / raw)
To: gregkh
Cc: patches, pjw, samuel.holland, stable, yongxuan.wang,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, linux-riscv
On Tue, 13 Oct 2026 13:36:02 +0200 Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
>
> 7.2-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
>
> commit 6694612317e5225086e39ca1ba97ada2b1942e48 upstream.
>
> The RISC-V privileged specification does not mandate HSTATUS reset
> values, leaving the HU bit potentially set after hardware reset.
> When HU=1, hypervisor instructions (HLV/HLVX/HSV) can execute in
> U-mode to access guest memory, which may cause unintended behavior
> if not explicitly controlled.
>
> Clear HSTATUS.HU during CPU initialization to ensure hypervisor
> instructions are only available in HS-mode, preventing unexpected
> guest memory access from U-mode code.
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
> Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
> Link: https://patch.msgid.link/20260924-hstatus_hu-v2-1-7e970f5f1d8d@sifive.com
> Cc: stable@vger.kernel.org
> [pjw@kernel.org: capitalized RISCV_ISA_EXT_h to fix build; added stable cc]
> Signed-off-by: Paul Walmsley <pjw@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
For riscv64, I am seeing:
arch/riscv/kernel/cpufeature.c:1189:36: error: use of undeclared identifier 'RISCV_ISA_EXT_H'
1189 | if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_H))
| ^
It seems it is missing commit
0c5a9ab5192b ("riscv: Standardize extension capitalization")
Either that or manually tweak the identifier to match 7.2.y.
6.18.y also breaks for the same reason.
I hope this helps!
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: linux-riscv@lists.infradead.org
Cheers,
Miguel
^ permalink raw reply [flat|nested] 291+ messages in thread* Re: [PATCH 7.2 046/281] RISC-V: Clear HSTATUS.HU on CPU initialization
@ 2026-10-13 13:05 ` Miguel Ojeda
0 siblings, 0 replies; 291+ messages in thread
From: Miguel Ojeda @ 2026-10-13 13:05 UTC (permalink / raw)
To: gregkh
Cc: patches, pjw, samuel.holland, stable, yongxuan.wang,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, linux-riscv
On Tue, 13 Oct 2026 13:36:02 +0200 Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
>
> 7.2-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
>
> commit 6694612317e5225086e39ca1ba97ada2b1942e48 upstream.
>
> The RISC-V privileged specification does not mandate HSTATUS reset
> values, leaving the HU bit potentially set after hardware reset.
> When HU=1, hypervisor instructions (HLV/HLVX/HSV) can execute in
> U-mode to access guest memory, which may cause unintended behavior
> if not explicitly controlled.
>
> Clear HSTATUS.HU during CPU initialization to ensure hypervisor
> instructions are only available in HS-mode, preventing unexpected
> guest memory access from U-mode code.
>
> Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
> Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
> Link: https://patch.msgid.link/20260924-hstatus_hu-v2-1-7e970f5f1d8d@sifive.com
> Cc: stable@vger.kernel.org
> [pjw@kernel.org: capitalized RISCV_ISA_EXT_h to fix build; added stable cc]
> Signed-off-by: Paul Walmsley <pjw@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
For riscv64, I am seeing:
arch/riscv/kernel/cpufeature.c:1189:36: error: use of undeclared identifier 'RISCV_ISA_EXT_H'
1189 | if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_H))
| ^
It seems it is missing commit
0c5a9ab5192b ("riscv: Standardize extension capitalization")
Either that or manually tweak the identifier to match 7.2.y.
6.18.y also breaks for the same reason.
I hope this helps!
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexandre Ghiti <alex@ghiti.fr>
Cc: linux-riscv@lists.infradead.org
Cheers,
Miguel
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 291+ messages in thread
* [PATCH 7.2 047/281] selinux: fix data race on AVC latest_notif
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (45 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 046/281] RISC-V: Clear HSTATUS.HU on CPU initialization Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 048/281] selinux: preserve NATIVE_LABELS on already-initialized sb in set_mnt_opts Greg Kroah-Hartman
` (240 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+a7f7cb0737bd91aa698c,
Christian Göttsche, Stephen Smalley, Paul Moore
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Göttsche <cgzones@googlemail.com>
commit 1ca924044bf0de879a1648be93a56939652267d3 upstream.
avc_policy_seqno() reads latest_notif without holding notif_lock, while
avc_latest_notif_update() can update it under that lock. KCSAN reports
these concurrent accesses during policy boolean updates and permission
checks.
Use READ_ONCE() for the lockless read and WRITE_ONCE() for the update.
The spinlock continues to serialize the comparison and update against
other writers. Reads made while holding notif_lock cannot race with a
writer and can remain plain accesses.
This marks both sides of the intentional concurrent access and constrains
compiler transformations, without suppressing checking with data_race().
Cc: stable@vger.kernel.org
Fixes: 788e7dd4c22e ("SELinux: Improve read/write performance")
Reported-by: syzbot+a7f7cb0737bd91aa698c@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a7f7cb0737bd91aa698c
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/selinux/avc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -579,7 +579,7 @@ static int avc_latest_notif_update(u32 s
}
} else {
if (seqno > selinux_avc.avc_cache.latest_notif)
- selinux_avc.avc_cache.latest_notif = seqno;
+ WRITE_ONCE(selinux_avc.avc_cache.latest_notif, seqno);
}
spin_unlock_irqrestore(¬if_lock, flag);
@@ -1207,5 +1207,6 @@ int avc_has_perm(u32 ssid, u32 tsid, u16
u32 avc_policy_seqno(void)
{
- return selinux_avc.avc_cache.latest_notif;
+ /* Writers hold notif_lock; readers only sample the sequence number. */
+ return READ_ONCE(selinux_avc.avc_cache.latest_notif);
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 048/281] selinux: preserve NATIVE_LABELS on already-initialized sb in set_mnt_opts
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (46 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 047/281] selinux: fix data race on AVC latest_notif Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 049/281] sctp: copy zeroed stats to user in sctp_getsockopt_pr_streamstatus() when !streamoute Greg Kroah-Hartman
` (239 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Stephen Smalley, Paul Moore
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephen Smalley <stephen.smalley.work@gmail.com>
commit 28b7260548af3d35773477993ad4e4de41578dd7 upstream.
When an NFSv4 filesystem exported with security_label is mounted a
second time, sget_fc() returns the existing superblock and
nfs_get_root() calls security_sb_set_mnt_opts() again on it. Since the
superblock is already SB_INITIALIZED, selinux_set_mnt_opts() takes an
early exit without setting SECURITY_LSM_NATIVE_LABELS in
*set_kern_flags. nfs_get_root() then sees kflags without
SECURITY_LSM_NATIVE_LABELS set and clears NFS_CAP_SECURITY_LABEL on
the shared nfs_server, silently disabling per-file labeling for both
the new and the original mount.
Commit 3815a245b501 ("security/selinux: fix SECURITY_LSM_NATIVE_LABELS
on reused superblock") fixed the same problem in
selinux_sb_clone_mnt_opts(). The reused-superblock path for a plain
second mount now goes through sb_set_mnt_opts rather than
sb_clone_mnt_opts, so it needs the same treatment: on both
SE_SBINITIALIZED early exits, set SECURITY_LSM_NATIVE_LABELS in
*set_kern_flags when the superblock was already using
SECURITY_FS_USE_NATVE.
Cc: stable@vger.kernel.org
Closes: https://github.com/SELinuxProject/selinux-kernel/issues/69
Closes: https://github.com/SELinuxProject/selinux-kernel/issues/70
Closes: https://github.com/SELinuxProject/selinux-testsuite/issues/91
Closes: https://github.com/SELinuxProject/selinux-testsuite/issues/92
Fixes: eb9ae686507b ("SELinux: Add new labeling type native labels")
Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/selinux/hooks.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -688,8 +688,12 @@ static int selinux_set_mnt_opts(struct s
* will be used for both mounts)
*/
if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
- && !opts)
+ && !opts) {
+ if ((kern_flags & SECURITY_LSM_NATIVE_LABELS) &&
+ sbsec->behavior == SECURITY_FS_USE_NATIVE)
+ *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
goto out;
+ }
root_isec = backing_inode_security_novalidate(root);
@@ -733,6 +737,9 @@ static int selinux_set_mnt_opts(struct s
/* previously mounted with options, but not on this attempt? */
if ((sbsec->flags & SE_MNTMASK) && !opts)
goto out_double_mount;
+ if ((kern_flags & SECURITY_LSM_NATIVE_LABELS) &&
+ sbsec->behavior == SECURITY_FS_USE_NATIVE)
+ *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
rc = 0;
goto out;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 049/281] sctp: copy zeroed stats to user in sctp_getsockopt_pr_streamstatus() when !streamoute
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (47 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 048/281] selinux: preserve NATIVE_LABELS on already-initialized sb in set_mnt_opts Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 050/281] selftests/mm: cleanup -Wformat issues in hugetlb-mmap Greg Kroah-Hartman
` (238 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xin Long, Hui Peng, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Peng <benquike@gmail.com>
commit 538b529509c7ab0d909cb65bb7264edca1788d30 upstream.
When an SCTP stream output extension structure (streamoute) has not yet
been allocated, sctp_getsockopt_pr_streamstatus() sets the local stack
variables params.sprstat_abandoned_unsent = 0 and
params.sprstat_abandoned_sent = 0, but then immediately jumps to 'out:',
bypassing copy_to_user(). As a result, when an uninitialized user buffer
is passed to getsockopt(SCTP_PR_STREAM_STATUS), the kernel returns
success (0) without copying the zeroed stats back to user space, leaving
uninitialized data in the user buffer.
Refactor the !streamoute check into an if-else chain so that when
streamoute is NULL, params is zeroed and falls through to copy_to_user(),
copying the zeroed stats to user space and setting retval = 0 once before
returning.
Tested in QEMU against Linux 7.3.0-rc3 using an uninitialized
sctp_prstatus user struct passed to getsockopt(SCTP_PR_STREAM_STATUS) on a
freshly created stream: on the unfixed kernel the user struct contains
uninitialized stack garbage; whereas with this fix applied, getsockopt()
copies zeroed stats into user space and returns 0.
Cc: stable@vger.kernel.org
Reviewed-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Hui Peng <benquike@gmail.com>
Fixes: f952be79cebd ("sctp: introduce struct sctp_stream_out_ext")
Link: https://patch.msgid.link/20260930044611.204739-1-benquike@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/sctp/socket.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -7569,11 +7569,7 @@ static int sctp_getsockopt_pr_streamstat
/* Not allocated yet, means all stats are 0 */
params.sprstat_abandoned_unsent = 0;
params.sprstat_abandoned_sent = 0;
- retval = 0;
- goto out;
- }
-
- if (policy == SCTP_PR_SCTP_ALL) {
+ } else if (policy == SCTP_PR_SCTP_ALL) {
params.sprstat_abandoned_unsent = 0;
params.sprstat_abandoned_sent = 0;
for (policy = 0; policy <= SCTP_PR_INDEX(MAX); policy++) {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 050/281] selftests/mm: cleanup -Wformat issues in hugetlb-mmap
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (48 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 049/281] sctp: copy zeroed stats to user in sctp_getsockopt_pr_streamstatus() when !streamoute Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 051/281] e1000e: add system to disable K1 list Greg Kroah-Hartman
` (237 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Carlos Llamas, Andrew Morton,
Sarthak Sharma, SJ Park, Lorenzo Stoakes (ARM), Mike Rapoport,
David Hildenbrand, Liam R. Howlett, Vlastimil Babka,
Suren Baghdasaryan, Michal Hocko, Shuah Khan
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carlos Llamas <cmllamas@google.com>
commit 28eed9906e01d01cbdfb352e799413b2e8b33b76 upstream.
Commit ae571cd6015c ("selftests/mm: hugetlb-mmap: add setup of HugeTLB
pages") and commit 9c5a65f374f8 ("selftests/mm: merge map_hugetlb into
hugepage-mmap") added logs of 'hugepage_size' which has a size_t type.
However, the incorrect format specifier '%lu' was used which triggers
-Wformat warnings when building for 32-bit:
hugetlb-mmap.c:125:55: warning: format specifies type 'unsigned long'
but the argument has type 'size_t' (aka 'unsigned int') [-Wformat]
125 | ksft_print_msg("Default size hugepages (%lu kB)\n", hugepage_size >> 10);
| ~~~ ^~~~~~~~~~~~~~~~~~~
| %zu
hugetlb-mmap.c:134:47: warning: format specifies type 'unsigned long'
but the argument has type 'size_t' (aka 'unsigned int') [-Wformat]
134 | ksft_exit_skip("Not enough %lu Kb pages\n", hugepage_size >> 10);
| ~~~ ^~~~~~~~~~~~~~~~~~~
| %zu
Fix this by switching to the expected '%zu' format specifier.
Link: https://lore.kernel.org/20260927162419.820609-1-cmllamas@google.com
Fixes: ae571cd6015c ("selftests/mm: hugetlb-mmap: add setup of HugeTLB pages")
Fixes: 9c5a65f374f8 ("selftests/mm: merge map_hugetlb into hugepage-mmap")
Signed-off-by: Carlos Llamas <cmllamas@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Sarthak Sharma <sarthak.sharma@arm.com>
Reviewed-by: SJ Park <sj@kernel.org>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
tools/testing/selftests/mm/hugetlb-mmap.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb-mmap.c b/tools/testing/selftests/mm/hugetlb-mmap.c
index 0f2aad1b7dbd..2edbc992e6bc 100644
--- a/tools/testing/selftests/mm/hugetlb-mmap.c
+++ b/tools/testing/selftests/mm/hugetlb-mmap.c
@@ -122,7 +122,7 @@ int main(int argc, char **argv)
hugepage_size = default_huge_page_size();
if (!hugepage_size)
ksft_exit_skip("Could not detect default hugetlb page size.");
- ksft_print_msg("Default size hugepages (%lu kB)\n", hugepage_size >> 10);
+ ksft_print_msg("Default size hugepages (%zu kB)\n", hugepage_size >> 10);
}
/* munmap will fail if the length is not page aligned */
@@ -131,7 +131,7 @@ int main(int argc, char **argv)
hugetlb_set_nr_pages(hugepage_size, nr);
if (hugetlb_free_pages(hugepage_size) < nr)
- ksft_exit_skip("Not enough %lu Kb pages\n", hugepage_size >> 10);
+ ksft_exit_skip("Not enough %zu Kb pages\n", hugepage_size >> 10);
ksft_set_plan(2);
ksft_print_msg("Mapping %lu Mbytes\n", (unsigned long)length >> 20);
--
2.56.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 051/281] e1000e: add system to disable K1 list
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (49 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 050/281] selftests/mm: cleanup -Wformat issues in hugetlb-mmap Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 052/281] EDAC/amd64: Mask UMC chip select to the four implemented selects Greg Kroah-Hartman
` (236 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Herrera, Aleksandr Loktionov,
Tony Nguyen, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tony Nguyen <anthony.l.nguyen@intel.com>
commit 1d6500523b8d5112afe0118173ebc8c1ca23784e upstream.
Javier reports seeing packet loss issues related to the re-enablement
of K1; disabling it makes the issues go away. Add the reported system
to have K1 disabled by default.
Reproduction steps (from the Link):
Plug the cable and ping the default gateway on the LAN. No suspend/resume
involved, machine freshly booted and on AC power. Nothing e1000e-related in
dmesg apart from the link up/down messages; no "Hardware Unit Hang".
Default (K1 enabled):
$ ping -c 30 192.168.10.1
--- 192.168.10.1 ping statistics ---
30 packets transmitted, 18 received, 40% packet loss, time 29734ms
rtt min/avg/max/mdev = 0.211/0.315/0.384/0.046 ms
The lost packets are spread over the run (seq 6, 8, 9, 11, 13, 14, 16, 19,
20, 24, 25, 30), not a single burst. DHCP on this link also takes 1-2
minutes to get a lease, consistent with incoming packets being dropped.
With K1 disabled at runtime:
# ethtool --set-priv-flags enp0s31f6 disable-k1 on
$ ethtool --show-priv-flags enp0s31f6
Private flags for enp0s31f6:
s0ix-enabled: on
disable-k1 : on
$ ping -c 30 192.168.10.1
--- 192.168.10.1 ping statistics ---
30 packets transmitted, 30 received, 0% packet loss, time 29713ms
rtt min/avg/max/mdev = 0.169/0.251/0.468/0.054 ms
$ ping -c 30 192.168.10.1
--- 192.168.10.1 ping statistics ---
30 packets transmitted, 30 received, 0% packet loss, time 29677ms
rtt min/avg/max/mdev = 0.101/0.222/0.360/0.064 ms
I have only compile tested this, but Javier has tested that disabling K1
on his system (Lenovo ThinkPad P14s Gen 5 (Intel), I219-LM [8086:550a])
resolves his issues.
Cc: stable@vger.kernel.org
Fixes: 578294b8b60d ("e1000e: Reconfigure PLL clock gate timeout and re-enable K1 on Meteor Lake")
Reported-by: Javier Herrera <javier.herrera@afronta.com>
Link: https://lore.kernel.org/intel-wired-lan/CAKRuCQLWEcci9hPgNUmvq44Bd2H30T5_vP=exMjsknXMN5Yh9A@mail.gmail.com/
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Link: https://patch.msgid.link/20261001222443.3500206-7-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/intel/e1000e/netdev.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 844f31ab37ad..c282f65199e4 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -67,6 +67,13 @@ static const struct dmi_system_id disable_k1_list[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro 16 Plus PB16250"),
},
},
+ {
+ .ident = "Lenovo ThinkPad P14s Gen 5",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad P14s Gen 5"),
+ },
+ },
{}
};
--
2.56.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 052/281] EDAC/amd64: Mask UMC chip select to the four implemented selects
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (50 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 051/281] e1000e: add system to disable K1 list Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 053/281] fsverity: RCU-delay the freeing of struct fsverity_info Greg Kroah-Hartman
` (235 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yazen Ghannam, Vishal Badole,
Borislav Petkov (AMD)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vishal Badole <Vishal.Badole@amd.com>
commit 7484bc43ba6b8e189b482db5b75e7842890a82b1 upstream.
For DRAM ECC errors, the chip select value can be found in the
MCA_SYND[ErrorInformation] field.
ErrorInformation[2:0] was first documented in Zen1. The 3 bit field
implied that up to 8 chip selects may be used.
However, all Zen-based systems have only ever had up to 4 chip selects.
So only bits [1:0] would contain a valid chip select value.
Future systems are redefining the field to ErrorInformation[1:0]. This
matches the existing 'up to 4 chip selects' implementations. And it
frees up the extra bit for other decoding.
Change the current chip select mask from 0x7 to 0x3 to prepare for the
decode change.
Fixes: 713ad54675fd ("EDAC, amd64: Define and register UMC error decode function")
Suggested-by: Yazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: Vishal Badole <Vishal.Badole@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
Cc: <stable@vger.kernel.org>
Link: https://patch.msgid.link/20261002113204.3358815-2-Vishal.Badole@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/edac/amd64_edac.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2796,13 +2796,13 @@ static inline void decode_bus_error(int
* the instance_id. For example, instance_id=0xYXXXXX where Y is the channel
* number.
*
- * For DRAM ECC errors, the Chip Select number is given in bits [2:0] of
+ * For DRAM ECC errors, the Chip Select number is given in bits [1:0] of
* the MCA_SYND[ErrorInformation] field.
*/
static void umc_get_err_info(struct mce *m, struct err_info *err)
{
err->channel = (m->ipid & GENMASK(31, 0)) >> 20;
- err->csrow = m->synd & 0x7;
+ err->csrow = m->synd & 0x3;
}
static void decode_umc_error(int node_id, struct mce *m)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 053/281] fsverity: RCU-delay the freeing of struct fsverity_info
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (51 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 052/281] EDAC/amd64: Mask UMC chip select to the four implemented selects Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 054/281] gpio: mpsse: fix race when arming the IRQ poll worker Greg Kroah-Hartman
` (234 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Sandeep Dhavale,
Eric Biggers
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit e58c3805ed325fe2d4ae2dd467c0486cc860b733 upstream.
__fsverity_get_info() calls rhashtable_lookup_fast(), which just uses
rcu_read_lock() and doesn't directly synchronize with
fsverity_remove_info().
For the same inode this isn't a problem: its fsverity_info is removed
only at inode eviction time or upon failure to enable verity, when the
inode no longer needs its fsverity_info and it will no longer be
accessed via that inode.
However, this is broken and can cause a use-after-free for concurrent
__fsverity_get_info() for *different* inodes. Those rely on following
fsverity_info::rhash_head in the rhashtable under rcu_read_lock() only.
They also use fsverity_info::inode to do the key comparison.
Fix this by RCU-delaying the freeing of 'struct fsverity_info' after
it's been removed from the rhashtable.
Fixes: f77f281b6118 ("fsverity: use a hashtable to find the fsverity_info")
Cc: stable@vger.kernel.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sandeep Dhavale <dhavale@google.com>
Link: https://patch.msgid.link/20261001171349.81454-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/verity/fsverity_private.h | 15 ++++++++++++++-
fs/verity/open.c | 13 ++++++++++++-
2 files changed, 26 insertions(+), 2 deletions(-)
--- a/fs/verity/fsverity_private.h
+++ b/fs/verity/fsverity_private.h
@@ -11,6 +11,7 @@
#define pr_fmt(fmt) "fs-verity: " fmt
#include <linux/fsverity.h>
+#include <linux/rcupdate.h>
#include <linux/rhashtable.h>
/*
@@ -76,7 +77,19 @@ struct merkle_tree_params {
struct fsverity_info {
struct rhash_head rhash_head;
struct merkle_tree_params tree_params;
- u8 root_hash[FS_VERITY_MAX_DIGEST_SIZE];
+ union {
+ u8 root_hash[FS_VERITY_MAX_DIGEST_SIZE];
+
+ /*
+ * Used for final freeing of the struct, in which case root_hash
+ * is no longer needed. Specifically, the only fields needed
+ * besides the rcu_head are those needed by fsverity_free_info()
+ * itself, and those that can be accessed by fsverity_get_info()
+ * (rhash_head and inode) during the RCU-protected rhashtable
+ * chain search trying to find another inode's fsverity_info.
+ */
+ struct rcu_head rcu_head;
+ };
u8 file_digest[FS_VERITY_MAX_DIGEST_SIZE];
struct inode *inode;
unsigned long *hash_block_verified;
--- a/fs/verity/open.c
+++ b/fs/verity/open.c
@@ -399,11 +399,22 @@ void fsverity_free_info(struct fsverity_
kmem_cache_free(fsverity_info_cachep, vi);
}
+static void fsverity_free_info_rcu(struct rcu_head *head)
+{
+ fsverity_free_info(container_of(head, struct fsverity_info, rcu_head));
+}
+
void fsverity_remove_info(struct fsverity_info *vi)
{
rhashtable_remove_fast(&fsverity_info_hash, &vi->rhash_head,
fsverity_info_hash_params);
- fsverity_free_info(vi);
+ /*
+ * The freeing must be RCU-delayed because __fsverity_get_info() for a
+ * *different* inode's fsverity_info in the same rhashtable hash chain
+ * can still be accessing *this* fsverity_info's rhash_head and inode
+ * fields as part of the RCU-protected hash chain search.
+ */
+ call_rcu(&vi->rcu_head, fsverity_free_info_rcu);
}
void fsverity_cleanup_inode(struct inode *inode)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 054/281] gpio: mpsse: fix race when arming the IRQ poll worker
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (52 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 053/281] fsverity: RCU-delay the freeing of struct fsverity_info Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 055/281] gpio: xilinx: fix runtime PM leak on request error path Greg Kroah-Hartman
` (233 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Song Li, Fan Wu, Bartosz Golaszewski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 7efa1a1953cd6b20b23a3524d5b4b81789c6ef25 upstream.
gpio_mpsse_irq_enable() arms the poll worker before publishing it:
schedule_work() runs before the worker is added to priv->workers. If
gpio_mpsse_disconnect() walks the list in that window it misses the
worker, and once disconnect returns, the USB core frees mpsse_priv
while the orphaned gpio_mpsse_poll() work keeps accessing it, causing
a use-after-free.
Fix this by publishing and arming the worker in one irq_spin
critical section. Teardown walks the same list under irq_spin, so a
worker found on the list is guaranteed to be armed, and
cancel_work_sync() handles it whether it is queued or running.
A worker armed after the disconnect walk would still be missed, so
also set a new priv->dying flag under irq_spin before the teardown
walk, and check it in the same critical section, freeing it via
kfree_rcu() instead when the device is going away, since kfree()
would be called with the IRQ core's raw spinlock held and may sleep
on PREEMPT_RT. schedule_work() is safe to call with irq_spin held,
and the next probe gets a fresh mpsse_priv, so the flag never needs
to be cleared.
This issue was found by an in-house static analysis tool.
Fixes: 179ef1127d7a ("gpio: mpsse: ensure worker is torn down")
Cc: stable@vger.kernel.org
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260929093646.18419-1-fanwu01@zju.edu.cn
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpio/gpio-mpsse.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
--- a/drivers/gpio/gpio-mpsse.c
+++ b/drivers/gpio/gpio-mpsse.c
@@ -10,6 +10,7 @@
#include <linux/cleanup.h>
#include <linux/gpio/driver.h>
#include <linux/mutex.h>
+#include <linux/rcupdate.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
@@ -24,6 +25,7 @@ struct mpsse_priv {
raw_spinlock_t irq_spin; /* protects worker list */
atomic_t irq_type[16]; /* pin -> edge detection type */
atomic_t irq_enabled;
+ atomic_t dying; /* no new workers after disconnect */
int id;
u8 gpio_outputs[2]; /* Output states for GPIOs [L, H] */
@@ -46,6 +48,7 @@ struct mpsse_worker {
atomic_t cancelled;
struct list_head list; /* linked list */
struct list_head destroy; /* teardown linked list */
+ struct rcu_head rcu; /* deferred free for dying path */
};
struct bulk_desc {
@@ -525,10 +528,24 @@ static void gpio_mpsse_irq_enable(struct
worker->priv = priv;
INIT_LIST_HEAD(&worker->list);
INIT_WORK(&worker->work, gpio_mpsse_poll);
- schedule_work(&worker->work);
- scoped_guard(raw_spinlock_irqsave, &priv->irq_spin)
+ scoped_guard(raw_spinlock_irqsave, &priv->irq_spin) {
+ if (atomic_read(&priv->dying)) {
+ /*
+ * Cannot kfree() here: this callback
+ * runs with the IRQ descriptor's raw
+ * spinlock held and kfree() may sleep
+ * on PREEMPT_RT. The worker is not
+ * yet published, so the deferred free
+ * is unobservable.
+ */
+ kfree_rcu(worker, rcu);
+ return;
+ }
+
list_add(&worker->list, &priv->workers);
+ schedule_work(&worker->work);
+ }
}
}
@@ -704,6 +721,9 @@ static void gpio_mpsse_disconnect(struct
{
struct mpsse_priv *priv = usb_get_intfdata(intf);
+ scoped_guard(raw_spinlock_irqsave, &priv->irq_spin)
+ atomic_set(&priv->dying, 1);
+
/*
* Lock prevents double-free of worker from here and the teardown
* step at the beginning of gpio_mpsse_poll
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 055/281] gpio: xilinx: fix runtime PM leak on request error path
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (53 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 054/281] gpio: mpsse: fix race when arming the IRQ poll worker Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 056/281] iavf: send MAC change request synchronously Greg Kroah-Hartman
` (232 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ridham Khurana, Bartosz Golaszewski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ridham Khurana <khurana.ridham222@gmail.com>
commit ff82fc3a4a1d417dee1229681cc5285986edb1fa upstream.
pm_runtime_get_sync() leaves the usage counter incremented even when it
fails, and xgpio_request() returns the error without dropping it.
gpiolib does not call ->free() when ->request() fails, so xgpio_free(),
which holds the only matching pm_runtime_put(), never runs. The reference
is leaked and the controller can no longer runtime-suspend, so its clock
stays enabled.
Switch to pm_runtime_resume_and_get(), which only increments the usage
counter on success.
Fixes: 26b04774621e ("gpio: gpio-xilinx: Add support for suspend and resume")
Cc: stable@vger.kernel.org
Signed-off-by: Ridham Khurana <khurana.ridham222@gmail.com>
Link: https://patch.msgid.link/20260923113905.1409290-1-khurana.ridham222@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpio/gpio-xilinx.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -271,14 +271,7 @@ static void xgpio_save_regs(struct xgpio
static int xgpio_request(struct gpio_chip *chip, unsigned int offset)
{
- int ret;
-
- ret = pm_runtime_get_sync(chip->parent);
- /*
- * If the device is already active pm_runtime_get() will return 1 on
- * success, but gpio_request still needs to return 0.
- */
- return ret < 0 ? ret : 0;
+ return pm_runtime_resume_and_get(chip->parent);
}
static void xgpio_free(struct gpio_chip *chip, unsigned int offset)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 056/281] iavf: send MAC change request synchronously
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (54 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 055/281] gpio: xilinx: fix runtime PM leak on request error path Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 057/281] gve: fix napi_disable deadlock when attempting to disable XSK pools Greg Kroah-Hartman
` (231 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jose Ignacio Tornos Martinez,
Przemek Kitszel, Rafal Romanowski, Tony Nguyen
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
commit 436729a56dd4dac611d10b569c5359d2cf705b19 upstream.
After commit ad7c7b2172c3 ("net: hold netdev instance lock during sysfs
operations"), iavf_set_mac() is called with the netdev instance lock
already held.
The function queues a MAC address change request via
iavf_replace_primary_mac() and then waits for completion. However, in
the current flow, the actual virtchnl message is sent by the watchdog
task, which also needs to acquire the netdev lock to run. Additionally,
the adminq_task which processes virtchnl responses also needs the netdev
lock.
This creates a deadlock scenario:
1. iavf_set_mac() holds netdev lock and waits for MAC change
2. Watchdog needs netdev lock to send the request -> blocked
3. Even if request is sent, adminq_task needs netdev lock to process
PF response -> blocked
4. MAC change times out after 2.5 seconds
5. iavf_set_mac() returns -EAGAIN
This particularly affects VFs during bonding setup when multiple VFs are
enslaved in quick succession.
Fix by implementing a synchronous MAC change operation similar to the
approach used in commit fdadbf6e84c4 ("iavf: fix incorrect reset handling
in callbacks").
The solution:
1. Send the virtchnl ADD_ETH_ADDR message directly (not via watchdog)
2. Poll the admin queue hardware directly for responses
3. Process all received messages (including non-MAC messages)
4. Return when MAC change completes or times out
A new generic function iavf_poll_virtchnl_response() is introduced that
can be reused for any future synchronous virtchnl operations. It takes a
callback to check completion, allowing flexible condition checking.
This allows the operation to complete synchronously while holding
netdev_lock, without relying on watchdog or adminq_task. The function
can sleep for up to 2.5 seconds polling hardware, but this is acceptable
since netdev_lock is per-device and only serializes operations on the
same interface.
To support this, change iavf_add_ether_addrs() to return an error code
instead of void, allowing callers to detect failures. Additionally,
export iavf_mac_add_reject() to enable proper rollback on local failures
(timeouts, send errors) - PF rejections are already handled automatically
by iavf_virtchnl_completion().
Remove vc_waitqueue entirely because iavf_set_mac was the only waiter on
this waitqueue and after the changes it is not needed.
Fixes: ad7c7b2172c3 ("net: hold netdev instance lock during sysfs operations")
cc: stable@vger.kernel.org
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/intel/iavf/iavf.h | 11 ++
drivers/net/ethernet/intel/iavf/iavf_main.c | 85 ++++++++++++++++----
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 99 +++++++++++++++++++++---
3 files changed, 165 insertions(+), 30 deletions(-)
--- a/drivers/net/ethernet/intel/iavf/iavf.h
+++ b/drivers/net/ethernet/intel/iavf/iavf.h
@@ -259,7 +259,6 @@ struct iavf_adapter {
struct work_struct adminq_task;
struct work_struct finish_config;
wait_queue_head_t down_waitqueue;
- wait_queue_head_t vc_waitqueue;
struct iavf_q_vector *q_vectors;
struct list_head vlan_filter_list;
int num_vlan_filters;
@@ -588,8 +587,9 @@ void iavf_configure_queues(struct iavf_a
void iavf_enable_queues(struct iavf_adapter *adapter);
void iavf_disable_queues(struct iavf_adapter *adapter);
void iavf_map_queues(struct iavf_adapter *adapter);
-void iavf_add_ether_addrs(struct iavf_adapter *adapter);
+int iavf_add_ether_addrs(struct iavf_adapter *adapter);
void iavf_del_ether_addrs(struct iavf_adapter *adapter);
+void iavf_mac_add_reject(struct iavf_adapter *adapter);
void iavf_add_vlans(struct iavf_adapter *adapter);
void iavf_del_vlans(struct iavf_adapter *adapter);
void iavf_set_promiscuous(struct iavf_adapter *adapter);
@@ -606,6 +606,13 @@ void iavf_disable_vlan_stripping(struct
void iavf_virtchnl_completion(struct iavf_adapter *adapter,
enum virtchnl_ops v_opcode,
enum iavf_status v_retval, u8 *msg, u16 msglen);
+int iavf_poll_virtchnl_response(struct iavf_adapter *adapter,
+ struct iavf_arq_event_info *event,
+ bool (*condition)(struct iavf_adapter *adapter,
+ const void *data,
+ enum virtchnl_ops v_op),
+ const void *cond_data,
+ unsigned int timeout_ms);
int iavf_config_rss(struct iavf_adapter *adapter);
void iavf_cfg_queues_bw(struct iavf_adapter *adapter);
void iavf_cfg_queues_quanta_size(struct iavf_adapter *adapter);
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -1030,6 +1030,60 @@ static bool iavf_is_mac_set_handled(stru
}
/**
+ * iavf_mac_change_done - Check if MAC change completed
+ * @adapter: board private structure
+ * @data: MAC address being checked (as const void *)
+ * @v_op: virtchnl opcode from processed message
+ *
+ * Callback for iavf_poll_virtchnl_response() to check if MAC change completed.
+ *
+ * Return: true if MAC change completed, false otherwise
+ */
+static bool iavf_mac_change_done(struct iavf_adapter *adapter,
+ const void *data, enum virtchnl_ops v_op)
+{
+ const u8 *addr = data;
+
+ return iavf_is_mac_set_handled(adapter->netdev, addr);
+}
+
+/**
+ * iavf_set_mac_sync - Synchronously change MAC address
+ * @adapter: board private structure
+ * @addr: MAC address to set
+ *
+ * Send MAC change request to PF and poll admin queue for response.
+ * Caller must hold netdev_lock. This can sleep for up to 2.5 seconds.
+ * Event buffer is allocated before sending to avoid state mismatch if
+ * allocation fails after message is sent to PF.
+ *
+ * Return: 0 on success, negative on failure
+ */
+static int iavf_set_mac_sync(struct iavf_adapter *adapter, const u8 *addr)
+{
+ struct iavf_arq_event_info event;
+ int ret;
+
+ netdev_assert_locked(adapter->netdev);
+
+ event.buf_len = IAVF_MAX_AQ_BUF_SIZE;
+ event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
+ if (!event.msg_buf)
+ return -ENOMEM;
+
+ ret = iavf_add_ether_addrs(adapter);
+ if (ret)
+ goto out;
+
+ ret = iavf_poll_virtchnl_response(adapter, &event,
+ iavf_mac_change_done, addr, 2500);
+
+out:
+ kfree(event.msg_buf);
+ return ret;
+}
+
+/**
* iavf_set_mac - NDO callback to set port MAC address
* @netdev: network interface device structure
* @p: pointer to an address structure
@@ -1046,25 +1100,23 @@ static int iavf_set_mac(struct net_devic
return -EADDRNOTAVAIL;
ret = iavf_replace_primary_mac(adapter, addr->sa_data);
-
if (ret)
return ret;
- ret = wait_event_interruptible_timeout(adapter->vc_waitqueue,
- iavf_is_mac_set_handled(netdev, addr->sa_data),
- msecs_to_jiffies(2500));
-
- /* If ret < 0 then it means wait was interrupted.
- * If ret == 0 then it means we got a timeout.
- * else it means we got response for set MAC from PF,
- * check if netdev MAC was updated to requested MAC,
- * if yes then set MAC succeeded otherwise it failed return -EACCES
- */
- if (ret < 0)
+ ret = iavf_set_mac_sync(adapter, addr->sa_data);
+ if (ret) {
+ /* Rollback only if send failed (message never reached PF).
+ * Don't rollback on timeout (-EAGAIN) because the message was
+ * sent and PF will eventually respond. When the response arrives,
+ * iavf_virtchnl_completion() will handle rollback (on PF error)
+ * or acceptance (on PF success) automatically.
+ */
+ if (ret != -EAGAIN) {
+ iavf_mac_add_reject(adapter);
+ ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
+ }
return ret;
-
- if (!ret)
- return -EAGAIN;
+ }
if (!ether_addr_equal(netdev->dev_addr, addr->sa_data))
return -EACCES;
@@ -5394,9 +5446,6 @@ static int iavf_probe(struct pci_dev *pd
/* Setup the wait queue for indicating transition to down status */
init_waitqueue_head(&adapter->down_waitqueue);
- /* Setup the wait queue for indicating virtchannel events */
- init_waitqueue_head(&adapter->vc_waitqueue);
-
INIT_LIST_HEAD(&adapter->ptp.aq_cmds);
init_waitqueue_head(&adapter->ptp.phc_time_waitqueue);
mutex_init(&adapter->ptp.aq_cmd_lock);
--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2013 - 2018 Intel Corporation. */
#include <linux/net/intel/libie/rx.h>
+#include <net/netdev_lock.h>
#include "iavf.h"
#include "iavf_ptp.h"
@@ -555,20 +556,23 @@ iavf_set_mac_addr_type(struct virtchnl_e
* @adapter: adapter structure
*
* Request that the PF add one or more addresses to our filters.
- **/
-void iavf_add_ether_addrs(struct iavf_adapter *adapter)
+ *
+ * Return: 0 on success, negative on failure
+ */
+int iavf_add_ether_addrs(struct iavf_adapter *adapter)
{
struct virtchnl_ether_addr_list *veal;
struct iavf_mac_filter *f;
int i = 0, count = 0;
bool more = false;
size_t len;
+ int ret;
if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
/* bail because we already have a command pending */
dev_err(&adapter->pdev->dev, "Cannot add filters, command %d pending\n",
adapter->current_op);
- return;
+ return -EBUSY;
}
spin_lock_bh(&adapter->mac_vlan_list_lock);
@@ -580,7 +584,7 @@ void iavf_add_ether_addrs(struct iavf_ad
if (!count) {
adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_MAC_FILTER;
spin_unlock_bh(&adapter->mac_vlan_list_lock);
- return;
+ return 0;
}
adapter->current_op = VIRTCHNL_OP_ADD_ETH_ADDR;
@@ -594,8 +598,9 @@ void iavf_add_ether_addrs(struct iavf_ad
veal = kzalloc(len, GFP_ATOMIC);
if (!veal) {
+ adapter->current_op = VIRTCHNL_OP_UNKNOWN;
spin_unlock_bh(&adapter->mac_vlan_list_lock);
- return;
+ return -ENOMEM;
}
veal->vsi_id = adapter->vsi_res->vsi_id;
@@ -615,8 +620,15 @@ void iavf_add_ether_addrs(struct iavf_ad
spin_unlock_bh(&adapter->mac_vlan_list_lock);
- iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_ETH_ADDR, (u8 *)veal, len);
+ ret = iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_ETH_ADDR, (u8 *)veal, len);
kfree(veal);
+ if (ret) {
+ dev_err(&adapter->pdev->dev,
+ "Unable to send ADD_ETH_ADDR message to PF, error %d\n", ret);
+ adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+ }
+
+ return ret;
}
/**
@@ -712,8 +724,8 @@ static void iavf_mac_add_ok(struct iavf_
* @adapter: adapter structure
*
* Remove filters from list based on PF response.
- **/
-static void iavf_mac_add_reject(struct iavf_adapter *adapter)
+ */
+void iavf_mac_add_reject(struct iavf_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
struct iavf_mac_filter *f, *ftmp;
@@ -2364,7 +2376,6 @@ void iavf_virtchnl_completion(struct iav
iavf_mac_add_reject(adapter);
/* restore administratively set MAC address */
ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
- wake_up(&adapter->vc_waitqueue);
break;
case VIRTCHNL_OP_DEL_ETH_ADDR:
dev_err(&adapter->pdev->dev, "Failed to delete MAC filter, error %s\n",
@@ -2555,7 +2566,6 @@ void iavf_virtchnl_completion(struct iav
eth_hw_addr_set(netdev, adapter->hw.mac.addr);
netif_addr_unlock_bh(netdev);
}
- wake_up(&adapter->vc_waitqueue);
break;
case VIRTCHNL_OP_GET_STATS: {
struct iavf_eth_stats *stats =
@@ -2950,3 +2960,72 @@ void iavf_virtchnl_completion(struct iav
} /* switch v_opcode */
adapter->current_op = VIRTCHNL_OP_UNKNOWN;
}
+
+/**
+ * iavf_poll_virtchnl_response - Poll admin queue for virtchnl response
+ * @adapter: adapter structure
+ * @event: pre-allocated event buffer to use for polling
+ * @condition: callback to check if desired response received
+ * @cond_data: context data passed to condition callback
+ * @timeout_ms: maximum time to wait in milliseconds
+ *
+ * Polls the admin queue and processes all incoming virtchnl messages.
+ * After processing each valid message, calls the condition callback to check
+ * if the expected response has been received. The callback receives the opcode
+ * of the processed message to identify which response was received. Continues
+ * polling until the callback returns true or timeout expires.
+ *
+ * Caller must allocate event buffer before sending any messages to PF to avoid
+ * state mismatch if allocation fails after message is sent.
+ *
+ * Caller must hold netdev_lock. This can sleep for up to timeout_ms while
+ * polling hardware.
+ *
+ * Return: 0 on success (condition met), -EAGAIN on timeout, or error code
+ */
+int iavf_poll_virtchnl_response(struct iavf_adapter *adapter,
+ struct iavf_arq_event_info *event,
+ bool (*condition)(struct iavf_adapter *adapter,
+ const void *data,
+ enum virtchnl_ops v_op),
+ const void *cond_data,
+ unsigned int timeout_ms)
+{
+ struct iavf_hw *hw = &adapter->hw;
+ enum virtchnl_ops received_op;
+ unsigned long timeout;
+ int ret = -EAGAIN;
+ u16 pending = 0;
+ u32 v_retval;
+
+ netdev_assert_locked(adapter->netdev);
+
+ timeout = jiffies + msecs_to_jiffies(timeout_ms);
+ do {
+ if (!pending)
+ usleep_range(50, 75);
+
+ if (iavf_clean_arq_element(hw, event, &pending) == IAVF_SUCCESS) {
+ received_op = (enum virtchnl_ops)le32_to_cpu(event->desc.cookie_high);
+ if (received_op != VIRTCHNL_OP_UNKNOWN) {
+ v_retval = le32_to_cpu(event->desc.cookie_low);
+
+ iavf_virtchnl_completion(adapter, received_op,
+ (enum iavf_status)v_retval,
+ event->msg_buf, event->msg_len);
+
+ if (condition(adapter, cond_data, received_op)) {
+ ret = 0;
+ break;
+ }
+ }
+
+ memset(event->msg_buf, 0, IAVF_MAX_AQ_BUF_SIZE);
+
+ if (pending)
+ continue;
+ }
+ } while (time_before(jiffies, timeout));
+
+ return ret;
+}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 057/281] gve: fix napi_disable deadlock when attempting to disable XSK pools
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (55 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 056/281] iavf: send MAC change request synchronously Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 058/281] gve: fix XSK buffer leak when rings are stopped Greg Kroah-Hartman
` (230 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harshitha Ramamurthy, Jordan Rhee,
Joshua Washington, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Washington <joshwash@google.com>
commit 0cb6939a4dfefa822007b7a71986e06bc4f61f54 upstream.
When disabling XSK pools, GVE calls the unlocked versions of
napi_disable and napi_enable. However, the netdev lock has already been
acquired before ndo_bpf is called because GVE supports queue management
ops. Calling the unlocked versions of napi_disable/enable results in a
deadlock when attempting to disable XSK pools, as the thread attempts to
re-acquire a lock it already holds.
Update the NAPI calls to use the locked versions.
This issue was found in production.
Fixes: 606048cbd834 ("net: designate XSK pool pointers in queues as "ops protected"")
Cc: stable@vger.kernel.org
Reviewed-by: Harshitha Ramamurthy <hramamurthy@google.com>
Reviewed-by: Jordan Rhee <jordanrhee@google.com>
Signed-off-by: Joshua Washington <joshwash@google.com>
Link: https://patch.msgid.link/20260930214735.3288780-4-joshwash@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/google/gve/gve_main.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -1708,17 +1708,17 @@ static int gve_xsk_pool_disable(struct n
}
napi_rx = &priv->ntfy_blocks[priv->rx[qid].ntfy_id].napi;
- napi_disable(napi_rx); /* make sure current rx poll is done */
+ napi_disable_locked(napi_rx); /* make sure current rx poll is done */
tx_qid = gve_xdp_tx_queue_id(priv, qid);
napi_tx = &priv->ntfy_blocks[priv->tx[tx_qid].ntfy_id].napi;
- napi_disable(napi_tx); /* make sure current tx poll is done */
+ napi_disable_locked(napi_tx); /* make sure current tx poll is done */
gve_unreg_xsk_pool(priv, qid);
smp_mb(); /* Make sure it is visible to the workers on datapath */
- napi_enable(napi_rx);
- napi_enable(napi_tx);
+ napi_enable_locked(napi_rx);
+ napi_enable_locked(napi_tx);
if (gve_is_gqi(priv)) {
if (gve_rx_work_pending(&priv->rx[qid]))
napi_schedule(napi_rx);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 058/281] gve: fix XSK buffer leak when rings are stopped
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (56 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 057/281] gve: fix napi_disable deadlock when attempting to disable XSK pools Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 059/281] gve: fix XSK buffer leak on error descriptor Greg Kroah-Hartman
` (229 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tim Hostetler, Jordan Rhee,
Joshua Washington, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Washington <joshwash@google.com>
commit 73670ddb91a4d22e1deb3efd962242de1ec48e90 upstream.
GVE does not free XSK buffers when resetting ring state as a part of
stopping queues. This causes all XSK buffers which are posted to the
NIC to be leaked.
Free XSK buffers attached to an allocated buf_state when stopping rings.
This issue was hit in production.
Fixes: c1fffc5d66a7 ("gve: implement DQO RX datapath and control path for AF_XDP zero-copy")
Cc: stable@vger.kernel.org
Reviewed-by: Tim Hostetler <thostet@google.com>
Reviewed-by: Jordan Rhee <jordanrhee@google.com>
Signed-off-by: Joshua Washington <joshwash@google.com>
Link: https://patch.msgid.link/20260930214735.3288780-2-joshwash@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/google/gve/gve_rx_dqo.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c
+++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c
@@ -113,6 +113,12 @@ static void gve_rx_reset_ring_dqo(struct
gve_free_to_page_pool(rx, bs, false);
else
gve_free_qpl_page_dqo(bs);
+
+ if (gve_buf_state_is_allocated(rx, bs) &&
+ bs->xsk_buff) {
+ xsk_buff_free(bs->xsk_buff);
+ bs->xsk_buff = NULL;
+ }
}
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 059/281] gve: fix XSK buffer leak on error descriptor
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (57 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 058/281] gve: fix XSK buffer leak when rings are stopped Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 060/281] ibmveth: h_free logical LAN on open-fail after register Greg Kroah-Hartman
` (228 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jordan Rhee, Tim Hostetler,
Joshua Washington, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Washington <joshwash@google.com>
commit 9fed6a8ab8a5bacba2c709cb19d2dd6d2fa9112e upstream.
When the error bit is set in the RX completion descriptor, the buf_state
and its attached buffer should be freed. In the case of AF_XDP ZC, the
XSK buffer was not freed, leading to a leak.
This issue was caught by LLM.
Fixes: c1fffc5d66a7 ("gve: implement DQO RX datapath and control path for AF_XDP zero-copy")
Cc: stable@vger.kernel.org
Reviewed-by: Jordan Rhee <jordanrhee@google.com>
Reviewed-by: Tim Hostetler <thostet@google.com>
Signed-off-by: Joshua Washington <joshwash@google.com>
Link: https://patch.msgid.link/20260930214735.3288780-3-joshwash@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/google/gve/gve_rx_dqo.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c
+++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c
@@ -845,7 +845,12 @@ static int gve_rx_dqo(struct napi_struct
}
if (unlikely(compl_desc->rx_error)) {
- gve_free_buffer(rx, buf_state);
+ if (buf_state->xsk_buff) {
+ xsk_buff_free(buf_state->xsk_buff);
+ gve_free_buf_state(rx, buf_state);
+ } else {
+ gve_free_buffer(rx, buf_state);
+ }
return -EINVAL;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 060/281] ibmveth: h_free logical LAN on open-fail after register
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (58 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 059/281] gve: fix XSK buffer leak on error descriptor Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 061/281] ibmveth: fix TX LTB and filter unwind on open-fail Greg Kroah-Hartman
` (227 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mingming Cao, Dave Marquardt,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mingming Cao <mmc@linux.ibm.com>
commit af0524bf4ce1a4cbd2946aa81751582951cfcab5 upstream.
ibmveth_open() registers the logical LAN, then allocates the RX
buffer pools. A pool failure jumps to out_free_buffer_pools without
h_free_logical_lan(), so PHYP still owns the buffer-list page when
it is unmapped. request_irq() failure already issued the hypercall
before taking the same label.
Move that h_free to the shared post-register unwind so both paths
deregister before the buffer list is unmapped.
Fixes: d43732ce021f ("ibmveth: properly unwind on init errors")
Cc: stable@vger.kernel.org
Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
Link: https://patch.msgid.link/7a56fbfb9e0674f011f4e310fbd7dfd8e67c30aa.1790357373.git.mmc@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/ibm/ibmveth.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -718,10 +718,6 @@ static int ibmveth_open(struct net_devic
if (rc != 0) {
netdev_err(netdev, "unable to request irq 0x%x, rc %d\n",
netdev->irq, rc);
- do {
- lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
- } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY));
-
goto out_free_buffer_pools;
}
@@ -737,6 +733,9 @@ static int ibmveth_open(struct net_devic
return 0;
out_free_buffer_pools:
+ do {
+ lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
+ } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY));
while (--i >= 0) {
if (adapter->rx_buff_pool[i].active)
ibmveth_free_buffer_pool(adapter,
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 061/281] ibmveth: fix TX LTB and filter unwind on open-fail
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (59 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 060/281] ibmveth: h_free logical LAN on open-fail after register Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 062/281] ice: fix use-after-free in dynamic port cleanup Greg Kroah-Hartman
` (226 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mingming Cao, Dave Marquardt,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mingming Cao <mmc@linux.ibm.com>
commit 84bec0bf035258a1073ffd6f6dc8ea61806aa7d4 upstream.
out_free_buffer_pools reuses open()'s loop index for the TX LTB
walk. After the pool unwind i is -1, so the TX buffers allocated
earlier are leaked. request_irq() failure has the same leak.
The TX-fail goto on that walk also skips dma_unmap of the filter
list (pre-existing since the LTB was added). Rewrite the TX walk
to real_num_tx_queues with a pointer check, and unmap the filter
list before those frees.
Fixes: d926793c1de9 ("ibmveth: Implement multi queue on xmit")
Cc: stable@vger.kernel.org
Signed-off-by: Mingming Cao <mmc@linux.ibm.com>
Reviewed-by: Dave Marquardt <davemarq@linux.ibm.com>
Link: https://patch.msgid.link/d14314c2b10f125f5e578782484ba3cc50564d53.1790357373.git.mmc@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/ibm/ibmveth.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
--- a/drivers/net/ethernet/ibm/ibmveth.c
+++ b/drivers/net/ethernet/ibm/ibmveth.c
@@ -553,10 +553,15 @@ static int ibmveth_rxq_harvest_buffer(st
static void ibmveth_free_tx_ltb(struct ibmveth_adapter *adapter, int idx)
{
+ void *ptr = adapter->tx_ltb_ptr[idx];
+
+ if (!ptr)
+ return;
+
+ adapter->tx_ltb_ptr[idx] = NULL;
dma_unmap_single(&adapter->vdev->dev, adapter->tx_ltb_dma[idx],
adapter->tx_ltb_size, DMA_TO_DEVICE);
- kfree(adapter->tx_ltb_ptr[idx]);
- adapter->tx_ltb_ptr[idx] = NULL;
+ kfree(ptr);
}
static int ibmveth_allocate_tx_ltb(struct ibmveth_adapter *adapter, int idx)
@@ -667,7 +672,7 @@ static int ibmveth_open(struct net_devic
for (i = 0; i < netdev->real_num_tx_queues; i++) {
if (ibmveth_allocate_tx_ltb(adapter, i))
- goto out_free_tx_ltb;
+ goto out_unmap_filter_list;
}
adapter->rx_queue.index = 0;
@@ -745,10 +750,8 @@ out_unmap_filter_list:
dma_unmap_single(dev, adapter->filter_list_dma, 4096,
DMA_BIDIRECTIONAL);
-out_free_tx_ltb:
- while (--i >= 0) {
+ for (i = netdev->real_num_tx_queues - 1; i >= 0; i--)
ibmveth_free_tx_ltb(adapter, i);
- }
out_unmap_buffer_list:
dma_unmap_single(dev, adapter->buffer_list_dma, 4096,
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 062/281] ice: fix use-after-free in dynamic port cleanup
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (60 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 061/281] ibmveth: fix TX LTB and filter unwind on open-fail Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 063/281] ice: fix metadata_dst refcount handling on representor teardown Greg Kroah-Hartman
` (225 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xuanqiang Luo, Marcin Szycik,
Aleksandr Loktionov, Patryk Holda, Tony Nguyen, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
commit 1402fc67d2f4e2e1fc7bf8ee0825b8ad994557ff upstream.
ice_dealloc_dynamic_port() uses dyn_port->vsi->idx to erase the dynamic
port from pf->dyn_ports. However, it frees the VSI before reading the
index for the erase, resulting in a use-after-free.
Follow the reverse of the allocation order in ice_alloc_dynamic_port()
by erasing the xarray entry before freeing the VSI.
Fixes: eda69d654c7e ("ice: add basic devlink subfunctions support")
Cc: stable@vger.kernel.org
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Marcin Szycik <marcin.szycik@linux.intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Patryk Holda <patryk.holda@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Link: https://patch.msgid.link/20260928230429.495442-3-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/intel/ice/devlink/port.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/intel/ice/devlink/port.c
+++ b/drivers/net/ethernet/intel/ice/devlink/port.c
@@ -590,8 +590,8 @@ static void ice_dealloc_dynamic_port(str
xa_erase(&pf->sf_nums, devlink_port->attrs.pci_sf.sf);
ice_eswitch_detach_sf(pf, dyn_port);
- ice_vsi_free(dyn_port->vsi);
xa_erase(&pf->dyn_ports, dyn_port->vsi->idx);
+ ice_vsi_free(dyn_port->vsi);
kfree(dyn_port);
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 063/281] ice: fix metadata_dst refcount handling on representor teardown
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (61 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 062/281] ice: fix use-after-free in dynamic port cleanup Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 064/281] io_uring/register: dont exempt disabled rings from task restrictions Greg Kroah-Hartman
` (224 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tristan Madani, Simon Horman,
Tony Nguyen, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <tristan@talencesecurity.com>
commit 58858b8f14803a7eeac297b3ce20f3b21bf2ff66 upstream.
ice_eswitch_release_repr() uses metadata_dst_free() to release the
representor's metadata_dst. metadata_dst_free() directly frees the
underlying memory without checking the dst_entry refcount.
When ice_eswitch_port_start_xmit() processes a packet, it takes a
reference via dst_hold() and attaches the metadata_dst to the skb.
If the representor is torn down while packets are still queued on
the lower device (e.g. in a qdisc), the metadata_dst is freed while
references are still held.
Use dst_release() instead, which correctly decrements the refcount
and only frees the object when all references are dropped. The dst
subsystem already handles metadata_dst cleanup in dst_destroy() when
DST_METADATA is set.
Other drivers sharing this pattern (nfp, airoha, bnxt) already use
dst_release() for their metadata_dst lifecycle.
Fixes: f5396b8a663f7 ("ice: switchdev slow path")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Link: https://patch.msgid.link/20260928230429.495442-5-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/intel/ice/ice_eswitch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/intel/ice/ice_eswitch.c
+++ b/drivers/net/ethernet/intel/ice/ice_eswitch.c
@@ -95,7 +95,7 @@ ice_eswitch_release_repr(struct ice_pf *
return;
ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);
- metadata_dst_free(repr->dst);
+ dst_release(&repr->dst->dst);
repr->dst = NULL;
ice_fltr_add_mac_and_broadcast(vsi, repr->parent_mac,
ICE_FWD_TO_VSI);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 064/281] io_uring/register: dont exempt disabled rings from task restrictions
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (62 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 063/281] ice: fix metadata_dst refcount handling on representor teardown Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 065/281] io_uring/net: populate CONNECT filter fields for 24-byte sockaddr_in6 Greg Kroah-Hartman
` (223 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Eugene Gvozdetsky, Jens Axboe
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eugene Gvozdetsky <gvozdet@gmail.com>
commit 6da8f402e362b2f546e2efb7167fc9597aef6faf upstream.
A ring created with IORING_SETUP_R_DISABLED is exempt from its register
restrictions until it is enabled. This lets the creator register the
restrictions and then enable the ring with IORING_REGISTER_ENABLE_RINGS,
whether or not that opcode is in the allowed set.
Since commit ed82f35b926b ("io_uring: allow registration of per-task
restrictions"), a ring also inherits restrictions from the task that
creates it, and the same exemption applies to those. A task whose
register opcodes are restricted can therefore create a disabled ring,
issue any register opcode on it, and then enable it.
Mark rings whose restrictions were inherited from the task, and keep
checking register opcodes for them while the ring is disabled. Enabling
such a ring now requires IORING_REGISTER_ENABLE_RINGS to be in the
task's allowed set. Per-ring restrictions registered on a disabled ring
work as before.
Fixes: ed82f35b926b ("io_uring: allow registration of per-task restrictions")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Eugene Gvozdetsky <gvozdet@gmail.com>
Link: https://patch.msgid.link/20261009-iouring-task-restrict-fix-v1-1-a49daf55a12c@gmail.com
[axboe: amend with inheritance flag fixup]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/io_uring_types.h | 2 ++
io_uring/io_uring.c | 3 ++-
io_uring/register.c | 9 ++++++++-
3 files changed, 12 insertions(+), 2 deletions(-)
--- a/include/linux/io_uring_types.h
+++ b/include/linux/io_uring_types.h
@@ -316,6 +316,8 @@ enum {
IO_RING_F_DRAIN_DISABLED = BIT(10),
IO_RING_F_COMPAT = BIT(11),
IO_RING_F_IOWQ_LIMITS_SET = BIT(12),
+ /* restrictions were inherited from the task that created the ring */
+ IO_RING_F_RESTRICT_INHERITED = BIT(13),
};
struct iou_ctx {};
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -2967,7 +2967,8 @@ static void io_ctx_restriction_clone(str
if (dst->op_registered)
ctx->int_flags |= IO_RING_F_OP_RESTRICTED;
if (dst->reg_registered)
- ctx->int_flags |= IO_RING_F_REG_RESTRICTED;
+ ctx->int_flags |= IO_RING_F_REG_RESTRICTED |
+ IO_RING_F_RESTRICT_INHERITED;
}
static __cold int io_uring_create(struct io_ctx_config *config)
--- a/io_uring/register.c
+++ b/io_uring/register.c
@@ -764,7 +764,14 @@ static int __io_uring_register(struct io
if (ctx->submitter_task && ctx->submitter_task != current)
return -EEXIST;
- if ((ctx->int_flags & IO_RING_F_REG_RESTRICTED) && !(ctx->flags & IORING_SETUP_R_DISABLED)) {
+ /*
+ * A disabled ring is exempt from its own register restrictions, so
+ * that the creator can set them up and then enable the ring. That
+ * does not apply to restrictions inherited from the task.
+ */
+ if ((ctx->int_flags & IO_RING_F_REG_RESTRICTED) &&
+ (!(ctx->flags & IORING_SETUP_R_DISABLED) ||
+ (ctx->int_flags & IO_RING_F_RESTRICT_INHERITED))) {
opcode = array_index_nospec(opcode, IORING_REGISTER_LAST);
if (!test_bit(opcode, ctx->restrictions.register_op))
return -EACCES;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 065/281] io_uring/net: populate CONNECT filter fields for 24-byte sockaddr_in6
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (63 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 064/281] io_uring/register: dont exempt disabled rings from task restrictions Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 066/281] ip6_gre: remove obsolete ERSPAN PMTU update Greg Kroah-Hartman
` (222 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Natasha Klaus, Jens Axboe
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Natasha Klaus <natalie.klaus@runtimeverification.com>
commit aa5d5f8e502318e783545ba5d04bb40130b83e20 upstream.
io_connect_bpf_populate() fills connect.port and connect.v6_addr for
AF_INET6 only when addr_len >= sizeof(struct sockaddr_in6), i.e. 28
bytes.
The IPv6 connect paths accept SIN6_LEN_RFC2133 (24 bytes), which
already holds sin6_port and sin6_addr. io_connect() passes addr_len to
the socket layer unchanged.
At addr_len 24 the filter sees family AF_INET6 with port and address
zero, while the kernel connects to the real destination. A filter that
denies an IPv6 port or address is bypassed. Denying connect.port == P
rejects [::1]:P with -EACCES at addr_len 28 but connects at addr_len 24.
Use SIN6_LEN_RFC2133 as the threshold. sin6_scope_id stays zero when
absent.
The threshold mismatch was found by an AI coding assistant (Claude Code)
comparing this hook against the net/ipv6 length checks on my
instructions; it also drafted the reproducer and this patch. I verified
the bypass and the fix in a VM on 7.3-rc6 and that 7.2 has the same
code.
Fixes: 899bea8248ce ("io_uring/net: allow filtering on IORING_OP_CONNECT")
Cc: stable@vger.kernel.org # 7.2
Signed-off-by: Natasha Klaus <natalie.klaus@runtimeverification.com>
Link: https://patch.msgid.link/20261009133807.730724-1-natalie.klaus@runtimeverification.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/net.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -7,6 +7,7 @@
#include <linux/un.h>
#include <linux/compat.h>
#include <net/compat.h>
+#include <net/ipv6.h>
#include <linux/io_uring.h>
#include <uapi/linux/io_uring.h>
@@ -1772,7 +1773,8 @@ void io_connect_bpf_populate(struct io_u
case AF_INET6: {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ss;
- if (conn->addr_len < (int)sizeof(*sin6))
+ /* The IPv6 stack accepts SIN6_LEN_RFC2133; port and addr are in it. */
+ if (conn->addr_len < SIN6_LEN_RFC2133)
break;
bctx->connect.port = sin6->sin6_port;
memcpy(bctx->connect.v6_addr, &sin6->sin6_addr,
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 066/281] ip6_gre: remove obsolete ERSPAN PMTU update
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (64 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 065/281] io_uring/net: populate CONNECT filter fields for 24-byte sockaddr_in6 Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 067/281] keys: finalize persistent keyring timeout after link attempt Greg Kroah-Hartman
` (221 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Daehyeon Ko,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit 8bc60db48e8cba35488bbd6e1f94aa990afa275a upstream.
A tc tunnel_key action can attach a METADATA_IP_TUNNEL dst to an skb,
and mirred can redirect it to a native ip6erspan device. The legacy PMTU
update in ip6erspan_tunnel_xmit() treats that metadata dst as a route.
Since it has no output device, dst_dev(dst)->mtu dereferences NULL.
On v7.2 with KASAN, an initial UID/GID 65534 process with CapEff 0 used
self-created user and network namespaces to trigger:
KASAN: null-ptr-deref
RIP: ip6erspan_tunnel_xmit+0x10fc/0x2cc0
Kernel panic - not syncing: Fatal exception in interrupt
The update is obsolete. Commit fe1a4ca0a2b7 ("ip6_gre: process toobig
in a better way") changed IPv6 GRE Too Big handling to update the
underlay route and removed the equivalent block from __gre6_xmit().
ip6_tnl_xmit() then propagates the underlay PMTU to the overlay route.
Remove the stale ERSPAN copy and its now-unused dst variable. This
eliminates the metadata-dst dereference and keeps ERSPAN aligned with
IPv6 GRE PMTU handling.
Fixes: 5a963eb61b7c ("ip6_gre: Add ERSPAN native tunnel support")
Cc: stable@vger.kernel.org
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261002033058.358137-1-4ncienth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/ip6_gre.c | 7 -------
1 file changed, 7 deletions(-)
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -923,7 +923,6 @@ static netdev_tx_t ip6erspan_tunnel_xmit
{
struct ip_tunnel_info *tun_info = NULL;
struct ip6_tnl *t = netdev_priv(dev);
- struct dst_entry *dst = skb_dst(skb);
IP_TUNNEL_DECLARE_FLAGS(flags) = { };
bool truncate = false;
int encap_limit = -1;
@@ -1059,12 +1058,6 @@ static netdev_tx_t ip6erspan_tunnel_xmit
gre_build_header(skb, 8, flags, proto, 0,
htonl(atomic_fetch_inc(&t->o_seqno)));
- /* TooBig packet may have updated dst->dev's mtu */
- if (!t->parms.collect_md && dst) {
- mtu = READ_ONCE(dst_dev(dst)->mtu);
- if (dst_mtu(dst) > mtu)
- dst->ops->update_pmtu(dst, NULL, skb, mtu, false);
- }
err = ip6_tnl_xmit(skb, dev, dsfield, &fl6, encap_limit, &mtu,
NEXTHDR_GRE);
if (err != 0) {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 067/281] keys: finalize persistent keyring timeout after link attempt
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (65 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 066/281] ip6_gre: remove obsolete ERSPAN PMTU update Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 068/281] KEYS: Fix add_key() race with keyring restriction Greg Kroah-Hartman
` (220 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Jarkko Sakkinen
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
commit 25bf14f817168079f731975b8998fc2af380f29e upstream.
When no keyring exists for the requested UID, KEYCTL_GET_PERSISTENT
creates and registers one before linking it to the requested destination.
The configured timeout is set only after the destination link succeeds.
A destination restricted with KEYCTL_RESTRICT_KEYRING makes that link fail
with -EPERM. With persistent_keyring_expiry set to 60 seconds, /proc/keys
still reports the registered keyring's expiry as "perm".
The failed call therefore leaves a quota-exempt keyring in the namespace's
hidden register, where it may remain until namespace teardown.
Rename the write-locked helper to key_get_or_create_persistent() and return
the key reference through a result parameter. Return 0 when it creates a
keyring and 1 when the retry finds an existing one. Return a negative error
on failure. Another caller may create the keyring between the initial
read-locked lookup and the retry under the write lock.
Set the timeout after permission checking and linking. Do this on success,
or on failure if the call allocated the keyring. This leaves a new keyring
collectible after failure without starting its timeout while linking is
still in progress.
Cc: stable@vger.kernel.org # v5.10+
Fixes: f36f8c75ae2e ("KEYS: Add per-user_namespace registers for persistent per-UID kerberos caches")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://lore.kernel.org/r/20260912095440.79864-1-kmehltretter@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/keys/persistent.c | 55 ++++++++++++++++++++++++++-------------------
1 file changed, 32 insertions(+), 23 deletions(-)
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -33,25 +33,31 @@ static int key_create_persistent_registe
}
/*
- * Create the persistent keyring for the specified user.
+ * Get or create the persistent keyring for the specified user.
*
* Called with the namespace's sem locked for writing.
+ *
+ * Returns a boolean indicating whether the keyring already existed,
+ * or a negative error. On success, *persistent_ref holds a reference
+ * to the keyring.
*/
-static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
- struct keyring_index_key *index_key)
+static int key_get_or_create_persistent(struct user_namespace *ns, kuid_t uid,
+ struct keyring_index_key *index_key,
+ key_ref_t *persistent_ref)
{
struct key *persistent;
- key_ref_t reg_ref, persistent_ref;
+ key_ref_t reg_ref;
if (!ns->persistent_keyring_register) {
- long err = key_create_persistent_register(ns);
+ int err = key_create_persistent_register(ns);
+
if (err < 0)
- return ERR_PTR(err);
+ return err;
} else {
reg_ref = make_key_ref(ns->persistent_keyring_register, true);
- persistent_ref = find_key_to_update(reg_ref, index_key);
- if (persistent_ref)
- return persistent_ref;
+ *persistent_ref = find_key_to_update(reg_ref, index_key);
+ if (*persistent_ref)
+ return 1;
}
persistent = keyring_alloc(index_key->description,
@@ -61,9 +67,10 @@ static key_ref_t key_create_persistent(s
KEY_ALLOC_NOT_IN_QUOTA, NULL,
ns->persistent_keyring_register);
if (IS_ERR(persistent))
- return ERR_CAST(persistent);
+ return PTR_ERR(persistent);
- return make_key_ref(persistent, true);
+ *persistent_ref = make_key_ref(persistent, true);
+ return 0;
}
/*
@@ -78,6 +85,7 @@ static long key_get_persistent(struct us
key_ref_t reg_ref, persistent_ref;
char buf[32];
long ret;
+ bool created = false;
/* Look in the register if it exists */
memset(&index_key, 0, sizeof(index_key));
@@ -100,23 +108,24 @@ static long key_get_persistent(struct us
* also need to create the register.
*/
down_write(&ns->keyring_sem);
- persistent_ref = key_create_persistent(ns, uid, &index_key);
+ ret = key_get_or_create_persistent(ns, uid, &index_key,
+ &persistent_ref);
up_write(&ns->keyring_sem);
- if (!IS_ERR(persistent_ref))
- goto found;
-
- return PTR_ERR(persistent_ref);
+ if (ret < 0)
+ return ret;
+ created = ret == 0;
found:
+ persistent = key_ref_to_ptr(persistent_ref);
ret = key_task_permission(persistent_ref, current_cred(), KEY_NEED_LINK);
- if (ret == 0) {
- persistent = key_ref_to_ptr(persistent_ref);
+ if (ret == 0)
ret = key_link(key_ref_to_ptr(dest_ref), persistent);
- if (ret == 0) {
- key_set_timeout(persistent, persistent_keyring_expiry);
- ret = persistent->serial;
- }
- }
+
+ if (ret == 0 || created)
+ key_set_timeout(persistent, persistent_keyring_expiry);
+
+ if (ret == 0)
+ ret = persistent->serial;
key_ref_put(persistent_ref);
return ret;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 068/281] KEYS: Fix add_key() race with keyring restriction
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (66 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 067/281] keys: finalize persistent keyring timeout after link attempt Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 069/281] memstick: core: wait for request completion before freeing card Greg Kroah-Hartman
` (219 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, 성병찬,
Jarkko Sakkinen
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: 성병찬 <tjdqudcks0424@naver.com>
commit dd3ea3fcba7c75493760cdbccd35f029597e8d5e upstream.
__key_create_or_update() snapshots keyring->restrict_link before taking
the destination keyring's semaphore. keyring_restrict() installs a
restriction while holding that semaphore.
This allows a writer to observe no restriction, wait for the keyring
owner to install a reject-all restriction and return successfully, and
then link a key using the stale NULL snapshot. The writer only needs
write permission on the destination keyring.
Move the restrict_link read after __key_link_lock() and
__key_link_begin(). The read and the subsequent restriction check are
then serialized with restriction installation by keyring->sem.
The race was reproduced on v7.2.8 in 19 executions where restriction
installation returned before the link completed. All 19 linked the key
despite the reject-all restriction. With this change, 312 executions
reached the same ordering and every add_key() call failed with -EPERM.
The issue was found by manual concurrency analysis assisted by AI-based
analysis and independently verified with a QEMU reproducer and kernel
instrumentation.
Fixes: 5ac7eace2d00 ("KEYS: Add a facility to restrict new links into a keyring")
Cc: stable@vger.kernel.org
Signed-off-by: 성병찬 <tjdqudcks0424@naver.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260930041802.6114-1-tjdqudcks0424@naver.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/keys/key.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -840,9 +840,6 @@ static key_ref_t __key_create_or_update(
key_check(keyring);
- if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
- restrict_link = keyring->restrict_link;
-
key_ref = ERR_PTR(-ENOTDIR);
if (keyring->type != &key_type_keyring)
goto error_put_type;
@@ -880,6 +877,9 @@ static key_ref_t __key_create_or_update(
goto error_link_end;
}
+ if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
+ restrict_link = keyring->restrict_link;
+
if (restrict_link && restrict_link->check) {
ret = restrict_link->check(keyring, index_key.type,
&prep.payload, restrict_link->key);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 069/281] memstick: core: wait for request completion before freeing card
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (67 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 068/281] KEYS: Fix add_key() race with keyring restriction Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 070/281] memstick: rtsx_usb_ms: complete requests after eject instead of dropping them Greg Kroah-Hartman
` (218 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+ccffdf05833ebdaeae70,
Raj Ojha, Ulf Hansson
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raj Ojha <rajojha047@gmail.com>
commit aa0a37b5024d921e96ac4f8f487c8bfbf1f1a582 upstream.
In memstick_alloc_card() and memstick_set_rw_addr(),
wait_for_completion_timeout() is used to wait for device identification
and address configuration requests to complete.
The memstick subsystem does not provide an abort or cancellation
callback in struct memstick_host for in-flight requests. If
wait_for_completion_timeout() expires (for instance, when a USB transfer
or command retry is delayed), memstick_alloc_card() returns an error and
frees the memstick_dev structure via kfree(card).
However, the host controller driver (such as rtsx_usb_ms) is still
running the request asynchronously in worker context. When the transfer
eventually finishes, the driver writes into host->req->data, which
points to memory inside the already freed card structure. This leads to
a KASAN slab-use-after-free write:
BUG: KASAN: slab-use-after-free in ms_read_bytes+0x8fe/0x990
Write of size 1 at addr ffff88813c188079 by task kworker/1:5/5239
Workqueue: events rtsx_usb_ms_handle_req
Call Trace:
ms_read_bytes+0x8fe/0x990 drivers/memstick/host/rtsx_usb_ms.c:450
rtsx_usb_ms_issue_cmd drivers/memstick/host/rtsx_usb_ms.c:477 [inline]
rtsx_usb_ms_handle_req+0x557/0x1a00 drivers/memstick/host/rtsx_usb_ms.c:531
process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
worker_thread+0x5ef/0xe50 kernel/workqueue.c:3560
kthread+0x373/0x450 kernel/kthread.c:436
Allocated by task 1662:
memstick_alloc_card drivers/memstick/core/memstick.c:383 [inline]
memstick_check+0x2c1/0x10d0 drivers/memstick/core/memstick.c:452
process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
Freed by task 1662:
kfree+0x20c/0x650 mm/slub.c:6792
memstick_alloc_card drivers/memstick/core/memstick.c:420 [inline]
memstick_check+0x72b/0x10d0 drivers/memstick/core/memstick.c:452
process_one_work+0xac7/0x1b10 kernel/workqueue.c:3396
Host controller drivers (rtsx_usb_ms, jmb38x_ms, tifm_ms, r592) already
implement their own hardware and bus timeouts, and callers in
mspro_block and ms_block already rely on wait_for_completion()
unconditionally.
Replace wait_for_completion_timeout() with wait_for_completion() in
memstick_set_rw_addr() and memstick_alloc_card() so that the card
structure is never freed while an asynchronous request is in flight.
Fixes: baf8532a147d ("memstick: initial commit for Sony MemoryStick support")
Reported-by: syzbot+ccffdf05833ebdaeae70@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=ccffdf05833ebdaeae70
Cc: stable@vger.kernel.org
Signed-off-by: Raj Ojha <rajojha047@gmail.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/memstick/core/memstick.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
--- a/drivers/memstick/core/memstick.c
+++ b/drivers/memstick/core/memstick.c
@@ -370,9 +370,7 @@ int memstick_set_rw_addr(struct memstick
{
card->next_request = h_memstick_set_rw_addr;
memstick_new_req(card->host);
- if (!wait_for_completion_timeout(&card->mrq_complete,
- msecs_to_jiffies(500)))
- card->current_mrq.error = -ETIMEDOUT;
+ wait_for_completion(&card->mrq_complete);
return card->current_mrq.error;
}
@@ -405,9 +403,7 @@ static struct memstick_dev *memstick_all
card->next_request = h_memstick_read_dev_id;
memstick_new_req(host);
- if (!wait_for_completion_timeout(&card->mrq_complete,
- msecs_to_jiffies(500)))
- card->current_mrq.error = -ETIMEDOUT;
+ wait_for_completion(&card->mrq_complete);
if (card->current_mrq.error)
goto err_out;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 070/281] memstick: rtsx_usb_ms: complete requests after eject instead of dropping them
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (68 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 069/281] memstick: core: wait for request completion before freeing card Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 071/281] mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP Greg Kroah-Hartman
` (217 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Nguyen Ngoc Thang, Ulf Hansson
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
commit c96ca94425b076dc398d929366e378d1e22ec794 upstream.
memstick_check() can pass its host->removing check just before
rtsx_usb_ms_drv_remove() sets eject/removing. Its next request is then
silently dropped: rtsx_usb_ms_request() skips schedule_work() once eject
is set, and drv_remove's cancel_work_sync() can also cancel a queued
handle_req before it picks the request up. Nobody completes
card->mrq_complete.
Once memstick core waits for requests without a timeout ("memstick: core:
wait for request completion before freeing card"), this hangs removal:
memstick_check() never returns and memstick_remove_host() blocks in
flush_workqueue():
INFO: task kworker/u10:3:65 blocked for more than 20 seconds.
Workqueue: kmemstick memstick_check
__wait_for_common
memstick_check
INFO: task kworker/1:1:33 blocked for more than 20 seconds.
Workqueue: usb_hub_wq hub_event
__flush_workqueue
memstick_remove_host
rtsx_usb_ms_drv_remove
Never drop a request. rtsx_usb_ms_request() always schedules handle_req,
and handle_req fails requests with -ENOMEDIUM once eject is set, without
touching the device. drv_remove flushes handle_req instead of cancelling
it, and cancels it only after memstick_remove_host(), when no new
request can arrive, so it cannot run on a freed host.
The host_mutex drain in drv_remove is removed: handle_req always leaves
host->req NULL when it finishes, so the drain never had anything to do,
and it would now race with handle_req.
Fixes: 99451dceeb5f ("memstick: Add realtek USB memstick host driver")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/20260924204142.607-1-rajojha047@gmail.com/
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/memstick/host/rtsx_usb_ms.c | 31 +++++++++++--------------------
1 file changed, 11 insertions(+), 20 deletions(-)
--- a/drivers/memstick/host/rtsx_usb_ms.c
+++ b/drivers/memstick/host/rtsx_usb_ms.c
@@ -27,7 +27,6 @@ struct rtsx_usb_ms {
struct memstick_host *msh;
struct memstick_request *req;
- struct mutex host_mutex;
struct work_struct handle_req;
struct delayed_work poll_card;
@@ -514,6 +513,13 @@ static void rtsx_usb_ms_handle_req(struc
struct memstick_host *msh = host->msh;
int rc;
+ /* Fail requests after eject so their waiters are released. */
+ if (host->eject) {
+ while (!memstick_next_req(msh, &host->req))
+ host->req->error = -ENOMEDIUM;
+ return;
+ }
+
if (!host->req) {
pm_runtime_get_sync(ms_dev(host));
do {
@@ -547,8 +553,7 @@ static void rtsx_usb_ms_request(struct m
dev_dbg(ms_dev(host), "--> %s\n", __func__);
- if (!host->eject)
- schedule_work(&host->handle_req);
+ schedule_work(&host->handle_req);
}
static int rtsx_usb_ms_set_param(struct memstick_host *msh,
@@ -781,7 +786,6 @@ static int rtsx_usb_ms_drv_probe(struct
host->power_mode = MEMSTICK_POWER_OFF;
platform_set_drvdata(pdev, host);
- mutex_init(&host->host_mutex);
INIT_WORK(&host->handle_req, rtsx_usb_ms_handle_req);
INIT_DELAYED_WORK(&host->poll_card, rtsx_usb_ms_poll_card);
@@ -812,27 +816,12 @@ static void rtsx_usb_ms_drv_remove(struc
{
struct rtsx_usb_ms *host = platform_get_drvdata(pdev);
struct memstick_host *msh = host->msh;
- int err;
host->eject = true;
msh->removing = true;
- cancel_work_sync(&host->handle_req);
+ flush_work(&host->handle_req);
cancel_delayed_work_sync(&host->poll_card);
- mutex_lock(&host->host_mutex);
- if (host->req) {
- dev_dbg(ms_dev(host),
- "%s: Controller removed during transfer\n",
- dev_name(&msh->dev));
- host->req->error = -ENOMEDIUM;
- do {
- err = memstick_next_req(msh, &host->req);
- if (!err)
- host->req->error = -ENOMEDIUM;
- } while (!err);
- }
- mutex_unlock(&host->host_mutex);
-
/* Balance possible unbalanced usage count
* e.g. unconditional module removal
*/
@@ -841,6 +830,8 @@ static void rtsx_usb_ms_drv_remove(struc
pm_runtime_disable(ms_dev(host));
memstick_remove_host(msh);
+ /* No card, no new requests; wait for the last failed one to finish. */
+ cancel_work_sync(&host->handle_req);
dev_dbg(ms_dev(host),
": Realtek USB Memstick controller has been removed\n");
memstick_free_host(msh);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 071/281] mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (69 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 070/281] memstick: rtsx_usb_ms: complete requests after eject instead of dropping them Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 072/281] mm: dont schedule deferred kernel page table freeing while booting Greg Kroah-Hartman
` (216 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Andrew Morton,
Pedro Falcato, Kiryl Shutsemau (Meta), Jose A. Perez de Azpillaga,
Anirudh Srinivasan, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Brian Geffon, Minchan Kim
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
commit 597e4b9ab48a3f841080f627722064853d3f650e upstream.
The MREMAP_DONTUNMAP feature is highly unusual in that it permits mremap()
operations that keep the original VMA in place.
Historically this has led to a lot of bugs where non-obvious interactions
occur between existing mremap() operations and the original VMA.
Fix another of these - partial copies.
The long-standing mremap() partial VMA logic has the baked-in assumption
that the originating VMA is unmapped and thus moved.
However MREMAP_DONTUNMAP defeats this by performing a partial copy
instead since it keeps the source VMA around.
An mremap(..., MREMAP_DONTUNMAP) operation disallows resizing of the VMA,
but the operation can be performed partially:
|-----------------|
| |
| v
<------> <------>
.new_sz. new_sz
|--.------.--| |------|
| .source. | | dest |
|--.------.--| |------|
<------------>
old_sz
The page tables in the specified range are moved, but the original VMA is
kept intact.
This interacts poorly with mlock()'d VMAs, as the VMA_LOCKED_BIT flag is
cleared for the entire source VMA and set for the entire destination VMA.
This results in an mm->locked_vm leak as the change is therefore not
accounted correctly.
The clear solution here is to make the portion of the source VMA which is
mremap()'d distinct from the rest of it, a.k.a. split it.
Therefore resolve this issue by splitting it ahead of the rest of the
mremap() operation if the VMA is mlock()'d.
This is valid, as the source VMA will lose its VMA_LOCKED_BIT flag, so if a
partial remap it will become distinct from the rest of the VMA.
In order to make this change re-expose split_vma() in vma.h for
CONFIG_MMU (nommu doesn't compile mremap.c and uses a static helper
instead).
Finally, update the sys_map_count check to account for this case.
Note that the early check does not use needs_pre_split() - this is because
the VMA has not been looked up by this point, so be conservative and assume
that the VMA is mlock()'d in this case for the purposes of the
sys_map_count check.
Link: https://lore.kernel.org/20260930-fix-dontunmap-partial-self-merge-v2-2-f388985a0f0a@kernel.org
Fixes: e346b3813067 ("mm/mremap: add MREMAP_DONTUNMAP to mremap()")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Tested-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: Brian Geffon <bgeffon@google.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
mm/mremap.c | 62 ++++++++++++++++++++++++++++++++++++++++++++----------------
mm/vma.c | 4 +--
mm/vma.h | 5 ++++
3 files changed, 53 insertions(+), 18 deletions(-)
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -1029,6 +1029,7 @@ static void vrm_stat_account(struct vma_
}
static bool __check_map_count_against_split(struct mm_struct *mm,
+ bool pre_split,
bool before_unmaps)
{
const int sys_map_count = get_sysctl_max_map_count();
@@ -1080,26 +1081,42 @@ static bool __check_map_count_against_sp
* Therefore we must check to ensure we have headroom of 2 additional
* VMAs.
*/
- return map_count + 2 <= sys_map_count;
+ map_count += 2;
+
+ /* If pre-split, the -1 observed above doesn't apply. */
+ if (pre_split)
+ map_count++;
+
+ return map_count <= sys_map_count;
+}
+
+static bool needs_pre_split(struct vma_remap_struct *vrm)
+{
+ /*
+ * An MREMAP_DONTUNMAP of a mlock()'d VMA needs to unlock the
+ * source VMA, so split in this case.
+ */
+ return (vrm->flags & MREMAP_DONTUNMAP) &&
+ vma_test(vrm->vma, VMA_LOCKED_BIT);
}
/* Do we violate the map count limit if we split VMAs when moving the VMA? */
-static bool check_map_count_against_split(void)
+static bool check_map_count_against_split(struct vma_remap_struct *vrm)
{
return __check_map_count_against_split(current->mm,
- /*before_unmaps=*/false);
+ needs_pre_split(vrm), /*before_unmaps=*/false);
}
/* Do we violate the map count limit if we split VMAs prior to early unmaps? */
-static bool check_map_count_against_split_early(void)
+static bool check_map_count_against_split_early(struct vma_remap_struct *vrm)
{
return __check_map_count_against_split(current->mm,
- /*before_unmaps=*/true);
+ vrm->flags & MREMAP_DONTUNMAP, /*before_unmaps=*/true);
}
/*
- * Perform checks before attempting to write a VMA prior to it being
- * moved.
+ * Perform checks and preparation before attempting to write a VMA prior to it
+ * being moved.
*/
static unsigned long prep_move_vma(struct vma_remap_struct *vrm)
{
@@ -1108,19 +1125,17 @@ static unsigned long prep_move_vma(struc
unsigned long old_addr = vrm->addr;
unsigned long old_len = vrm->old_len;
vm_flags_t dummy = vma->vm_flags;
+ const bool split_before = vma->vm_start != old_addr;
+ const bool split_after = vma->vm_end != old_addr + old_len;
- /*
- * We'd prefer to avoid failure later on in do_munmap: we copy a VMA,
- * which may not merge, then (if MREMAP_DONTUNMAP is not set) unmap the
- * source, which may split, causing a net increase of 2 mappings.
- */
- if (!check_map_count_against_split())
+ /* Avoid failure later on. */
+ if (!check_map_count_against_split(vrm))
return -ENOMEM;
if (vma->vm_ops && vma->vm_ops->may_split) {
- if (vma->vm_start != old_addr)
+ if (split_before)
err = vma->vm_ops->may_split(vma, old_addr);
- if (!err && vma->vm_end != old_addr + old_len)
+ if (!err && split_after)
err = vma->vm_ops->may_split(vma, old_addr + old_len);
if (err)
return err;
@@ -1138,6 +1153,21 @@ static unsigned long prep_move_vma(struc
if (err)
return err;
+ /*
+ * To account mlock()'d pages correctly in the MREMAP_DONTUNMAP
+ * case perform any split ahead of time for an mlock()'d VMA.
+ */
+ if (needs_pre_split(vrm)) {
+ VMA_ITERATOR(vmi, vma->vm_mm, old_addr);
+
+ if (split_before)
+ err = split_vma(&vmi, vma, old_addr, 1);
+ if (!err && split_after)
+ err = split_vma(&vmi, vma, old_addr + old_len, 0);
+ vrm->vmi_needs_invalidate = true;
+ return err;
+ }
+
return 0;
}
@@ -1992,7 +2022,7 @@ static unsigned long do_mremap(struct vm
return -EINTR;
vrm->mmap_locked = true;
- if (!check_map_count_against_split_early()) {
+ if (!check_map_count_against_split_early(vrm)) {
mmap_write_unlock(mm);
return -ENOMEM;
}
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -590,8 +590,8 @@ out_free_vma:
* Split a vma into two pieces at address 'addr', a new vma is allocated
* either for the first part or the tail.
*/
-static int split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
- unsigned long addr, int new_below)
+int split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
+ unsigned long addr, int new_below)
{
if (vma->vm_mm->map_count >= get_sysctl_max_map_count())
return -ENOMEM;
--- a/mm/vma.h
+++ b/mm/vma.h
@@ -470,6 +470,11 @@ int do_brk_flags(struct vma_iterator *vm
unsigned long unmapped_area(struct vm_unmapped_area_info *info);
unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info);
+#ifdef CONFIG_MMU
+int split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
+ unsigned long addr, int new_below);
+#endif
+
static inline bool vma_wants_manual_pte_write_upgrade(struct vm_area_struct *vma)
{
/*
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 072/281] mm: dont schedule deferred kernel page table freeing while booting
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (70 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 071/281] mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 073/281] dm-crypt: reject the lmk IV mode with AEAD ciphers Greg Kroah-Hartman
` (215 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikhail Gavrilov, Andrew Morton,
David Hildenbrand (Arm), Lorenzo Stoakes (ARM),
Jose A. Perez de Azpillaga, Dave Hansen, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Vishal Moola (Oracle), Ingo Molnar, Lu Baolu, Jason Gunthorpe,
Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
commit 2fb552b0bee70c24c092720028ab4620f5eb2646 upstream.
Booting with a boot-time function tracer and a filter, for example
ftrace=function ftrace_filter=pud_free_pmd_page
panics on 7.3-rc4 as soon as the tracer starts:
[ 23.531178] Starting tracer 'function'
[ 23.675800] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000038: 0000 [#1] SMP KASAN NOPTI
[ 23.819917] KASAN: null-ptr-deref in range [0x00000000000001c0-0x00000000000001c7]
[ 23.964025] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 7.3.0-rc4-fe2ec83746e5-with-fixes-v2+ #195 PREEMPT(undef)
[ 24.252248] RIP: 0010:__queue_work+0xab/0xf00
[ 25.981629] Call Trace:
[ 26.125727] <TASK>
[ 26.413912] ? pagetable_free_kernel+0x20/0x120
[ 26.990283] queue_work_on+0x97/0xf0
[ 27.134382] __cpa_collapse_large_pages+0x501/0x6f0
[ 27.566662] cpa_flush+0x394/0x620
[ 27.998953] change_page_attr_set_clr+0x321/0x4a0
[ 29.151729] set_memory_rox+0xa2/0xf0
[ 29.584018] create_trampoline+0x431/0x6f0
...
[ 44.343347] Kernel panic - not syncing: Attempted to kill the idle task!
The boot-time tracer is started from early_trace_init(), which runs
before workqueue_init_early(). Making its trampoline read-only splits a
large page, and CPA collapses it again right away. The split table has
been a kernel page table since commit 9e4a3ec3411b
("x86/mm/pat: Allocate split page tables as kernel page tables"), so the
collapse frees it through pagetable_free_kernel(), which queues work on
system_percpu_wq - still NULL at that point. That commit is correct in
itself; it only lets CPA reach pagetable_free_kernel() before the
workqueue that function relies on exists.
Keep putting the table on the list, but don't schedule the work while
the system is still booting. A core_initcall schedules it once to free
whatever was queued by then.
Link: https://lore.kernel.org/20260925050647.86913-1-mikhail.v.gavrilov@gmail.com
Link: https://lore.kernel.org/20260924064321.23787-1-mikhail.v.gavrilov@gmail.com
Fixes: 9e4a3ec3411b ("x86/mm/pat: Allocate split page tables as kernel page tables")
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Suggested-by: David Hildenbrand (Arm) <david@kernel.org>
Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Tested-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Lu Baolu <baolu.lu@linux.intel.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
mm/pgtable-generic.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -438,12 +438,30 @@ static void kernel_pgtable_work_func(str
__pagetable_free(pt);
}
+static void schedule_kernel_pgtable_free(void)
+{
+ schedule_work(&kernel_pgtable_work.work);
+}
+
void pagetable_free_kernel(struct ptdesc *pt)
{
spin_lock(&kernel_pgtable_work.lock);
list_add(&pt->pt_list, &kernel_pgtable_work.list);
spin_unlock(&kernel_pgtable_work.lock);
- schedule_work(&kernel_pgtable_work.work);
+ /*
+ * The workqueue may not exist yet while the system is booting.
+ * kernel_pgtable_drain_early() schedules the work once it does.
+ */
+ if (system_state != SYSTEM_BOOTING)
+ schedule_kernel_pgtable_free();
+}
+
+static int __init kernel_pgtable_drain_early(void)
+{
+ /* Free the kernel page tables queued while booting. */
+ schedule_kernel_pgtable_free();
+ return 0;
}
+core_initcall(kernel_pgtable_drain_early);
#endif
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 073/281] dm-crypt: reject the lmk IV mode with AEAD ciphers
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (71 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 072/281] mm: dont schedule deferred kernel page table freeing while booting Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 074/281] dm-integrity: fix buffer overflow in inline mode with large tag size Greg Kroah-Hartman
` (214 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ben Cressey, Mikulas Patocka
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Cressey <ben@cressey.dev>
commit 3195e0daf590683992edb4eed32269e569e04924 upstream.
A "capi:" table line that pairs an AEAD cipher with the lmk IV mode,
for example "capi:gcm(aes)-lmk" with the integrity:28:aead option,
causes an oops when it is loaded. lmk sets tfms_count to 64, but
crypt_alloc_tfms_aead only allocates one transform, so crypt_setkey
reads past the end of the tfms_aead array and calls crypto_aead_setkey
on the values it finds there.
lmk exists for compatibility with Loop-AES, which uses CBC, so refuse
it with an AEAD cipher rather than allocate 64 AEAD transforms. The
check cannot go in crypt_iv_lmk_ctr with the other lmk checks, because
the IV constructor runs after crypt_set_key.
Note that this is not a security bug because the memory corruption can
only be triggered by root.
Fixes: 33d2f09fcb35 ("dm crypt: introduce new format of cipher with "capi:" prefix")
Cc: stable@vger.kernel.org
Signed-off-by: Ben Cressey <ben@cressey.dev>
Assisted-by: LLM
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/md/dm-crypt.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -2895,8 +2895,13 @@ static int crypt_ctr_cipher_new(struct d
}
}
- if (*ivmode && !strcmp(*ivmode, "lmk"))
+ if (*ivmode && !strcmp(*ivmode, "lmk")) {
+ if (crypt_integrity_aead(cc)) {
+ ti->error = "AEAD transforms not supported for LMK";
+ return -EINVAL;
+ }
cc->tfms_count = 64;
+ }
if (*ivmode && !strcmp(*ivmode, "essiv")) {
if (!*ivopts) {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 074/281] dm-integrity: fix buffer overflow in inline mode with large tag size
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (72 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 073/281] dm-crypt: reject the lmk IV mode with AEAD ciphers Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 075/281] dm-snap: reject the transient exception store for snapshot-merge Greg Kroah-Hartman
` (213 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ben Cressey, Mikulas Patocka
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Cressey <ben@cressey.dev>
commit 764b683a6180fd72c931c13fea98d383506a3475 upstream.
In inline mode, dm_integrity_check and dm_integrity_inline_recheck
compute the checksum of each block into an on-stack buffer of
HASH_MAX_DIGESTSIZE bytes. integrity_sector_checksum pads its result
with zeroes up to the tag size, so if the tag size is larger than
HASH_MAX_DIGESTSIZE, the padding runs past the end of the buffer. With
CONFIG_STACKPROTECTOR the kernel panics in dm_integrity_check on the
first read.
Enlarge both buffers to hold MAX_TAG_SIZE bytes, as commit b93b6643e9b5
("dm integrity: fix a crash with unusually large tag size") did for
integrity_metadata.
Note that this is not a security bug because the buffer overflow can only
be triggered by root.
Fixes: fb0987682c62 ("dm-integrity: introduce the Inline mode")
Cc: stable@vger.kernel.org
Signed-off-by: Ben Cressey <ben@cressey.dev>
Assisted-by: LLM
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/md/dm-integrity.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -2721,7 +2721,7 @@ static void dm_integrity_inline_recheck(
outgoing_data = dio->integrity_payload + PAGE_SIZE;
while (dio->bio_details.bi_iter.bi_size) {
- char digest[HASH_MAX_DIGESTSIZE];
+ char digest[MAX_T(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)];
int r;
struct bio_integrity_payload *bip;
struct bio_vec bv;
@@ -2788,7 +2788,7 @@ static inline bool dm_integrity_check(st
unsigned pos = 0;
while (dio->bio_details.bi_iter.bi_size) {
- char digest[HASH_MAX_DIGESTSIZE];
+ char digest[MAX_T(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)];
struct bio_vec bv = bio_iter_iovec(bio, dio->bio_details.bi_iter);
char *mem = integrity_kmap(ic, bv.bv_page);
integrity_sector_checksum(ic, &dio->ahash_req, dio->bio_details.bi_iter.bi_sector, mem, bv.bv_offset, digest);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 075/281] dm-snap: reject the transient exception store for snapshot-merge
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (73 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 074/281] dm-integrity: fix buffer overflow in inline mode with large tag size Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 076/281] dm: fix reading free memory in do_resume Greg Kroah-Hartman
` (212 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ma Xinmeng, Mikulas Patocka
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Xinmeng <1564938642@qq.com>
commit fcbde6227fcc53c73f08c56b2539e462d545cac6 upstream.
snapshot_merge_next_chunks() calls s->store->type->prepare_merge() without
checking it. The transient store ("N") implements neither prepare_merge nor
commit_merge, and snapshot_ctr() validates those callbacks only on the handover
path (__validate_exception_handover()), so a directly constructed snapshot-merge
calls a NULL prepare_merge on resume:
snapshot_merge_resume -> snapshot_merge_next_chunks -> prepare_merge(...)
commit_merge() is NULL for the same reason. Userspace only issues documented
device-mapper ioctls (CAP_SYS_ADMIN); this is a misconfiguration the kernel must
reject rather than oops on.
Reject the combination in snapshot_ctr() at table-load time (-EINVAL), the same
check the handover path already performs; this also covers the commit_merge()
call site, which a guard local to the prepare_merge call would miss.
Tested on Linux v6.6.157 KASAN: unpatched, the dmsetup reproducer oopses in
snapshot_merge_next_chunks(); with this patch, the table load fails with -EINVAL
and no oops. Also present on v6.6.145; still present on the linux-dm tree
(555f3d7be91a) and on torvalds/linux master (62f4c998b297) as of 2026-09-22.
Note that this is not a security bug because only root can trigger it.
Signed-off-by: Ma Xinmeng <1564938642@qq.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/md/dm-snap.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1294,6 +1294,20 @@ static int snapshot_ctr(struct dm_target
goto bad_store;
}
+ /*
+ * snapshot-merge requires the optional prepare_merge/commit_merge
+ * callbacks; the transient exception store does not implement them.
+ * The handover path checks this in __validate_exception_handover(),
+ * but a directly constructed snapshot-merge never goes through it.
+ */
+ if (dm_target_is_snapshot_merge(ti) &&
+ (!s->store->type->prepare_merge ||
+ !s->store->type->commit_merge)) {
+ ti->error = "Snapshot exception store does not support snapshot-merge.";
+ r = -EINVAL;
+ goto bad_hash_tables;
+ }
+
argv += args_used;
argc -= args_used;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 076/281] dm: fix reading free memory in do_resume
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (74 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 075/281] dm-snap: reject the transient exception store for snapshot-merge Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 077/281] mmc: cavium-octeon: destroy slot platform devices on remove Greg Kroah-Hartman
` (211 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikulas Patocka,
syzbot+bdff1ecf726d2af66afd
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <mpatocka@redhat.com>
commit c9417c1c5269e2bd0570fbe53e4ec03a8d31f008 upstream.
When do_resume calls dm_table_get_mode(new_map), the call is done without
holding any locks (it only holds a reference to the md). It may be
possible that another concurrent ioctl on the same device will swap table
after dm_swap_table and before dm_table_get_mode. In this case,
dm_table_get_mode(new_map) reads freed memory.
This race condition was triggered by syzbot.
This commit fixes the race by reading mode of the new table before
dm_swap_table. Note that new_map is also passed to dm_ima_need_measure,
but this function doesn't attempt to dereference it, so this call should
be safe.
Note that this is not a security bug because only root can trigger it and
the commonly used tools such as lvm or cryptsetup do not call the ioctls
concurrently, so that they can't trigger it acceidentally.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reported-by: syzbot+bdff1ecf726d2af66afd@syzkaller.appspotmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/md/dm-ioctl.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1295,6 +1295,7 @@ static int do_resume(struct dm_ioctl *pa
/* Do we need to load a new map ? */
if (new_map) {
sector_t old_size, new_size;
+ blk_mode_t new_map_mode;
dm_ima_context_table_op(md, ima_context, DM_IMA_TABLE_SAVE);
/* Suspend if it isn't already suspended */
@@ -1327,6 +1328,7 @@ static int do_resume(struct dm_ioctl *pa
}
}
+ new_map_mode = dm_table_get_mode(new_map);
old_size = dm_get_size(md);
old_map = dm_swap_table(md, new_map);
if (IS_ERR(old_map)) {
@@ -1342,7 +1344,7 @@ static int do_resume(struct dm_ioctl *pa
if (old_size && new_size && old_size != new_size)
need_resize_uevent = true;
- if (dm_table_get_mode(new_map) & BLK_OPEN_WRITE)
+ if (new_map_mode & BLK_OPEN_WRITE)
set_disk_ro(dm_disk(md), 0);
else
set_disk_ro(dm_disk(md), 1);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 077/281] mmc: cavium-octeon: destroy slot platform devices on remove
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (75 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 076/281] dm: fix reading free memory in do_resume Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 078/281] mmc: cavium-thunderx: " Greg Kroah-Hartman
` (210 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Ulf Hansson
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit 0f4d4424fc1d651ec3fa63a0a8060ba9087eb0ec upstream.
octeon_mmc_probe() creates host->slot_pdev[i] with
of_platform_device_create(), while octeon_mmc_remove() does not destroy
the child platform devices.
The probe failure path removes each MMC slot and destroys its associated
platform device, but the normal remove path only removes the MMC slot.
As a result, the child platform devices remain registered after the
Octeon MMC controller is removed.
Destroy each slot platform device during removal after cleaning up the
corresponding MMC slot, matching the probe failure cleanup path.
This issue was found by manual code inspection.
Fixes: 01d95843335c ("mmc: cavium: Add MMC support for Octeon SOCs.")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/cavium-octeon.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/mmc/host/cavium-octeon.c
+++ b/drivers/mmc/host/cavium-octeon.c
@@ -301,9 +301,12 @@ static void octeon_mmc_remove(struct pla
u64 dma_cfg;
int i;
- for (i = 0; i < CAVIUM_MAX_MMC; i++)
+ for (i = 0; i < CAVIUM_MAX_MMC; i++) {
if (host->slot[i])
cvm_mmc_of_slot_remove(host->slot[i]);
+ if (host->slot_pdev[i])
+ of_platform_device_destroy(&host->slot_pdev[i]->dev, NULL);
+ }
dma_cfg = readq(host->dma_base + MIO_EMM_DMA_CFG(host));
dma_cfg &= ~MIO_EMM_DMA_CFG_EN;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 078/281] mmc: cavium-thunderx: destroy slot platform devices on remove
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (76 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 077/281] mmc: cavium-octeon: destroy slot platform devices on remove Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 079/281] mmc: mtk-sd: Cancel request timeout work " Greg Kroah-Hartman
` (209 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Ulf Hansson
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit 29ee8cf18a21b02cd0b2e35f741b61cd1fe3e14e upstream.
thunder_mmc_probe() creates host->slot_pdev[i] with
of_platform_device_create(), while thunder_mmc_remove() does not destroy
the child platform devices.
The probe failure path removes each MMC slot and destroys its associated
platform device, but the normal remove path only removes the MMC slot.
As a result, the child platform devices remain registered after the
ThunderX MMC controller is removed.
Destroy each slot platform device during removal after cleaning up the
corresponding MMC slot, matching the probe failure cleanup path. Keep an
extra device reference around of_platform_device_destroy() as done in
the existing error path.
This issue was found by manual code inspection.
Fixes: 166bac38c3c56 ("mmc: cavium: Add MMC PCI driver for ThunderX SOCs")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/cavium-thunderx.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/mmc/host/cavium-thunderx.c
+++ b/drivers/mmc/host/cavium-thunderx.c
@@ -173,9 +173,12 @@ static void thunder_mmc_remove(struct pc
u64 dma_cfg;
int i;
- for (i = 0; i < CAVIUM_MAX_MMC; i++)
+ for (i = 0; i < CAVIUM_MAX_MMC; i++) {
if (host->slot[i])
cvm_mmc_of_slot_remove(host->slot[i]);
+ if (host->slot_pdev[i])
+ of_platform_device_destroy(&host->slot_pdev[i]->dev, NULL);
+ }
dma_cfg = readq(host->dma_base + MIO_EMM_DMA_CFG(host));
dma_cfg &= ~MIO_EMM_DMA_CFG_EN;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 079/281] mmc: mtk-sd: Cancel request timeout work on remove
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (77 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 078/281] mmc: cavium-thunderx: " Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 080/281] mmc: sdhci-sprd: disable runtime PM " Greg Kroah-Hartman
` (208 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yibo Tan, Ulf Hansson
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yibo Tan <lhfff@tju.edu.cn>
commit b38af5386a74416e898955443f2e26547b358cb2 upstream.
The driver queues req_timeout while a request is active.
msdc_request_done() uses cancel_delayed_work(), which does not wait for
a timeout callback that has already started.
The timeout callback calls mmc_request_done(), which wakes the request
waiter, and then continues to use host->dev_comp and check the SDIO IRQ.
During unbind, msdc_drv_remove() can return and the managed mmc_host can
be freed before the callback finishes.
KASAN reported use-after-free accesses in msdc_request_done() and
msdc_recheck_sdio_irq() in each of three unbind tests. The same tests
completed without a kernel diagnostic after this change.
Call cancel_delayed_work_sync() after mmc_remove_host() has stopped new
requests and before the driver releases the host resources.
Fixes: 208489032bdd ("mmc: mediatek: Add Mediatek MMC driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/mtk-sd.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -3216,6 +3216,7 @@ static void msdc_drv_remove(struct platf
platform_set_drvdata(pdev, NULL);
mmc_remove_host(mmc);
+ cancel_delayed_work_sync(&host->req_timeout);
msdc_deinit_hw(host);
msdc_gate_clock(host);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 080/281] mmc: sdhci-sprd: disable runtime PM on remove
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (78 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 079/281] mmc: mtk-sd: Cancel request timeout work " Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 081/281] net/packet: guard the ll header push in packet_rcv_spkt() Greg Kroah-Hartman
` (207 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Baolin Wang,
Adrian Hunter, Ulf Hansson
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
commit e1c6c10a6a70a69e29b04fcc1ebe4b9bcbc7a49a upstream.
sdhci_sprd_probe() enables runtime PM, while sdhci_sprd_remove() does
not perform the corresponding runtime PM cleanup.
The probe failure path disables runtime PM before disabling the clocks,
but the normal remove path directly disables clocks that are also
managed by the runtime PM callbacks. If the device is runtime
suspended, those clocks may already be disabled.
Resume the device before removal, disable runtime PM and drop the
temporary runtime PM reference before disabling the clocks.
This issue was found by manual code inspection.
Fixes: fb8bd90f83c4 ("mmc: sdhci-sprd: Add Spreadtrum's initial host controller")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/sdhci-sprd.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/mmc/host/sdhci-sprd.c
+++ b/drivers/mmc/host/sdhci-sprd.c
@@ -890,6 +890,10 @@ static void sdhci_sprd_remove(struct pla
struct sdhci_host *host = platform_get_drvdata(pdev);
struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
+ pm_runtime_get_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_put_noidle(&pdev->dev);
+
sdhci_remove_host(host, 0);
clk_disable_unprepare(sprd_host->clk_sdio);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 081/281] net/packet: guard the ll header push in packet_rcv_spkt()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (79 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 080/281] mmc: sdhci-sprd: disable runtime PM " Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 082/281] net/smc: protect clcsock lifetime in smc_getname Greg Kroah-Hartman
` (206 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Quchaosheng, Willem de Bruijn,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Quchaosheng <quchaosheng000406@163.com>
commit 28bc1ef699610ee09ce3d46a00552f5a0a0144bd upstream.
packet_rcv_spkt() restores the link layer header with
skb_push(skb, skb->data - skb_mac_header(skb));
That subtraction is only meaningful when the device actually has a link
layer header. packet_rcv() and tpacket_rcv() both wrap it in
dev_has_header(), which is also the predicate the block comment at the
top of the file states the restore in terms of; packet_rcv_spkt() does
not. commit d549699048b4 ("net/packet: fix packet receive on L3
devices without visible hard header") introduced the helper and changed
the two call sites, and this one stayed behind.
A device without a visible ll header can leave skb->mac_header at the
0xFFFF sentinel that __alloc_skb() initialises it to. A CAN skb does:
init_can_skb() sets pkt_type and ip_summed but does not reset the
headers, and commit 9f10374bb024 ("can: remove private CAN skb
headroom infrastructure") dropped the skb_reset_*_header() calls that
used to be there. skb_mac_header() is then 0xFFFF, the length becomes
a large negative number and skb_push() reports it through
skb_under_panic() -- from softirq context, so it is a full system panic
even with panic_on_oops=0:
skbuff: skb_under_panic: text:ffffffff8bd21bc1 len:-65455 put:-65471 head:... data:... tail:0x50 end:0x180 dev:can0
kernel BUG at net/core/skbuff.c:214!
RIP: 0010:skb_panic+0x50/0x60
Call Trace:
<IRQ>
skb_push+0x38/0x40
packet_rcv_spkt+0xe1/0x170
__netif_receive_skb_core.constprop.0+0x7e8/0xd30
...
Kernel panic - not syncing: Fatal exception in interrupt
The socket type is reachable: packet_create() accepts SOCK_PACKET
alongside SOCK_RAW and SOCK_DGRAM behind the same CAP_NET_RAW check,
and neither the socket length nor a capability check keeps it away
from a CAN interface.
The missing skb_reset_*_header() calls in init_can_skb() are a
regression in their own right and are being fixed separately, but a
packet socket should not turn a link layer that did not initialise its
mac header into a kernel panic. Guard the push the way the other two
receive paths do.
Tested on v7.3-rc5 under QEMU with a slcan device on a pty, which is
the driver RX path: vcan does not reproduce it, because can_send()
resets the headers on the way out. One SOCK_PACKET socket bound to
can0 and one frame written into the line discipline panics an
unpatched kernel with the trace above; the same image with this patch
prints no panic and powers off normally. Both kernels are this tree,
defconfig plus CONFIG_CAN_SLCAN=y, differing only in this hunk.
Fixes: d549699048b4 ("net/packet: fix packet receive on L3 devices without visible hard header")
Cc: stable@vger.kernel.org
Signed-off-by: Quchaosheng <quchaosheng000406@163.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260928113108.2127215-1-quchaosheng000406@163.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/packet/af_packet.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1911,7 +1911,8 @@ static int packet_rcv_spkt(struct sk_buf
spkt = &PACKET_SKB_CB(skb)->sa.pkt;
- skb_push(skb, skb->data - skb_mac_header(skb));
+ if (dev_has_header(dev))
+ skb_push(skb, skb->data - skb_mac_header(skb));
/*
* The SOCK_PACKET socket receives _all_ frames.
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 082/281] net/smc: protect clcsock lifetime in smc_getname
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (80 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 081/281] net/packet: guard the ll header push in packet_rcv_spkt() Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 083/281] net: bridge: avoid recursive multicast port cleanup Greg Kroah-Hartman
` (205 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Mahanta Jambigi,
Dust Li, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 64a6b36b0e1855288080bc5f89769f27d6dc03c8 upstream.
smc_getname() dereferences smc->clcsock without holding
clcsock_release_lock. Link-group termination can release the CLC socket
through smc_close_active_abort() while the SMC socket is still open,
for example after shutdown(SHUT_WR).
A getsockname() caller can load smc->clcsock, then the termination worker
can clear the pointer and call sock_release() before the caller accesses
clcsock->ops or invokes getname(). This causes a use-after-free; if the
worker clears the pointer before the load, it causes a NULL dereference.
The syscall's file reference keeps the SMC socket alive but does not
prevent asynchronous release of its CLC socket.
KASAN reported the following with test-only timing instrumentation:
BUG: KASAN: slab-use-after-free in smc_getname+0x19e/0x1b0
Read of size 8 at addr ffff888109abb4e0 by task poc/103
Call Trace:
smc_getname+0x19e/0x1b0
do_getsockname+0xe5/0x170
__sys_getsockname+0x8c/0x100
Allocated by task 95:
sock_alloc_inode+0x1e/0x280
sock_alloc+0x3d/0x240
__sock_create+0x7e/0x430
smc_create+0x121/0x240
Freed by task 0:
kmem_cache_free+0xcc/0x340
rcu_core+0x50a/0x1850
Last potentially related work creation:
evict+0x446/0x6c0
smc_clcsock_release+0xa8/0xd0
smc_close_active_abort+0x26a/0x3a0
__smc_lgr_terminate.part.0+0x137/0x2e0
Hold clcsock_release_lock across the pointer check and the getname()
callback to serialize with smc_clcsock_release(). Return -EBADF if the
CLC socket has already been released, preserving the existing peer
state check and the callback's return value otherwise.
Fixes: b03faa1fafc8 ("net/smc: postpone release of clcsock")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
Link: https://patch.msgid.link/20261008084444.787449-1-nicoyip.dev@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/smc/af_smc.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -2784,6 +2784,7 @@ int smc_getname(struct socket *sock, str
int peer)
{
struct smc_sock *smc;
+ int rc = -EBADF;
if (peer && (sock->sk->sk_state != SMC_ACTIVE) &&
(sock->sk->sk_state != SMC_APPCLOSEWAIT1))
@@ -2791,7 +2792,11 @@ int smc_getname(struct socket *sock, str
smc = smc_sk(sock->sk);
- return smc->clcsock->ops->getname(smc->clcsock, addr, peer);
+ mutex_lock(&smc->clcsock_release_lock);
+ if (smc->clcsock)
+ rc = smc->clcsock->ops->getname(smc->clcsock, addr, peer);
+ mutex_unlock(&smc->clcsock_release_lock);
+ return rc;
}
int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 083/281] net: bridge: avoid recursive multicast port cleanup
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (81 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 082/281] net/smc: protect clcsock lifetime in smc_getname Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 084/281] net: dsa: microchip: fix KSZ8765 fiber detection Greg Kroah-Hartman
` (204 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zixuan Chai, Ren Wei,
David S. Miller
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zixuan Chai <petalzu987@gmail.com>
commit 5158353121bae4f552cb677ce8c5c3ef52f93a0d upstream.
br_multicast_sg_del_exclude_ports() removes automatically added STAR_EXCL
port groups by calling br_multicast_del_pg(). For S,G entries, that
deletion calls back into br_multicast_sg_del_exclude_ports(), so a large
number of STAR_EXCL ports consumes one kernel stack frame per port and can
hit the stack guard page.
Keep the complete port-group deletion path for cleanup, but suppress the
S,G exclude-port cleanup while that helper is already walking the same
entry. Normal deletion callers retain the existing behavior.
Fixes: 8266a0491e92 ("net: bridge: mcast: handle port group filter modes")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Zixuan Chai <petalzu987@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bridge/br_multicast.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -81,6 +81,10 @@ __br_multicast_add_group(struct net_brid
bool blocked);
static void br_multicast_find_del_pg(struct net_bridge *br,
struct net_bridge_port_group *pg);
+static void __br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
+ struct net_bridge_port_group *pg,
+ struct net_bridge_port_group __rcu **pp,
+ bool sg_del_exclude_ports);
static void __br_multicast_stop(struct net_bridge_mcast *brmctx);
static int br_mc_disabled_update(struct net_device *dev, bool value,
@@ -458,7 +462,7 @@ static void br_multicast_sg_del_exclude_
for (pp = &sgmp->ports;
(p = mlock_dereference(*pp, sgmp->br)) != NULL;) {
if (!(p->flags & MDB_PG_FLAGS_PERMANENT))
- br_multicast_del_pg(sgmp, p, pp);
+ __br_multicast_del_pg(sgmp, p, pp, false);
else
pp = &p->next;
}
@@ -799,9 +803,10 @@ static void br_multicast_destroy_port_gr
kfree_rcu(pg, rcu);
}
-void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
- struct net_bridge_port_group *pg,
- struct net_bridge_port_group __rcu **pp)
+static void __br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
+ struct net_bridge_port_group *pg,
+ struct net_bridge_port_group __rcu **pp,
+ bool sg_del_exclude_ports)
{
struct net_bridge *br = pg->key.port->br;
struct net_bridge_group_src *ent;
@@ -816,7 +821,8 @@ void br_multicast_del_pg(struct net_brid
if (!br_multicast_is_star_g(&mp->addr)) {
rhashtable_remove_fast(&br->sg_port_tbl, &pg->rhnode,
br_sg_port_rht_params);
- br_multicast_sg_del_exclude_ports(mp);
+ if (sg_del_exclude_ports)
+ br_multicast_sg_del_exclude_ports(mp);
} else {
br_multicast_star_g_handle_mode(pg, MCAST_INCLUDE);
}
@@ -828,6 +834,13 @@ void br_multicast_del_pg(struct net_brid
mod_timer(&mp->timer, jiffies);
}
+void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
+ struct net_bridge_port_group *pg,
+ struct net_bridge_port_group __rcu **pp)
+{
+ __br_multicast_del_pg(mp, pg, pp, true);
+}
+
static void br_multicast_find_del_pg(struct net_bridge *br,
struct net_bridge_port_group *pg)
{
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 084/281] net: dsa: microchip: fix KSZ8765 fiber detection
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (82 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 083/281] net: bridge: avoid recursive multicast port cleanup Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 085/281] net: skbuff: dont leave stale bytes in skb_copy_and_csum_bits() Greg Kroah-Hartman
` (203 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Sebastien Royen,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastien Royen <sebastien.royen@armadeus.com>
commit fc13ba44da197a186f2f4d77c5b7d73d0f99f053 upstream.
The KSZ8765 is similar to the KSZ8795 but has two fiber ports.
KSZ8_PORT_STATUS_0 is used to detect fiber mode. It is currently
defined as 0x08, which is the Global Control 6 MIB Control register
and has bit 7 defined as Flush Counter.
Set KSZ8_PORT_STATUS_0 to 0x18, which is the Port 1 Status 0 register
where bit 7 is the Fiber Mode bit.
This issue was discovered when upgrading an embedded device from kernel
5.10 to 6.16. The device was using a KSZ8765 device tree configuration
and the corresponding hardware, but during boot the kernel incorrectly
detected it as a KSZ8795. The relevant boot messages were:
ksz-switch spi0.0: found switch: KSZ8795, rev 0
ksz-switch spi0.0: Device tree specifies chip KSZ8765 but found KSZ8795, please fix it!
Cc: stable@vger.kernel.org
Fixes: 91a98917a883 ("net: dsa: microchip: move switch chip_id detection to ksz_common")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Sebastien Royen <sebastien.royen@armadeus.com>
Link: https://patch.msgid.link/20261007080557.15719-1-sebastien.royen@armadeus.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/dsa/microchip/ksz_common.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -778,7 +778,7 @@ static inline bool ksz_is_sgmii_port(str
#define KSZ88_FAMILY_ID 0x88
#define KSZ8895_FAMILY_ID 0x95
-#define KSZ8_PORT_STATUS_0 0x08
+#define KSZ8_PORT_STATUS_0 0x18
#define KSZ8_PORT_FIBER_MODE BIT(7)
#define SW_CHIP_ID_M GENMASK(7, 4)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 085/281] net: skbuff: dont leave stale bytes in skb_copy_and_csum_bits()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (83 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 084/281] net: dsa: microchip: fix KSZ8765 fiber detection Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 086/281] net: sparx5: free the matchall entry on destroy Greg Kroah-Hartman
` (202 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Mina Almasry,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
commit ab9414ed70bd783e902a85c350620dee269bcb2b upstream.
When skb_copy_and_csum_bits() reaches unreadable frags it returns 0
after copying only the linear part, and the rest of the caller's buffer
is left as it was. The callers copy into a buffer that is about to go
out on the wire: an ICMP error quoting the offending packet, or a
driver's TX bounce buffer in skb_copy_and_csum_dev(). Neither buffer
is zeroed beforehand, so whatever was in memory there gets sent.
Zero the part of the buffer we didn't fill. The checksum usually
won't match the data any more, so the receiver will usually drop the
packet, but either way it no longer carries anything it shouldn't.
Only zero for a positive @len, a negative one from a broken caller must
not turn into a huge memset().
Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20261007-b4-skb-copy-csum-stale-bytes-v1-1-adbbde033fb3@toxicpanda.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/core/skbuff.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3633,8 +3633,12 @@ __wsum skb_copy_and_csum_bits(const stru
pos = copy;
}
- if (!skb_frags_readable(skb))
+ if (!skb_frags_readable(skb)) {
+ /* Don't hand the caller a buffer with stale bytes in it. */
+ if (len > 0)
+ memset(to, 0, len);
return 0;
+ }
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
int end;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 086/281] net: sparx5: free the matchall entry on destroy
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (84 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 085/281] net: skbuff: dont leave stale bytes in skb_copy_and_csum_bits() Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 087/281] net: usb: ax88179_178a: fix rx frame length for non-last packets Greg Kroah-Hartman
` (201 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Daniel Machon, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Machon <daniel.machon@microchip.com>
commit 2b82e16d6084cbc651e3c902198f1945408ee1a5 upstream.
sparx5_tc_matchall_replace() allocates a struct sparx5_mall_entry for
every offloaded matchall filter and adds it to sparx5->mall_entries.
sparx5_tc_matchall_destroy() removes the entry from the list, but never
frees it, so the entry of every deleted mirror and goto matchall filter
is leaked.
Free the entry after unlinking it.
The leak was discovered by an AI code review agent, and reproduced with
kmemleak on a lan969x EV board (EV23X71A) by repeatedly adding and
deleting matchall mirror and goto filters. With the fix, kmemleak no
longer reports the leak.
Cc: stable@vger.kernel.org
Fixes: 1ede4acf045c ("net: sparx5: add bookkeeping code for matchall rules")
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261007-sparx5-matchall-kfree-net-v1-1-c8918685b337@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c
@@ -160,6 +160,7 @@ static int sparx5_tc_matchall_destroy(st
}
list_del(&entry->list);
+ kfree(entry);
return err;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 087/281] net: usb: ax88179_178a: fix rx frame length for non-last packets
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (85 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 086/281] net: sparx5: free the matchall entry on destroy Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 088/281] net: xilinx: axienet: Free outstanding DMA buffers on dmaengine stop Greg Kroah-Hartman
` (200 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fredrik Nyberg, Simon Horman,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fredrik Nyberg <fredrik.nyberg@volvocars.com>
commit 9b6c20f788472d2042717a3c2f1bc60b2b77083e upstream.
Commit 4ce62d5b2f7a ("net: usb: ax88179_178a: stop lying about
skb->truesize") replaced skb_clone() with a copy into a new skb for
every packet of a bulk-in transfer except the last one. The copy skips
the 2-byte IP alignment pseudo header but still copies pkt_len bytes,
and pkt_len includes that header. Each of these frames is therefore
delivered with two extra trailing bytes: the 0xeeee pseudo header of
the next slot when the frame ends on an 8-byte boundary, or slot
padding otherwise. The last packet is still trimmed to pkt_len - 2.
IPv4 and IPv6 trim the extra bytes, so most traffic is unaffected.
Anything that relies on the frame length is not. MACsec takes the ICV
from the last 16 bytes and drops every such frame as InPktsNotValid. In
our setup that was 0.2-1.2% of received MACsec frames, depending on how
many frames shared a transfer, including service discovery multicast.
Allocate and copy pkt_len - 2 bytes, like the last-packet path.
Fixes: 4ce62d5b2f7a ("net: usb: ax88179_178a: stop lying about skb->truesize")
Cc: stable@vger.kernel.org
Signed-off-by: Fredrik Nyberg <fredrik.nyberg@volvocars.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20261002-ax88179-rx-len-v1-1-f01a2a295079@volvocars.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/usb/ax88179_178a.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -1457,11 +1457,11 @@ static int ax88179_rx_fixup(struct usbne
return 1;
}
- ax_skb = netdev_alloc_skb_ip_align(dev->net, pkt_len);
+ ax_skb = netdev_alloc_skb_ip_align(dev->net, pkt_len - 2);
if (!ax_skb)
return 0;
- skb_put(ax_skb, pkt_len);
- memcpy(ax_skb->data, skb->data + 2, pkt_len);
+ skb_put(ax_skb, pkt_len - 2);
+ memcpy(ax_skb->data, skb->data + 2, pkt_len - 2);
ax88179_rx_checksum(ax_skb, pkt_hdr);
usbnet_skb_return(dev, ax_skb);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 088/281] net: xilinx: axienet: Free outstanding DMA buffers on dmaengine stop
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (86 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 087/281] net: usb: ax88179_178a: fix rx frame length for non-last packets Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 089/281] net: team: stop reusing skb after queue override Greg Kroah-Hartman
` (199 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Suraj Gupta, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suraj Gupta <suraj.gupta2@amd.com>
commit bcf2573a68a808a5b54cadafa72b6672e662c2bf upstream.
In the dmaengine path the driver pre-submits RX buffers and holds
in-flight TX buffers whose SKBs are DMA-mapped by the driver and freed
only in the completion callbacks. On ndo_stop() dmaengine_terminate_sync()
aborts these descriptors without running their callbacks, and the driver
then frees only the ring shells, leaking every SKB still owned by the
engine and its DMA mapping on each ifdown. With 128 RX buffers pre-posted
per channel, the mapping leak can eventually exhaust a limited IOMMU
aperture.
Clear the slot's skb in the TX and RX callbacks so a non-NULL skb marks a
slot that still owns a live, DMA-mapped buffer, and on stop unmap and free
every such buffer.
axienet_dma_rx_cb() runs from the DMA tasklet and re-arms the RX ring on
each completion, so it can race axienet_stop(): a completion may submit a
fresh buffer after dmaengine_terminate_sync() has returned, leaving the
channel armed with a buffer the teardown then frees while the engine may
still write into it (dma_release_channel() does not stop it either). Add a
lock that axienet_dma_rx_cb() holds across the @stopping check and the
resubmit, and axienet_stop() holds to set @stopping before terminating.
Once @stopping is set no callback can arm a new buffer, and any armed just
before is aborted by the terminate, so teardown only frees buffers the
engine no longer owns.
Fixes: 6a91b846af85 ("net: axienet: Introduce dmaengine support")
Cc: stable@vger.kernel.org
Signed-off-by: Suraj Gupta <suraj.gupta2@amd.com>
Link: https://patch.msgid.link/20260928184207.2361931-1-suraj.gupta2@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/xilinx/xilinx_axienet.h | 7 ++-
drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 51 ++++++++++++++++++----
2 files changed, 47 insertions(+), 11 deletions(-)
--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
@@ -523,8 +523,9 @@ struct skbuf_dma_descriptor {
* @stats_work: Work for reading the hardware statistics counters often enough
* to catch overflows.
* @dma_err_task: Work structure to process Axi DMA errors
- * @stopping: Set when @dma_err_task shouldn't do anything because we are
- * about to stop the device.
+ * @stopping: Set when we are about to stop the device: makes @dma_err_task
+ * a no-op (legacy DMA path) and fences RX descriptor
+ * resubmission in axienet_dma_rx_cb() (dmaengine path).
* @tx_irq: Axidma TX IRQ number
* @rx_irq: Axidma RX IRQ number
* @eth_irq: Ethernet core IRQ number
@@ -545,6 +546,7 @@ struct skbuf_dma_descriptor {
* @tx_ring_tail: TX skb ring buffer tail index.
* @rx_ring_head: RX skb ring buffer head index.
* @rx_ring_tail: RX skb ring buffer tail index.
+ * @rx_submit_lock: Protects RX ring resubmission vs teardown in dmaengine path.
*/
struct axienet_local {
struct net_device *ndev;
@@ -626,6 +628,7 @@ struct axienet_local {
int tx_ring_tail;
int rx_ring_head;
int rx_ring_tail;
+ spinlock_t rx_submit_lock;
};
/**
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -881,6 +881,7 @@ static void axienet_dma_tx_cb(void *data
u64_stats_update_end(&lp->tx_stat_sync);
dma_unmap_sg(lp->dev, skbuf_dma->sgl, skbuf_dma->sg_len, DMA_TO_DEVICE);
dev_consume_skb_any(skbuf_dma->skb);
+ skbuf_dma->skb = NULL;
netif_txq_completed_wake(txq, 1, len,
CIRC_SPACE(lp->tx_ring_head, lp->tx_ring_tail, TX_BD_NUM_MAX),
2);
@@ -1171,6 +1172,7 @@ static void axienet_dma_rx_cb(void *data
&meta_max_len);
dma_unmap_single(lp->dev, skbuf_dma->dma_address, lp->max_frm_size,
DMA_FROM_DEVICE);
+ skbuf_dma->skb = NULL;
if (IS_ERR(app_metadata)) {
if (net_ratelimit())
@@ -1193,10 +1195,17 @@ static void axienet_dma_rx_cb(void *data
u64_stats_update_end(&lp->rx_stat_sync);
rx_submit:
+ spin_lock(&lp->rx_submit_lock);
+ if (lp->stopping) {
+ spin_unlock(&lp->rx_submit_lock);
+ return;
+ }
+
for (i = 0; i < CIRC_SPACE(lp->rx_ring_head, lp->rx_ring_tail,
RX_BUF_NUM_DEFAULT); i++)
axienet_rx_submit_desc(lp->ndev);
dma_async_issue_pending(lp->rx_chan);
+ spin_unlock(&lp->rx_submit_lock);
}
/**
@@ -1541,6 +1550,7 @@ static int axienet_init_dmaengine(struct
lp->tx_ring_head = 0;
lp->rx_ring_tail = 0;
lp->rx_ring_head = 0;
+ lp->stopping = false;
lp->tx_skb_ring = kzalloc_objs(*lp->tx_skb_ring, TX_BD_NUM_MAX);
if (!lp->tx_skb_ring) {
ret = -ENOMEM;
@@ -1752,20 +1762,42 @@ static int axienet_stop(struct net_devic
free_irq(lp->rx_irq, ndev);
axienet_dma_bd_release(ndev);
} else {
+ struct skbuf_dma_descriptor *skbuf_dma;
+
+ spin_lock_bh(&lp->rx_submit_lock);
+ lp->stopping = true;
+ spin_unlock_bh(&lp->rx_submit_lock);
+
dmaengine_terminate_sync(lp->tx_chan);
- dmaengine_synchronize(lp->tx_chan);
dmaengine_terminate_sync(lp->rx_chan);
- dmaengine_synchronize(lp->rx_chan);
-
- for (i = 0; i < TX_BD_NUM_MAX; i++)
- kfree(lp->tx_skb_ring[i]);
- kfree(lp->tx_skb_ring);
- for (i = 0; i < RX_BUF_NUM_DEFAULT; i++)
- kfree(lp->rx_skb_ring[i]);
- kfree(lp->rx_skb_ring);
dma_release_channel(lp->rx_chan);
dma_release_channel(lp->tx_chan);
+
+ /* Unmap and free any buffer the terminate did not reclaim, so it
+ * is not leaked; a non-NULL skb marks such a slot.
+ */
+ for (i = 0; i < TX_BD_NUM_MAX; i++) {
+ skbuf_dma = lp->tx_skb_ring[i];
+ if (skbuf_dma && skbuf_dma->skb) {
+ dma_unmap_sg(lp->dev, skbuf_dma->sgl,
+ skbuf_dma->sg_len, DMA_TO_DEVICE);
+ dev_kfree_skb_any(skbuf_dma->skb);
+ }
+ kfree(skbuf_dma);
+ }
+ kfree(lp->tx_skb_ring);
+
+ for (i = 0; i < RX_BUF_NUM_DEFAULT; i++) {
+ skbuf_dma = lp->rx_skb_ring[i];
+ if (skbuf_dma && skbuf_dma->skb) {
+ dma_unmap_single(lp->dev, skbuf_dma->dma_address,
+ lp->max_frm_size, DMA_FROM_DEVICE);
+ dev_kfree_skb_any(skbuf_dma->skb);
+ }
+ kfree(skbuf_dma);
+ }
+ kfree(lp->rx_skb_ring);
}
netdev_reset_queue(ndev);
@@ -3062,6 +3094,7 @@ static int axienet_probe(struct platform
spin_lock_init(&lp->rx_cr_lock);
spin_lock_init(&lp->tx_cr_lock);
+ spin_lock_init(&lp->rx_submit_lock);
INIT_WORK(&lp->rx_dim.work, axienet_rx_dim_work);
lp->rx_dim_enabled = true;
lp->rx_dim.profile_ix = 1;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 089/281] net: team: stop reusing skb after queue override
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (87 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 088/281] net: xilinx: axienet: Free outstanding DMA buffers on dmaengine stop Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 090/281] net: team: free skb when broadcast has no txable port Greg Kroah-Hartman
` (198 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+2cf741c3005abc20, Weiming Shi,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
commit b7454f1940c5e6d92e753853c476a769e452f30a upstream.
A nonzero dev_queue_xmit() result does not return ownership of the skb.
When an override port's qdisc drops it, the queue override helper used to
try another port or the mode transmit op with the freed skb.
Return the handoff decision separately from transmit success. Select only
the first override port under RCU and stop after handing it the skb,
regardless of the lower transmit result. Keep the existing success and
drop accounting.
BUG: KASAN: slab-use-after-free in sk_skb_reason_drop
Write of size 4 by task poc/5040
sk_skb_reason_drop (net/core/skbuff.c:1240)
dev_kfree_skb_any_reason (net/core/dev.c:3470)
ab_transmit (drivers/net/team/team_mode_activebackup.c:49)
team_xmit (drivers/net/team/team_core.c:1849)
__dev_direct_xmit (net/core/dev.c:4934)
Freed by task 5040:
__tcf_kfree_skb_list (net/sched/sch_generic.c:43)
__dev_queue_xmit (net/core/dev.c:4831)
team_xmit (drivers/net/team/team_core.c:1846)
Kernel panic - not syncing: KASAN: panic_on_warn set ...
Cc: stable@vger.kernel.org
Fixes: 8ff5105a2b9d ("team: add support for queue override by setting queue_id for port")
Reported-by: <co+2cf741c3005abc20@bugs.sh>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Link: https://patch.msgid.link/20261001182326.572045-2-bestswngs@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/team/team_core.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
--- a/drivers/net/team/team_core.c
+++ b/drivers/net/team/team_core.c
@@ -820,7 +820,8 @@ static struct list_head *__team_get_qom_
/*
* note: already called with rcu_read_lock
*/
-static bool team_queue_override_transmit(struct team *team, struct sk_buff *skb)
+static bool team_queue_override_transmit(struct team *team, struct sk_buff *skb,
+ bool *tx_success)
{
struct list_head *qom_list;
struct team_port *port;
@@ -828,11 +829,11 @@ static bool team_queue_override_transmit
if (!team->queue_override_enabled || !skb->queue_mapping)
return false;
qom_list = __team_get_qom_list(team, skb->queue_mapping);
- list_for_each_entry_rcu(port, qom_list, qom_list) {
- if (!team_dev_queue_xmit(team, port, skb))
- return true;
- }
- return false;
+ port = list_first_or_null_rcu(qom_list, struct team_port, qom_list);
+ if (!port)
+ return false;
+ *tx_success = !team_dev_queue_xmit(team, port, skb);
+ return true;
}
static void __team_queue_override_port_del(struct team *team,
@@ -1864,8 +1865,7 @@ static netdev_tx_t team_xmit(struct sk_b
bool tx_success;
unsigned int len = skb->len;
- tx_success = team_queue_override_transmit(team, skb);
- if (!tx_success)
+ if (!team_queue_override_transmit(team, skb, &tx_success))
tx_success = READ_ONCE(team->ops.transmit)(team, skb);
if (tx_success) {
struct team_pcpu_stats *pcpu_stats;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 090/281] net: team: free skb when broadcast has no txable port
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (88 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 089/281] net: team: stop reusing skb after queue override Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 091/281] nvme: fix swapped ZRASF zone state values for full and read only Greg Kroah-Hartman
` (197 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Weiming Shi, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
commit 489114c9ecae44e523361a4b3e610ee5ebd9189c upstream.
bc_transmit() sends the original skb through the last txable port.
When no port is txable, it returns false without consuming the skb, but
team_xmit() still returns NETDEV_TX_OK. AF_PACKET sends then retain the
skb and its socket write-memory charge.
A TX-enabled, link-down port keeps the broadcast transmit op installed.
Carrier can stay up through a second link-up, TX-disabled port or be
forced on by userspace. Free the original skb on the no-port path while
leaving the existing drop accounting intact.
Discovered by Sashiko during review of previous commit.
Cc: stable@vger.kernel.org
Fixes: 5fc889911a99 ("team: add broadcast mode")
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Link: https://patch.msgid.link/20261001182326.572045-3-bestswngs@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/team/team_mode_broadcast.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/net/team/team_mode_broadcast.c
+++ b/drivers/net/team/team_mode_broadcast.c
@@ -37,6 +37,8 @@ static bool bc_transmit(struct team *tea
ret = !team_dev_queue_xmit(team, last, skb);
if (!sum_ret)
sum_ret = ret;
+ } else {
+ dev_kfree_skb_any(skb);
}
return sum_ret;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 091/281] nvme: fix swapped ZRASF zone state values for full and read only
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (89 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 090/281] net: team: free skb when broadcast has no txable port Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 092/281] openvswitch: fix soft lockup in the netlink flow dump Greg Kroah-Hartman
` (196 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Damien Le Moal, Karl Bonde Torp,
Andreas Hindborg, Keith Busch
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Bonde Torp <k.torp@samsung.com>
commit 564e46d9f6e87912effa03f123d37a511d520f09 upstream.
The Zone Management Receive command Zone Receive Action Specific (ZRASF)
reporting option values for the Full and Read Only zone states are swapped
compared to the NVM Express Zoned Namespace Command Set Specification,
Revision 1.5, Figure 35:
- 5h lists the zones in the ZSF:Full state.
- 6h lists the zones in the ZSRO:Read Only state.
The nvmet ZNS backend uses these constants to map the ZRASF value received
from the host to a block layer zone condition when filtering zones in
Report Zones. Because of the swap, a host asking for full zones was given
the read only zones, and a host asking for read only zones was given the
full zones.
Swap the values of NVME_ZRASF_ZONE_STATE_FULL and
NVME_ZRASF_ZONE_STATE_READONLY to match the specification.
Fixes: aaf2e048af27 ("nvmet: add ZBD over ZNS backend support")
Cc: stable@vger.kernel.org
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Karl Bonde Torp <k.torp@samsung.com>
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/nvme.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -1266,8 +1266,8 @@ enum {
NVME_ZRASF_ZONE_STATE_IMP_OPEN = 0x02,
NVME_ZRASF_ZONE_STATE_EXP_OPEN = 0x03,
NVME_ZRASF_ZONE_STATE_CLOSED = 0x04,
- NVME_ZRASF_ZONE_STATE_READONLY = 0x05,
- NVME_ZRASF_ZONE_STATE_FULL = 0x06,
+ NVME_ZRASF_ZONE_STATE_FULL = 0x05,
+ NVME_ZRASF_ZONE_STATE_READONLY = 0x06,
NVME_ZRASF_ZONE_STATE_OFFLINE = 0x07,
NVME_REPORT_ZONE_PARTIAL = 1,
};
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 092/281] openvswitch: fix soft lockup in the netlink flow dump
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (90 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 091/281] nvme: fix swapped ZRASF zone state values for full and read only Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 093/281] optee: register TEE devices only once fully initialized Greg Kroah-Hartman
` (195 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Denis V. Lunev, Ilya Maximets,
David S. Miller
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Denis V. Lunev <den@openvz.org>
commit aaaaf87ea99b8766c9a8aa0e71aa42e6bc8a5320 upstream.
A production compute node carrying a few thousand datapath flows hit a
soft lockup inside a single netlink flow dump and panicked.
ovs_flow_cmd_dump() calls ovs_flow_stats_get() for every flow it
emits, and that releases stats->lock with spin_unlock_bh() once per
CPU that has touched the flow. Every release is a local_bh_enable(),
and each one runs the pending softirq backlog in the dumping thread's
own context.
The skb bounds the flows one callback emits, but not the softirq work
it absorbs. On a CPU that carries the box's packet load the backlog
refills as fast as it drains, so the dumping thread becomes that CPU's
softirq engine. It never sleeps and it has no reschedule point, so
under voluntary preemption nothing can take the CPU away from it:
neither the ksoftirqd the kernel woke to take the work over, nor the
stopper thread the softlockup detector dispatches to refresh its
timestamp.
Hold BH off across the whole callback instead, the way
ctnetlink_dump_table() does, so the nested spin_unlock_bh() stop
draining softirqs. The loop already runs under rcu_read_lock() and
cannot sleep. What it gives up is preemption under CONFIG_PREEMPT,
since a BH-off region is not preemptible outside PREEMPT_RT. The
region stays short: the skb caps the flows one callback emits, and
empty buckets cost no skb space but are each visited once per dump, as
the cursor only moves forward. The table grows on insert and shrinks
only on flush, so the walk is bounded by the largest flow count the
datapath has held. The softirq backlog the callback used to absorb has
no bound at all.
Fixes: 63e7959c4b9b ("openvswitch: Per NUMA node flow stats.")
Cc: stable@vger.kernel.org
Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/openvswitch/datapath.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1529,6 +1529,12 @@ static int ovs_flow_cmd_dump(struct sk_b
return -ENODEV;
}
+ /*
+ * Not needed for safety. Stops every spin_unlock_bh() in
+ * ovs_flow_stats_get() from running the softirq backlog.
+ */
+ local_bh_disable();
+
ti = rcu_dereference(dp->table.ti);
for (;;) {
struct sw_flow *flow;
@@ -1549,6 +1555,8 @@ static int ovs_flow_cmd_dump(struct sk_b
cb->args[0] = bucket;
cb->args[1] = obj;
}
+
+ local_bh_enable();
rcu_read_unlock();
return skb->len;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 093/281] optee: register TEE devices only once fully initialized
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (91 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 092/281] openvswitch: fix soft lockup in the netlink flow dump Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 094/281] power: sequencing: pcie-m2: Fix leaking array from of_regulator_bulk_get_all() Greg Kroah-Hartman
` (194 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shao-Fu Chen, Jens Wiklander
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shao-Fu Chen <shf.chen@mediatek.com>
commit c108feca0a096f8db25d1b69130035025e9e936d upstream.
optee_probe() called tee_device_register() on both the client and the
supplicant device before the rest of struct optee had been initialized.
tee_device_register() calls cdev_device_add(), which does two things at
once: it creates /dev/tee0 and /dev/teepriv0, and it links the device
into the tee class so that class_find_device() can find it. From that
moment on the device is reachable both from user space via tee_open()
and from kernel space via tee_client_open_context(). The only gate in
teedev_open() is tee_device_get(), which merely checks that
teedev->desc is non-NULL, which was already set by tee_device_alloc().
Therefore, there is effectively no gate at all.
A context opened in that window can run against a struct optee where
- optee->call_queue.mutex is not initialized by optee_cq_init()
- optee->supp mutex and completions is not initialized by
optee_supp_init()
- optee->rpmb_dev_mutex is not initialized yet,
- the message argument cache is not initialized by
optee_shm_arg_cache_init()
- optee->ctx is still NULL
Any open session or invoke during this window takes uninitialized
mutexes and dereferences a NULL pointer.
Fix it by moving both tee_device_register() calls down to the point
where all of struct optee is set up.
Fixes: 4fb0a5eb364d ("tee: add OP-TEE driver")
Cc: stable@vger.kernel.org
Signed-off-by: Shao-Fu Chen <shf.chen@mediatek.com>
[JW: adding fixes and cc]
Signed-off-by: Jens Wiklander <jens.wiklander@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tee/optee/ffa_abi.c | 16 ++++++++--------
drivers/tee/optee/smc_abi.c | 17 ++++++++---------
2 files changed, 16 insertions(+), 17 deletions(-)
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -1123,14 +1123,6 @@ static int optee_ffa_probe(struct ffa_de
optee_set_dev_group(optee);
- rc = tee_device_register(optee->teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
- rc = tee_device_register(optee->supp_teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
rc = rhashtable_init(&optee->ffa.global_ids, &shm_rhash_params);
if (rc)
goto err_unreg_supp_teedev;
@@ -1159,6 +1151,14 @@ static int optee_ffa_probe(struct ffa_de
if (optee_ffa_protmem_pool_init(optee, sec_caps))
pr_info("Protected memory service not available\n");
+ rc = tee_device_register(optee->teedev);
+ if (rc)
+ goto err_unregister_devices;
+
+ rc = tee_device_register(optee->supp_teedev);
+ if (rc)
+ goto err_unregister_devices;
+
rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
if (rc)
goto err_unregister_devices;
--- a/drivers/tee/optee/smc_abi.c
+++ b/drivers/tee/optee/smc_abi.c
@@ -1849,14 +1849,6 @@ static int optee_probe(struct platform_d
optee_set_dev_group(optee);
- rc = tee_device_register(optee->teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
- rc = tee_device_register(optee->supp_teedev);
- if (rc)
- goto err_unreg_supp_teedev;
-
optee_cq_init(&optee->call_queue, thread_count);
optee_supp_init(&optee->supp);
optee->smc.memremaped_shm = memremaped_shm;
@@ -1916,6 +1908,14 @@ static int optee_probe(struct platform_d
if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
pr_info("dynamic shared memory is enabled\n");
+ rc = tee_device_register(optee->teedev);
+ if (rc)
+ goto err_disable_shm_cache;
+
+ rc = tee_device_register(optee->supp_teedev);
+ if (rc)
+ goto err_disable_shm_cache;
+
rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
if (rc)
goto err_disable_shm_cache;
@@ -1942,7 +1942,6 @@ err_supp_uninit:
optee_shm_arg_cache_uninit(optee);
optee_supp_uninit(&optee->supp);
mutex_destroy(&optee->call_queue.mutex);
-err_unreg_supp_teedev:
tee_device_unregister(optee->supp_teedev);
err_unreg_teedev:
tee_device_unregister(optee->teedev);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 094/281] power: sequencing: pcie-m2: Fix leaking array from of_regulator_bulk_get_all()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (92 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 093/281] optee: register TEE devices only once fully initialized Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 095/281] regulator: ltc3676: dont read the write-only HRST and CLIRQ registers Greg Kroah-Hartman
` (193 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alexey Charkov, Bartosz Golaszewski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Charkov <alchark@flipper.net>
commit 0d6c5794fd633427f0d4ad8b51d94061295649da upstream.
of_regulator_bulk_get_all() allocates the consumers array and hands it to
the caller, who is expected to free it at an appropriate time.
pwrseq-pcie-m2.c never did, leading to a memory leak.
Add an explicit kfree() for the consumers array.
Cc: stable@vger.kernel.org
Fixes: 52e7b5bd62ba ("power: sequencing: Add the Power Sequencing driver for the PCIe M.2 connectors")
Signed-off-by: Alexey Charkov <alchark@flipper.net>
Link: https://patch.msgid.link/20260930-m2-pwrseq-kfree-v1-1-82678b02c126@flipper.net
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/power/sequencing/pwrseq-pcie-m2.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/power/sequencing/pwrseq-pcie-m2.c
+++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -562,6 +562,7 @@ err_destroy_mutex:
mutex_destroy(&ctx->list_lock);
err_free_regulators:
regulator_bulk_free(ctx->num_vregs, ctx->regs);
+ kfree(ctx->regs);
return ret;
}
@@ -575,6 +576,7 @@ static void pwrseq_pcie_m2_remove(struct
mutex_destroy(&ctx->list_lock);
regulator_bulk_free(ctx->num_vregs, ctx->regs);
+ kfree(ctx->regs);
}
static const struct of_device_id pwrseq_pcie_m2_of_match[] = {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 095/281] regulator: ltc3676: dont read the write-only HRST and CLIRQ registers
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (93 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 094/281] power: sequencing: pcie-m2: Fix leaking array from of_regulator_bulk_get_all() Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 096/281] regulator: of: fill in supply names in of_regulator_bulk_get_all() Greg Kroah-Hartman
` (192 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Abhishek Ojha, Mark Brown
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abhishek Ojha <Abhishek.ojha@savoirfairelinux.com>
commit 28c2388ee24cdbefbcc458fa41ef7bffaaa1cc83 upstream.
HRST (0x1e) and CLIRQ (0x1f) are write-only command strobes. Writing HRST
triggers a hard reset of the chip and writing CLIRQ clears the interrupt;
reading them returns nothing useful, and the read itself fires the command.
The result is that a plain register dump resets the board:
cat /sys/kernel/debug/regmap/2-003c/registers
walks every readable register, hits HRST, and the board reboots.
Split the callback back in two so HRST and CLIRQ stay writable but are no
longer readable. The readable range is left unchanged
(LTC3676_BUCK1 ... LTC3676_IRQSTAT).
Fixes: 37b918a034fe ("regulator: Add LTC3676 support")
Cc: stable@vger.kernel.org
Signed-off-by: Abhishek Ojha <Abhishek.ojha@savoirfairelinux.com>
Link: https://patch.msgid.link/20260902010701.3360310-1-Abhishek.ojha@savoirfairelinux.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/regulator/ltc3676.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
--- a/drivers/regulator/ltc3676.c
+++ b/drivers/regulator/ltc3676.c
@@ -232,7 +232,7 @@ static const struct regulator_desc ltc36
LTC3676_FIXED_REG(LDO4, ldo4, LDOB, 2),
};
-static bool ltc3676_readable_writeable_reg(struct device *dev, unsigned int reg)
+static bool ltc3676_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case LTC3676_BUCK1 ... LTC3676_IRQSTAT:
@@ -243,6 +243,15 @@ static bool ltc3676_readable_writeable_r
return false;
}
+static bool ltc3676_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case LTC3676_BUCK1 ... LTC3676_IRQSTAT:
+ return true;
+ }
+ return false;
+}
+
static bool ltc3676_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
@@ -255,8 +264,8 @@ static bool ltc3676_volatile_reg(struct
static const struct regmap_config ltc3676_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
- .writeable_reg = ltc3676_readable_writeable_reg,
- .readable_reg = ltc3676_readable_writeable_reg,
+ .writeable_reg = ltc3676_writeable_reg,
+ .readable_reg = ltc3676_readable_reg,
.volatile_reg = ltc3676_volatile_reg,
.max_register = LTC3676_CLIRQ,
.use_single_read = true,
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 096/281] regulator: of: fill in supply names in of_regulator_bulk_get_all()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (94 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 095/281] regulator: ltc3676: dont read the write-only HRST and CLIRQ registers Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 097/281] regulator: tps6594-regulator: Fix n_linear_ranges for TPS65224 BUCK2-4 Greg Kroah-Hartman
` (191 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Alexey Charkov, Mark Brown
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Charkov <alchark@flipper.net>
commit e2151c29cec73f6cc70abf1c7cbc7b9b202489f5 upstream.
of_regulator_bulk_get_all() returns an array it allocated itself, and
fills in only the consumer of each entry. Every other way of getting a
bulk array has the supply name set, because the caller provides it, and
the core expects it to be there: regulator_bulk_enable() prints it when
a supply fails to enable, so a caller that hands such an array to it
dereferences uninitialised memory on that path.
Copy each name into the array's own allocation, right behind the
entries, so that it shares the array's lifetime and callers still have
nothing extra to free. That also retires the fixed 64 byte stack buffer
the names were assembled in, which is_supply_name() never bounded the
copy against.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260928-b4-rk3576-reboot-mode-v1-0-65486b03bd41@flipper.net?part=3
Fixes: 27b9ecc7a9ba ("regulator: Add of_regulator_bulk_get_all")
Signed-off-by: Alexey Charkov <alchark@flipper.net>
Link: https://patch.msgid.link/20260930-regulator-get-all-v2-1-ca82070d22f2@flipper.net
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/regulator/of_regulator.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -935,15 +935,15 @@ static int is_supply_name(const char *na
int of_regulator_bulk_get_all(struct device *dev, struct device_node *np,
struct regulator_bulk_data **consumers)
{
- int num_consumers = 0;
+ int num_consumers = 0, names_len = 0;
struct regulator *tmp;
struct regulator_bulk_data *_consumers = NULL;
struct property *prop;
+ char *names;
int i, n = 0, ret;
- char name[64];
/*
- * first pass: get numbers of xxx-supply
+ * first pass: get numbers of xxx-supply and the room their names take
* second pass: fill consumers
*/
restart:
@@ -953,16 +953,19 @@ restart:
continue;
if (!_consumers) {
num_consumers++;
+ names_len += i + 1;
continue;
} else {
- memcpy(name, prop->name, i);
- name[i] = '\0';
- tmp = regulator_get(dev, name);
+ memcpy(names, prop->name, i);
+ names[i] = '\0';
+ tmp = regulator_get(dev, names);
if (IS_ERR(tmp)) {
ret = PTR_ERR(tmp);
goto error;
}
+ _consumers[n].supply = names;
_consumers[n].consumer = tmp;
+ names += i + 1;
n++;
continue;
}
@@ -973,9 +976,16 @@ restart:
}
if (num_consumers == 0)
return 0;
- _consumers = kmalloc_objs(struct regulator_bulk_data, num_consumers);
+ /*
+ * The supply names are kept in the same allocation as the array, so
+ * that they share its lifetime and the caller has nothing extra to
+ * free.
+ */
+ _consumers = kzalloc(size_add(size_mul(num_consumers, sizeof(*_consumers)),
+ names_len), GFP_KERNEL);
if (!_consumers)
return -ENOMEM;
+ names = (char *)(_consumers + num_consumers);
goto restart;
error:
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 097/281] regulator: tps6594-regulator: Fix n_linear_ranges for TPS65224 BUCK2-4
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (95 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 096/281] regulator: of: fill in supply names in of_regulator_bulk_get_all() Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 098/281] pmdomain: imx8m-blk-ctrl: Serialize power on/off across sibling domains Greg Kroah-Hartman
` (190 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ridham Khurana, Mark Brown
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ridham Khurana <khurana.ridham222@gmail.com>
commit 2f15518682c779b1014552cb2ccb4a2052f85f27 upstream.
The TPS65224 BUCK2, BUCK3 and BUCK4 descriptors pass 4 as
n_linear_ranges, but tps65224_bucks_2_3_4_ranges[] only has two
entries, covering selectors 0x00-0x45.
The linear range helpers loop over n_linear_ranges entries, so any
lookup of a selector above 0x45 reads past the end of the array and
treats whatever follows it as two more ranges. This happens on the
normal registration path when the core checks the voltage constraints
against every selector. TPS652G1 uses the same descriptors and is
affected too.
Use ARRAY_SIZE() so the count always matches the table.
Fixes: 00c826525fba ("regulator: tps6594-regulator: Add TI TPS65224 PMIC regulators")
Cc: stable@vger.kernel.org
Signed-off-by: Ridham Khurana <khurana.ridham222@gmail.com>
Link: https://patch.msgid.link/20260930105333.3522412-1-khurana.ridham222@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/regulator/tps6594-regulator.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/regulator/tps6594-regulator.c
+++ b/drivers/regulator/tps6594-regulator.c
@@ -241,21 +241,21 @@ static const struct regulator_desc tps65
TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_CTRL(1),
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
- 4, 0, 0, NULL, 0, 0),
+ ARRAY_SIZE(tps65224_bucks_2_3_4_ranges), 0, 0, NULL, 0, 0),
TPS6594_REGULATOR("BUCK3", "buck3", TPS6594_BUCK_3,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_VOUT_1(2),
TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_CTRL(2),
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
- 4, 0, 0, NULL, 0, 0),
+ ARRAY_SIZE(tps65224_bucks_2_3_4_ranges), 0, 0, NULL, 0, 0),
TPS6594_REGULATOR("BUCK4", "buck4", TPS6594_BUCK_4,
REGULATOR_VOLTAGE, tps6594_bucks_ops, TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_VOUT_1(3),
TPS65224_MASK_BUCKS_VSET,
TPS6594_REG_BUCKX_CTRL(3),
TPS6594_BIT_BUCK_EN, 0, 0, tps65224_bucks_2_3_4_ranges,
- 4, 0, 0, NULL, 0, 0),
+ ARRAY_SIZE(tps65224_bucks_2_3_4_ranges), 0, 0, NULL, 0, 0),
};
static const struct tps6594_regulator_irq_type tps6594_buck1_irq_types[] = {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 098/281] pmdomain: imx8m-blk-ctrl: Serialize power on/off across sibling domains
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (96 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 097/281] regulator: tps6594-regulator: Fix n_linear_ranges for TPS65224 BUCK2-4 Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 099/281] pmdomain: rockchip: dont ignore clock lookup errors on attach Greg Kroah-Hartman
` (189 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ming Qian, Frank Li, Ulf Hansson
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Qian <ming.qian@oss.nxp.com>
commit 51c2db3ef0cb89a49ab7f47a40efd5d5b074ce8d upstream.
On i.MX8MP the VPU blk-ctrl exposes G1, G2 and VC8000E as three separate
genpds, each serialized only by its own genpd lock, so their power_on and
power_off callbacks can run concurrently on SMP.
The sequences are not independent: they share the VPUMIX bus domain, the
VPU_NOC and the ADB400 handshake. On power up the GPC cannot ack-verify
the ADB400 handshake - the ack only completes once blk-ctrl sets the bus
clk-en bit - so it just waits a fixed delay instead of polling hskack. A
sibling transition landing inside another domain's reset window disturbs
that shared clock and handshake timing, the victim's reset does not take
effect, and its block registers read back all zeros: the decoder times
out or the encoder fails its format check.
Serialize the blk-ctrl reset sequence with a per-blk-ctrl mutex; the
driver deliberately avoids a genpd hierarchy, so the genpd core gives no
cross-sibling serialization.
Fixes: a1a5f15f7f6c ("soc: imx: imx8m-blk-ctrl: add i.MX8MP VPU blk ctrl")
Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/pmdomain/imx/imx8m-blk-ctrl.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c
+++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
@@ -15,6 +15,7 @@
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/clk.h>
+#include <linux/mutex.h>
#include <dt-bindings/power/imx8mm-power.h>
#include <dt-bindings/power/imx8mn-power.h>
@@ -34,6 +35,12 @@ struct imx8m_blk_ctrl {
struct regmap *regmap;
struct imx8m_blk_ctrl_domain *domains;
struct genpd_onecell_data onecell_data;
+ /*
+ * Serializes the blk-ctrl reset/clock sequence across sibling domains;
+ * their transitions interact through the shared VPUMIX bus domain,
+ * VPU_NOC and the not-ack-verified ADB400 handshake (ERR050531).
+ */
+ struct mutex power_lock;
};
struct imx8m_blk_ctrl_domain_data {
@@ -98,6 +105,8 @@ static int imx8m_blk_ctrl_power_on(struc
struct imx8m_blk_ctrl *bc = domain->bc;
int ret;
+ guard(mutex)(&bc->power_lock);
+
/* make sure bus domain is awake */
ret = pm_runtime_get_sync(bc->bus_power_dev);
if (ret < 0) {
@@ -164,6 +173,8 @@ static int imx8m_blk_ctrl_power_off(stru
const struct imx8m_blk_ctrl_domain_data *data = domain->data;
struct imx8m_blk_ctrl *bc = domain->bc;
+ guard(mutex)(&bc->power_lock);
+
/* put devices into reset and disable clocks */
if (data->mipi_phy_rst_mask)
regmap_clear_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask);
@@ -202,6 +213,10 @@ static int imx8m_blk_ctrl_probe(struct p
bc->dev = dev;
+ ret = devm_mutex_init(dev, &bc->power_lock);
+ if (ret)
+ return ret;
+
bc_data = of_device_get_match_data(dev);
base = devm_platform_ioremap_resource(pdev, 0);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 099/281] pmdomain: rockchip: dont ignore clock lookup errors on attach
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (97 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 098/281] pmdomain: imx8m-blk-ctrl: Serialize power on/off across sibling domains Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 100/281] pmdomain: rockchip: fix clock leak on domain probe failure Greg Kroah-Hartman
` (188 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shawn Lin, Sebastian Reichel,
Ulf Hansson
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <shawn.lin@rock-chips.com>
commit 4c66c423593e26273ea0d644906ed007630c6f6d upstream.
rockchip_pd_attach_dev() treated every of_clk_get() error as the end
of the clock list, so a clock that exists but is not available yet
(e.g. -EPROBE_DEFER) was silently skipped and the device ended up
without pm_clk management. Only -ENOENT means there are no more
clocks.
Fixes: 7c696693a4f5 ("soc: rockchip: power-domain: Add power domain driver")
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/pmdomain/rockchip/pm-domains.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -745,7 +745,19 @@ static int rockchip_pd_attach_dev(struct
}
i = 0;
- while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) {
+ while (1) {
+ clk = of_clk_get(dev->of_node, i++);
+ if (IS_ERR(clk)) {
+ error = PTR_ERR(clk);
+ if (error == -ENOENT)
+ break;
+
+ dev_err(dev, "failed to get clock %d: %d\n", i - 1,
+ error);
+ pm_clk_destroy(dev);
+ return error;
+ }
+
dev_dbg(dev, "adding clock '%pC' to list of PM clocks\n", clk);
error = pm_clk_add_clk(dev, clk);
if (error) {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 100/281] pmdomain: rockchip: fix clock leak on domain probe failure
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (98 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 099/281] pmdomain: rockchip: dont ignore clock lookup errors on attach Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 101/281] pmdomain: rockchip: propagate subdomain add errors Greg Kroah-Hartman
` (187 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shawn Lin, Sebastian Reichel,
Ulf Hansson
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <shawn.lin@rock-chips.com>
commit d8b3847770661b7109146e6479eeadcdab9cecf0 upstream.
When of_clk_get() failed in the middle of the loop, the references of
the clocks acquired so far were leaked instead of being released by
the error path.
Fixes: d909072d0521 ("soc: rockchip: power-domain: use clk_bulk APIs")
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/pmdomain/rockchip/pm-domains.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -840,7 +840,7 @@ static int rockchip_pm_add_one_domain(st
dev_err(pmu->dev,
"%pOFn: failed to get clk at index %d: %d\n",
node, i, error);
- return error;
+ goto err_put_clocks;
}
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 101/281] pmdomain: rockchip: propagate subdomain add errors
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (99 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 100/281] pmdomain: rockchip: fix clock leak on domain probe failure Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 102/281] scsi: ch: Do not keep references to data transfer element devices Greg Kroah-Hartman
` (186 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shawn Lin, Sebastian Reichel,
Ulf Hansson
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <shawn.lin@rock-chips.com>
commit 4c0d69d677cf5b0065ebbb3ceb8ba66fddbec630 upstream.
rockchip_pm_add_subdomain() ignored the return value of its recursive
call, so a failure deeper in the hierarchy was silently dropped and
probe still succeeded with an incomplete domain tree.
Fixes: 6be05b5ec161 ("soc: rockchip: power-domain: add support for sub-power domains")
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/pmdomain/rockchip/pm-domains.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -1016,7 +1016,9 @@ static int rockchip_pm_add_subdomain(str
parent_domain->name, child_domain->name);
}
- rockchip_pm_add_subdomain(pmu, np);
+ error = rockchip_pm_add_subdomain(pmu, np);
+ if (error)
+ return error;
}
return 0;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 102/281] scsi: ch: Do not keep references to data transfer element devices
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (100 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 101/281] pmdomain: rockchip: propagate subdomain add errors Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:36 ` [PATCH 7.2 103/281] scsi: qedi: Initialize callback state before registration Greg Kroah-Hartman
` (185 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ahmed Abdelhaleem Ahmed,
Laurence Oberman, Martin K. Petersen (Oracle)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ahmed Abdelhaleem Ahmed <ahmedhal@gmail.com>
commit 27c0f718d3b3c99e6d315308e95d987d0382a8a8 upstream.
ch_readconfig() looks up the scsi_device of every data transfer element
whose SCSI id the changer reports in READ ELEMENT STATUS, and stores it in
ch->dt[]. scsi_device_lookup() takes a reference, and nothing ever drops
it: ch_destroy() frees the array with kfree(). ch->dt[] is read nowhere
else - it only supplies the vendor, model and revision printed in the same
loop.
Once such a drive is removed, its scsi_device can never be released. It
stays on the host's device list at its address, so a new device there is
refused by anything that walks the list - target_core_pscsi reports
"scsi_device_get() failed for H:C:T:L" - and the low-level driver's module
can no longer be unloaded. Only a reboot recovers.
It shows with any changer that reports its drives' ids; with the mhvtl
virtual library (IBM 3573-TL personality), each create and remove of a
library with four drives leaves four references behind, counted by the
module's use count in lsmod. With ch not bound the count is unchanged, and
with this patch applied it is unchanged too.
Drop the reference as soon as the name has been printed, and remove the now
unused dt[] array. That also removes the array leaked when ch_probe() fails
after ch_readconfig().
The same leak was reported with an RFC patch in 2022, which was not merged.
Fixes: daa6eda65a53 ("[SCSI] add scsi changer driver")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/linux-scsi/20220719075442.6215-1-yanghao_ht@163.com/
Signed-off-by: Ahmed Abdelhaleem Ahmed <ahmedhal@gmail.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Fixes: daa6eda65a53 ("[SCSI] add scsi changer driver")
Link: https://patch.msgid.link/20260929-ch-dt-leak-v2-1-ddda8d635dca@gmail.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/ch.c | 29 +++++++++--------------------
1 file changed, 9 insertions(+), 20 deletions(-)
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -112,7 +112,6 @@ typedef struct {
int minor;
char name[8];
struct scsi_device *device;
- struct scsi_device **dt; /* ptrs to data transfer elements */
u_int firsts[CH_TYPES];
u_int counts[CH_TYPES];
u_int voltags;
@@ -363,15 +362,10 @@ ch_readconfig(scsi_changer *ch)
vendor_labels[i]);
}
- /* look up the devices of the data transfer elements */
- ch->dt = kzalloc_objs(*ch->dt, ch->counts[CHET_DT]);
-
- if (!ch->dt) {
- kfree(buffer);
- return -ENOMEM;
- }
-
+ /* report the devices of the data transfer elements */
for (elem = 0; elem < ch->counts[CHET_DT]; elem++) {
+ struct scsi_device *sdev;
+
id = -1;
lun = 0;
if (elem < CH_DT_MAX && -1 != dt_id[elem]) {
@@ -387,10 +381,8 @@ ch_readconfig(scsi_changer *ch)
VPRINTK(KERN_INFO, "dt 0x%x: ",elem+ch->firsts[CHET_DT]);
if (data[6] & 0x80) {
VPRINTK(KERN_CONT, "not this SCSI bus\n");
- ch->dt[elem] = NULL;
} else if (0 == (data[6] & 0x30)) {
VPRINTK(KERN_CONT, "ID/LUN unknown\n");
- ch->dt[elem] = NULL;
} else {
id = ch->device->id;
lun = 0;
@@ -400,18 +392,16 @@ ch_readconfig(scsi_changer *ch)
}
if (-1 != id) {
VPRINTK(KERN_CONT, "ID %i, LUN %i, ",id,lun);
- ch->dt[elem] =
- scsi_device_lookup(ch->device->host,
- ch->device->channel,
- id,lun);
- if (!ch->dt[elem]) {
+ sdev = scsi_device_lookup(ch->device->host,
+ ch->device->channel,
+ id, lun);
+ if (!sdev) {
/* should not happen */
VPRINTK(KERN_CONT, "Huh? device not found!\n");
} else {
VPRINTK(KERN_CONT, "name: %8.8s %16.16s %4.4s\n",
- ch->dt[elem]->vendor,
- ch->dt[elem]->model,
- ch->dt[elem]->rev);
+ sdev->vendor, sdev->model, sdev->rev);
+ scsi_device_put(sdev);
}
}
}
@@ -575,7 +565,6 @@ static void ch_destroy(struct kref *ref)
scsi_changer *ch = container_of(ref, scsi_changer, ref);
ch->device = NULL;
- kfree(ch->dt);
kfree(ch);
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 103/281] scsi: qedi: Initialize callback state before registration
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (101 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 102/281] scsi: ch: Do not keep references to data transfer element devices Greg Kroah-Hartman
@ 2026-10-13 11:36 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 104/281] scsi: ufs: core: Avoid unsafe MMIO reads in ufshcd_mcq_compl_all_cqes_lock() Greg Kroah-Hartman
` (184 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:36 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao,
Martin K. Petersen (Oracle)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
commit 85de8b3a5eaa23d153aff4c7c83dddbc949064c9 upstream.
qedi_get_protocol_tlv_data() can be called asynchronously by QED after
qedi_ops->register_ops(). It takes stats_lock and reads ll2_mtu, but
__qedi_probe() currently registers the callback before initializing the
mutex and assigning the default MTU on the normal probe path.
Initialize the callback-visible state before registering qedi_cb_ops. Keep
the recovery path from reinitializing state because it reuses the existing
qedi context.
Fixes: 3cc5746e5ad7 ("scsi: qedi: Initialize the stats mutex lock")
Cc: stable@vger.kernel.org
Assisted-by: LLM Codex
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260910092405.1300129-1-runyu.xiao@seu.edu.cn
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qedi/qedi_main.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -2652,8 +2652,6 @@ retry_probe:
snprintf(host_buf, sizeof(host_buf), "host_%d", qedi->shost->host_no);
qedi_ops->common->set_name(qedi->cdev, host_buf);
- qedi_ops->register_ops(qedi->cdev, &qedi_cb_ops, qedi);
-
memset(¶ms, 0, sizeof(params));
params.mtu = DEF_PATH_MTU + IPV6_HDR_LEN + TCP_HDR_LEN;
qedi->ll2_mtu = DEF_PATH_MTU;
@@ -2670,6 +2668,7 @@ retry_probe:
spin_lock_init(&qedi->task_idx_lock);
mutex_init(&qedi->stats_lock);
}
+ qedi_ops->register_ops(qedi->cdev, &qedi_cb_ops, qedi);
qedi_ops->ll2->register_cb_ops(qedi->cdev, &qedi_ll2_cb_ops, qedi);
qedi_ops->ll2->start(qedi->cdev, ¶ms);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 104/281] scsi: ufs: core: Avoid unsafe MMIO reads in ufshcd_mcq_compl_all_cqes_lock()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (102 preceding siblings ...)
2026-10-13 11:36 ` [PATCH 7.2 103/281] scsi: qedi: Initialize callback state before registration Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 105/281] scsi: ufs: core: Decouple CQ sweep from request iterator in MCQ Greg Kroah-Hartman
` (183 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Peter Wang, Stanley Jhu,
Bart Van Assche, Martin K. Petersen (Oracle)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanley Jhu <stanleyjhu@google.com>
commit 375f3a5691dd46b5d05b90a8968872ec8b2248c5 upstream.
During MCQ host reset, ufshcd_host_reset_and_restore() stops the host
controller via ufshcd_hba_stop() (HCE = 0) before calling
ufshcd_complete_requests(hba, true) ->
ufshcd_mcq_compl_pending_transfer(hba, true) ->
ufshcd_mcq_force_compl_one() -> ufshcd_mcq_compl_all_cqes_lock(). Because
ufshcd_mcq_force_compl_one() is its sole caller,
ufshcd_mcq_compl_all_cqes_lock() always runs with HCE = 0.
Despite the comment above ufshcd_mcq_compl_all_cqes_lock() stating that
reading CQTPy may not be safe with the controller disabled, the function
still calls ufshcd_mcq_update_cq_tail_slot() at the end of its sweep:
1. Unsafe CQTPy MMIO read:
Calling ufshcd_mcq_update_cq_tail_slot() at the end of the sweep reads
CQTPy over MMIO while HCE = 0, directly contradicting the function's
documented contract (commit 1373df88d535 ("scsi: ufs: core: Add a
comment block above ufshcd_mcq_compl_all_cqes_lock()")) that reading
CQTPy may not be safe with the controller disabled.
2. Spurious error logs on empty slots:
Sweeping all max_entries slots visits empty entries where
command_desc_base_addr is 0, causing ufshcd_mcq_process_cqe() to log
unguarded dev_err(hba->dev, "Abnormal CQ entry!\n") messages.
Fix both issues in ufshcd_mcq_compl_all_cqes_lock():
- Remove the ufshcd_mcq_update_cq_tail_slot() call and the redundant
hwq->cq_head_slot = hwq->cq_tail_slot assignment without replacement.
The two indices are already equal after the sweep: they are equal when
the sweep starts, since ufshcd_mcq_poll_cqe_lock() consumes entries
until cq_head_slot reaches cq_tail_slot, and the sweep advances
cq_head_slot by exactly one full ring. Both indices are also
reinitialized before the queue is reused.
- Extract ufshcd_mcq_compl_cqe() and invoke it only on non-empty slots
during full-ring sweeps, keeping "Abnormal CQ entry!" logging strictly
for unexpected empty entries in ufshcd_mcq_poll_cqe_lock().
Fixes: ab248643d3d6 ("scsi: ufs: core: Add error handling for MCQ mode")
Cc: stable@vger.kernel.org
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20260928035816.1294326-2-stanleyjhu@google.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/ufs/core/ufs-mcq.c | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
--- a/drivers/ufs/core/ufs-mcq.c
+++ b/drivers/ufs/core/ufs-mcq.c
@@ -306,20 +306,24 @@ static int ufshcd_mcq_get_tag(struct ufs
return div_u64(addr, ufshcd_get_ucd_size(hba));
}
+static void ufshcd_mcq_compl_cqe(struct ufs_hba *hba, struct cq_entry *cqe)
+{
+ int tag = ufshcd_mcq_get_tag(hba, cqe);
+
+ ufshcd_compl_one_cqe(hba, tag, cqe);
+ /* After processing the CQE, mark it as an empty (invalid) entry. */
+ cqe->command_desc_base_addr = 0;
+}
+
static void ufshcd_mcq_process_cqe(struct ufs_hba *hba,
struct ufs_hw_queue *hwq)
{
struct cq_entry *cqe = ufshcd_mcq_cur_cqe(hwq);
- if (cqe->command_desc_base_addr) {
- int tag = ufshcd_mcq_get_tag(hba, cqe);
-
- ufshcd_compl_one_cqe(hba, tag, cqe);
- /* After processed the cqe, mark it empty (invalid) entry */
- cqe->command_desc_base_addr = 0;
- } else {
+ if (cqe->command_desc_base_addr)
+ ufshcd_mcq_compl_cqe(hba, cqe);
+ else
dev_err(hba->dev, "Abnormal CQ entry!\n");
- }
}
/*
@@ -327,7 +331,7 @@ static void ufshcd_mcq_process_cqe(struc
* controller disabled (HCE = 0). Reading host controller registers, e.g. the
* CQ tail pointer (CQTPy), may not be safe with the host controller disabled.
* Hence, iterate over all completion queue entries. This won't result in
- * double completions because ufshcd_mcq_process_cqe() clears a CQE after it
+ * double completions because ufshcd_mcq_compl_cqe() clears a CQE after it
* has been processed.
*/
void ufshcd_mcq_compl_all_cqes_lock(struct ufs_hba *hba,
@@ -338,13 +342,13 @@ void ufshcd_mcq_compl_all_cqes_lock(stru
spin_lock_irqsave(&hwq->cq_lock, flags);
while (entries > 0) {
- ufshcd_mcq_process_cqe(hba, hwq);
+ struct cq_entry *cqe = ufshcd_mcq_cur_cqe(hwq);
+
+ if (cqe->command_desc_base_addr)
+ ufshcd_mcq_compl_cqe(hba, cqe);
ufshcd_mcq_inc_cq_head_slot(hwq);
entries--;
}
-
- ufshcd_mcq_update_cq_tail_slot(hwq);
- hwq->cq_head_slot = hwq->cq_tail_slot;
spin_unlock_irqrestore(&hwq->cq_lock, flags);
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 105/281] scsi: ufs: core: Decouple CQ sweep from request iterator in MCQ
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (103 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 104/281] scsi: ufs: core: Avoid unsafe MMIO reads in ufshcd_mcq_compl_all_cqes_lock() Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 106/281] riscv: entry: gate shadow call stack reload on sstatus.SPP, not tp Greg Kroah-Hartman
` (182 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bart Van Assche, Stanley Jhu,
Peter Wang, Martin K. Petersen (Oracle)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanley Jhu <stanleyjhu@google.com>
commit 469fa055664bfd8717b087a80d59c03055789c17 upstream.
In MCQ mode, ufshcd_mcq_compl_pending_transfer() uses
blk_mq_tagset_busy_iter() to iterate over busy requests during error
recovery and host reset. However, both iterator callbacks perform
whole-queue operations redundantly for each visited request:
- force_compl == true: ufshcd_mcq_force_compl_one() calls
ufshcd_mcq_compl_all_cqes_lock() on every busy request, sweeping the
entire completion ring (hwq->max_entries slots) once per active request
under spin_lock_irqsave even though the first sweep already cleared all
completion entries.
- force_compl == false: ufshcd_mcq_compl_one() acquires cq_lock and polls
CQTPy over MMIO via ufshcd_mcq_poll_cqe_lock() for every busy request
without doing any per-request work.
Sweep or poll each hardware queue (hba->uhq[i]) once at the start of
ufshcd_mcq_compl_pending_transfer(). When force_compl is true, run
blk_mq_tagset_busy_iter() afterward to complete residual in-flight
requests with DID_REQUEUE, and remove the now-unused
ufshcd_mcq_compl_one() callback.
Fixes: ab248643d3d6 ("scsi: ufs: core: Add error handling for MCQ mode")
Cc: stable@vger.kernel.org
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Link: https://patch.msgid.link/20260928035816.1294326-3-stanleyjhu@google.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/ufs/core/ufshcd.c | 31 ++++++++++++-------------------
1 file changed, 12 insertions(+), 19 deletions(-)
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -5975,8 +5975,6 @@ static bool ufshcd_mcq_force_compl_one(s
if (blk_mq_is_reserved_rq(rq) || !hwq)
return true;
- ufshcd_mcq_compl_all_cqes_lock(hba, hwq);
-
/*
* For those cmds of which the cqes are not present in the cq, complete
* them explicitly.
@@ -5992,19 +5990,6 @@ static bool ufshcd_mcq_force_compl_one(s
return true;
}
-static bool ufshcd_mcq_compl_one(struct request *rq, void *priv)
-{
- struct scsi_device *sdev = rq->q->queuedata;
- struct Scsi_Host *shost = sdev->host;
- struct ufs_hba *hba = shost_priv(shost);
- struct ufs_hw_queue *hwq = ufshcd_mcq_req_to_hwq(hba, rq);
-
- if (!blk_mq_is_reserved_rq(rq) && hwq)
- ufshcd_mcq_poll_cqe_lock(hba, hwq);
-
- return true;
-}
-
/**
* ufshcd_mcq_compl_pending_transfer - MCQ mode function. It is
* invoked from the error handler context or ufshcd_host_reset_and_restore()
@@ -6019,10 +6004,18 @@ static bool ufshcd_mcq_compl_one(struct
static void ufshcd_mcq_compl_pending_transfer(struct ufs_hba *hba,
bool force_compl)
{
- blk_mq_tagset_busy_iter(&hba->host->tag_set,
- force_compl ? ufshcd_mcq_force_compl_one :
- ufshcd_mcq_compl_one,
- NULL);
+ int i;
+
+ for (i = 0; i < hba->nr_hw_queues; i++) {
+ if (force_compl)
+ ufshcd_mcq_compl_all_cqes_lock(hba, &hba->uhq[i]);
+ else
+ ufshcd_mcq_poll_cqe_lock(hba, &hba->uhq[i]);
+ }
+
+ if (force_compl)
+ blk_mq_tagset_busy_iter(&hba->host->tag_set,
+ ufshcd_mcq_force_compl_one, NULL);
}
/**
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 106/281] riscv: entry: gate shadow call stack reload on sstatus.SPP, not tp
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (104 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 105/281] scsi: ufs: core: Decouple CQ sweep from request iterator in MCQ Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 107/281] riscv: errata: select RISCV_ALTERNATIVE_EARLY for THEAD GHOSTWRITE Greg Kroah-Hartman
` (181 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ziyi Guo, Sami Tolvanen,
Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ziyi Guo <guoziyi114@gmail.com>
commit 4d0697f192975dab5985e921989be1d85cf580e9 upstream.
Under CONFIG_SHADOW_CALL_STACK, handle_exception() reloads the kernel
shadow call stack pointer (gp) only when the trap came from userspace.
It made that decision with scs_load_current_if_task_changed, which
compares the trap-time tp (read back from sscratch into s5) against the
current tp:
beq \prev, tp, _skip_scs
scs_load_current
_skip_scs:
tp is a user-writable register. A user task that sets tp to the
linear-map address of its own task_struct (¤t) before trapping
makes the comparison succeed (can achieve by brute force with KASLR
enable under our test), so the kernel skips scs_load_current and
keeps running with the gp that userspace left in place. Under
CONFIG_SHADOW_CALL_STACK gp is the shadow call stack pointer and
load_global_pointer is a no-op, so the compiler-emitted
"sd ra, -8(gp)" / "ld ra, -8(gp)" in every non-leaf function then write
to, and return through, an attacker-controlled address -- an
unprivileged kernel arbitrary-write and control-flow-hijack primitive.
The poisoned gp is saved to task_struct.scs_sp on return, so the reload
is skipped on every subsequent entry as well.
Decide "came from userspace" from the hardware sstatus.SPP bit (already
in s1 at this point) instead of from tp, mirroring the check that
ret_from_exception already uses a few instructions later. SPP is
written by hardware on trap entry and cannot be forged from U-mode.
Legitimate behaviour is unchanged: user entries (SPP=0) reload the task
shadow call stack, nested kernel entries (SPP=1) skip it.
Fixes: d1584d791a29 ("riscv: Implement Shadow Call Stack")
Signed-off-by: Ziyi Guo <guoziyi114@gmail.com>
Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
Link: https://patch.msgid.link/20261001135711.934152-1-guoziyi114@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/include/asm/scs.h | 17 +++++++++++++----
arch/riscv/kernel/entry.S | 2 +-
2 files changed, 14 insertions(+), 5 deletions(-)
--- a/arch/riscv/include/asm/scs.h
+++ b/arch/riscv/include/asm/scs.h
@@ -4,6 +4,7 @@
#ifdef __ASSEMBLER__
#include <asm/asm-offsets.h>
+#include <asm/csr.h>
#ifdef CONFIG_SHADOW_CALL_STACK
@@ -22,9 +23,17 @@
REG_L gp, TASK_TI_SCS_SP(tp)
.endm
-/* Load task_scs_sp(current) to gp, but only if tp has changed. */
-.macro scs_load_current_if_task_changed prev
- beq \prev, tp, _skip_scs
+/*
+ * Load task_scs_sp(current) to gp, but only when the trap came from U-mode.
+ * The source privilege level is taken from the saved sstatus.SPP bit (written
+ * by hardware on trap entry), not by comparing tp. tp is a user-writable
+ * register, so gating the shadow call stack reload on it let a user task that
+ * set tp == ¤t skip the reload and run the kernel with an attacker
+ * controlled gp (the shadow call stack pointer).
+ */
+.macro scs_load_current_if_from_user status, tmp
+ andi \tmp, \status, SR_SPP
+ bnez \tmp, _skip_scs
scs_load_current
_skip_scs:
.endm
@@ -42,7 +51,7 @@ _skip_scs:
.endm
.macro scs_load_current
.endm
-.macro scs_load_current_if_task_changed prev
+.macro scs_load_current_if_from_user status, tmp
.endm
.macro scs_save_current
.endm
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -208,7 +208,7 @@ SYM_CODE_START(handle_exception)
load_global_pointer
/* Load the kernel shadow call stack pointer if coming from userspace */
- scs_load_current_if_task_changed s5
+ scs_load_current_if_from_user s1, s5
#ifdef CONFIG_RISCV_ISA_V_PREEMPTIVE
move a0, sp
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 107/281] riscv: errata: select RISCV_ALTERNATIVE_EARLY for THEAD GHOSTWRITE
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (105 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 106/281] riscv: entry: gate shadow call stack reload on sstatus.SPP, not tp Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 108/281] riscv: fix load_unaligned_zeropad() fixup for RV32 Greg Kroah-Hartman
` (180 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Zongmin Zhou, Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zongmin Zhou <zhouzongmin@kylinos.cn>
commit 298510bbc7c3017c0faf481c6ea66f1065b657b4 upstream.
errata_probe_ghostwrite() only marks the CPU as vulnerable when it is
called at the RISCV_ALTERNATIVES_EARLY_BOOT stage, and the mitigation
in ghostwrite_enable_mitigation() only takes effect if the vulnerable
state was recorded before the boot alternatives are patched.
The early boot stage is only executed when CONFIG_RISCV_ALTERNATIVE_EARLY
is enabled, which currently is only selected by ERRATA_THEAD_MAE. In a
kernel built with ERRATA_THEAD_GHOSTWRITE=y but ERRATA_THEAD_MAE=n, the
early alternatives never run, so ghostwrite_state is never set to
VULNERABLE: ghostwrite_enable_mitigation() returns false, xtheadvector
remains enabled, and sysfs reports "Not affected" on a vulnerable
T-Head C9xx CPU.
Select RISCV_ALTERNATIVE_EARLY from ERRATA_THEAD_GHOSTWRITE so that the
vulnerability is detected in the early boot stage and the default
mitigation is applied.
Fixes: 4bf97069239b ("riscv: Add ghostwrite vulnerability")
Signed-off-by: Zongmin Zhou <zhouzongmin@kylinos.cn>
Link: https://patch.msgid.link/20260917074843.52716-1-min_halo@163.com
Cc: stable@vger.kernel.org
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/Kconfig.errata | 1 +
1 file changed, 1 insertion(+)
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -146,6 +146,7 @@ config ERRATA_THEAD_PMU
config ERRATA_THEAD_GHOSTWRITE
bool "Apply T-Head Ghostwrite errata"
depends on ERRATA_THEAD && RISCV_ISA_XTHEADVECTOR
+ select RISCV_ALTERNATIVE_EARLY
default y
help
The T-Head C9xx cores have a vulnerability in the xtheadvector
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 108/281] riscv: fix load_unaligned_zeropad() fixup for RV32
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (106 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 107/281] riscv: errata: select RISCV_ALTERNATIVE_EARLY for THEAD GHOSTWRITE Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 109/281] riscv: futex: untag the user pointer before the atomic access Greg Kroah-Hartman
` (179 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Jisheng Zhang,
Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
commit d4f25b097e46d82718bb737d4540c99b7ab0a408 upstream.
The fixup for load_unaligned_zeropad() runs when REG_L crosses into an
unmapped page. REG_L is lw on RV32 and ld on RV64, but the fixup assumes
an 8-byte load: it rounds the address down to 8 bytes and derives the
shift from three address bits.
On RV32, a load starting in the last three bytes of a mapped page selects
the word four bytes earlier and shifts it by 40, 48, or 56 bits, more than
the register width. The caller gets earlier bytes instead of the string
tail followed by zeroes. This affects RV32 MMU kernels built with
RISCV_EFFICIENT_UNALIGNED_ACCESS=y, which selects DCACHE_WORD_ACCESS
and lets dcache name hashing and comparison and strscpy() use this
path.
Derive the alignment and offset masks from sizeof(data) instead of a fixed
8. This makes RV32 use the correct source word. RV64 code is unchanged: the
complete extable.o is byte-for-byte identical before and after.
Fixes: d0fdc20b0429 ("riscv: select DCACHE_WORD_ACCESS for efficient unaligned access HW")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Jisheng Zhang <jszhang@kernel.org>
Link: https://patch.msgid.link/20260907190750.26303-1-kmehltretter@gmail.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/mm/extable.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/riscv/mm/extable.c
+++ b/arch/riscv/mm/extable.c
@@ -68,8 +68,8 @@ ex_handler_load_unaligned_zeropad(const
addr = regs_get_gpr(regs, reg_addr * sizeof(unsigned long));
- offset = addr & 0x7UL;
- addr &= ~0x7UL;
+ offset = addr & (sizeof(data) - 1);
+ addr &= ~(sizeof(data) - 1);
data = *(unsigned long *)addr >> (offset * 8);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 109/281] riscv: futex: untag the user pointer before the atomic access
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (107 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 108/281] riscv: fix load_unaligned_zeropad() fixup for RV32 Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 110/281] riscv: hwprobe: use _BITULL() rather than BIT() in MIPS vendor uapi header Greg Kroah-Hartman
` (178 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Samuel Holland, Ziyi Guo,
Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ziyi Guo <guoziyi114@gmail.com>
commit 405290be962b32eec842776fbe3bdf81f15b1676 upstream.
access_ok() checks untagged_addr(uaddr), but arch_futex_atomic_op_inuser()
and futex_atomic_cmpxchg_inatomic() hand the raw uaddr to the inline asm
amoswap/amoadd/.../lr.w+sc.w through the "+m" (*uaddr) operand. When the
tagged address ABI is enabled (CONFIG_RISCV_ISA_SUPM, prctl
PR_SET_TAGGED_ADDR_CTRL with PMLEN != 0), those two addresses differ: a
user pointer whose top PMLEN bits hold a tag passes access_ok() after
untagging, but the atomic is then performed on the still-tagged raw
address.
Supervisor-mode data accesses are not subject to the U-mode pointer
masking (that is governed by menvcfg.PMM, which the kernel does not set),
so hardware does not strip the tag for the kernel's own access. With
Sv57 and PMLEN=16 the tag bits overlap the canonical-address bits, so a
tagged pointer can name a canonical kernel virtual address (e.g. in the
linear map) whose untagged form is a valid user address. An unprivileged
process can thus make FUTEX_WAKE_OP perform an atomic read-modify-write on
an arbitrary kernel address, with the matching FUTEX_OP_CMP_* result
serving as a read oracle.
get_user()/put_user()/raw_copy_{to,from}_user() already untag the pointer
after the access_ok() check; do the same in the futex helpers so the
atomic operates on the address that was actually validated.
Fixes: 2e1743085887 ("riscv: Add support for the tagged address ABI")
Reviewed-by: Samuel Holland <samuel.holland@sifive.com>
Signed-off-by: Ziyi Guo <guoziyi114@gmail.com>
Link: https://patch.msgid.link/20261006140200.877263-1-guoziyi114@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/include/asm/futex.h | 2 ++
1 file changed, 2 insertions(+)
--- a/arch/riscv/include/asm/futex.h
+++ b/arch/riscv/include/asm/futex.h
@@ -40,6 +40,7 @@ arch_futex_atomic_op_inuser(int op, int
if (!access_ok(uaddr, sizeof(u32)))
return -EFAULT;
+ uaddr = untagged_addr(uaddr);
switch (op) {
case FUTEX_OP_SET:
@@ -82,6 +83,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval,
if (!access_ok(uaddr, sizeof(u32)))
return -EFAULT;
+ uaddr = untagged_addr(uaddr);
__enable_user_access();
__asm__ __volatile__ (
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 110/281] riscv: hwprobe: use _BITULL() rather than BIT() in MIPS vendor uapi header
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (108 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 109/281] riscv: futex: untag the user pointer before the atomic access Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 111/281] riscv: lib: Fix ZBB strnlen wrap-around regression on huge counts Greg Kroah-Hartman
` (177 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zongmin Zhou, Jesse Taube,
Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zongmin Zhou <zhouzongmin@kylinos.cn>
commit edba6017c19f97ecc718fad6b50e0908392247ac upstream.
BIT() is a kernel-internal macro that is not available to userspace, but
the MIPS vendor extension uapi header uses it without defining or
including it. Any userspace program that includes this header and uses
RISCV_HWPROBE_VENDOR_EXT_XMIPSEXECTL fails to build.
Use _BITULL(0) from linux/const.h instead, which keeps the value at 1,
so there is no ABI change.
Fixes: bb4b0f8a1bcb ("riscv: hwprobe: Add MIPS vendor extension probing")
Cc: stable@vger.kernel.org
Signed-off-by: Zongmin Zhou <zhouzongmin@kylinos.cn>
Reviewed-by: Jesse Taube <jtaubepe@redhat.com>
Link: https://patch.msgid.link/20260918073650.42586-1-min_halo@163.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/include/uapi/asm/vendor/mips.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/arch/riscv/include/uapi/asm/vendor/mips.h
+++ b/arch/riscv/include/uapi/asm/vendor/mips.h
@@ -1,3 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#define RISCV_HWPROBE_VENDOR_EXT_XMIPSEXECTL BIT(0)
+#include <linux/const.h>
+
+#define RISCV_HWPROBE_VENDOR_EXT_XMIPSEXECTL _BITULL(0)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 111/281] riscv: lib: Fix ZBB strnlen wrap-around regression on huge counts
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (109 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 110/281] riscv: hwprobe: use _BITULL() rather than BIT() in MIPS vendor uapi header Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 112/281] riscv: patch: fix handling of bpf-jit execmem addresses Greg Kroah-Hartman
` (176 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Laight, Qingfang Deng,
Shao Mingyin, Michael Neuling, Troy Mitchell, Aurelien Jarno,
Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shao Mingyin <shao.mingyin@zte.com.cn>
commit 282f4a8aa95c5a01b96e55eb5da297560e5f2986 upstream.
The aligned scan boundary is derived from the last valid byte,
(s + count - 1). When count is huge (e.g. SIZE_MAX, which FORTIFY
strcat/strlcat pass when the destination size is not known at compile
time), s + count wraps around and the boundary lands before s, so the
ZBB path returns a bogus length. The original implementation
(5ba15d419fab) had the same wrap-around in its (s + count) & ~7
boundary computation; after 5d588c684833 the wrapped boundary is caught
by the pre-loop guard "bgeu t0, t4, 2f", which then always exits for
aligned strings of 8 or more characters and strnlen() returns 8
instead of the real length.
This silently truncates strings built by fortified strcat: the dm
sysfs name attribute shows "live-bas" instead of "live-base", the
truncated name pollutes the udev database, and blivet/anaconda (as
well as LVM/dm-crypt/multipath userspace) break on RISC-V systems.
Detect the wrap-around and saturate the boundary to the top of the
address space, making the scan equivalent to strlen(). The saturation
clamps the increment to ~s, so it stays branchless and wrap-free:
s + min(count - 1, ~s) == saturating_add(s, count - 1)
Normal counts are unaffected.
Fixes: 5ba15d419fab ("riscv: lib: add strnlen() implementation")
Cc: stable@vger.kernel.org
Suggested-by: David Laight <david.laight.linux@gmail.com>
Suggested-by: Qingfang Deng <qingfang.deng@linux.dev>
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
Acked-by: Michael Neuling <mikey@neuling.org>
Tested-by: Troy Mitchell <troy.mitchell@linux.dev>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Link: https://patch.msgid.link/20260915152656708z04s4oSYY2BGj34F36RZa@zte.com.cn
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/lib/strnlen.S | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/lib/strnlen.S b/arch/riscv/lib/strnlen.S
index a8911605c248..5b3bbf0a3098 100644
--- a/arch/riscv/lib/strnlen.S
+++ b/arch/riscv/lib/strnlen.S
@@ -87,9 +87,25 @@ strnlen_zbb:
* Aligned boundary. Use the address of the last valid byte
* (s + count - 1) to avoid loading a word past the count
* boundary in the loop below. count == 0 is handled above.
+ *
+ * Saturate the boundary when s + count would wrap around (very
+ * large counts, e.g. SIZE_MAX passed by FORTIFY strcat/strlcat
+ * with a destination whose size is unknown at compile time).
+ * Without this, the wrapped boundary lands before s and the
+ * pre-loop guard below always exits, returning a truncated
+ * length.
+ *
+ * Clamping the increment to ~s (== SIZE_MAX - s) keeps the
+ * computation branchless and wrap-free:
+ *
+ * s + min(count - 1, ~s) == saturating_add(s, count - 1)
+ *
+ * Saturating makes the scan equivalent to strlen().
*/
- add t4, a0, a1
- addi t4, t4, -1
+ addi t4, a1, -1 /* count - 1 */
+ not t1, a0 /* SIZE_MAX - s */
+ minu t4, t4, t1 /* clamp, so s + t4 can never wrap */
+ add t4, a0, t4 /* saturated s + count - 1 */
andi t4, t4, -SZREG
/* Get the first word. */
--
2.56.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 112/281] riscv: patch: fix handling of bpf-jit execmem addresses
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (110 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 111/281] riscv: lib: Fix ZBB strnlen wrap-around regression on huge counts Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 113/281] riscv: ptrace: reject CFI regset access when extensions are absent Greg Kroah-Hartman
` (175 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wei-Jie Hung, Pu Lehui,
Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei-Jie Hung <imbigking12@gmail.com>
commit a510e1ae8c9030750c2edf7b0bc9b186cd8c7a06 upstream.
Commit 8718e5a3090b ("riscv: patch: skip fixmap mapping when kernel text
is already writable") gated the core_kernel_text() branch of patch_map()
on CONFIG_STRICT_KERNEL_RWX, and explicitly left the vmalloc branch
unchanged. That branch has a separate problem.
That branch only creates a temporary writable fixmap alias when
CONFIG_STRICT_MODULE_RWX is enabled, and otherwise assumes the target is
directly writable and returns the address unchanged. That assumption no
longer holds: bpf_prog_pack_alloc calls set_memory_rox() on every pack
unconditionally in alloc_new_pack(), independently of any
CONFIG_STRICT_*_RWX option, so BPF text in the vmalloc area is read-only
regardless of what CONFIG_STRICT_MODULE_RWX says.
With CONFIG_STRICT_MODULE_RWX=n, patch_map() returns the read-only
address directly, the subsequent copy_to_kernel_nofault() takes a
page fault and returns -EFAULT. bpf_arch_text_copy() turns that into
-EINVAL, which propagates through bpf_jit_binary_pack_finalize() to the
WARN_ON() in bpf_int_jit_compile() and leaves the program un-JITed.
Note that BPF cannot be fixed the way kprobes was in
commit bdc46e507b59 ("riscv: mm: make EXECMEM_KPROBES writable without
CONFIG_STRICT_MODULE_RWX"). EXECMEM_BPF is already PAGE_KERNEL, i.e.
writable at allocation time; the read-only mapping is established
afterwards by generic code in alloc_new_pack(), which arch code cannot
influence. The only place this can be handled is patch_map().
This is the same problem that was fixed on arm64 by commit b1480ed230ac
("arm64: patching: fix handling of execmem addresses"), and the fix is
the same: CONFIG_EXECMEM is what actually tracks whether the vmalloc
area can hold executable memory that needs a temporary alias to be
written. CONFIG_BPF_JIT, CONFIG_KPROBES and CONFIG_MODULES all select
it.
Note that this is not limited to CONFIG_MODULES=n. Unlike arm64, riscv
selects CONFIG_ARCH_OPTIONAL_KERNEL_RWX, so CONFIG_STRICT_MODULE_RWX can
be disabled with CONFIG_MODULES=y as well, and the bug is reachable in
that configuration too.
The !CONFIG_MMU build is unaffected: it has its own __patch_insn_set()
and __patch_insn_write() implementations and never calls patch_map().
Fixes: 2c9e5d4a0082 ("bpf: remove CONFIG_BPF_JIT dependency on CONFIG_MODULES of")
Signed-off-by: Wei-Jie Hung <imbigking12@gmail.com>
Reviewed-by: Pu Lehui <pulehui@huawei.com>
Tested-by: Pu Lehui <pulehui@huawei.com>
Link: https://patch.msgid.link/20260914115607.350097-1-imbigking12@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/kernel/patch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/riscv/kernel/patch.c
+++ b/arch/riscv/kernel/patch.c
@@ -46,7 +46,7 @@ static __always_inline void *patch_map(v
if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) {
phys = __pa_symbol(addr);
- } else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) {
+ } else if (IS_ENABLED(CONFIG_EXECMEM)) {
struct page *page = vmalloc_to_page(addr);
BUG_ON(!page);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 113/281] riscv: ptrace: reject CFI regset access when extensions are absent
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (111 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 112/281] riscv: patch: fix handling of bpf-jit execmem addresses Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 114/281] Bluetooth: btintel_pcie: use managed IRQ teardown Greg Kroah-Hartman
` (174 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chen Pei, Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Pei <cp0613@linux.alibaba.com>
commit adadf6df0bd55aa40ccbc6519fb443133e103227 upstream.
riscv_cfi_get() and riscv_cfi_set() do not check whether the Zicfilp
or Zicfiss extensions are present. On systems without them,
PTRACE_GETREGSET on REGSET_CFI still succeeds and returns a zeroed
user_cfi_state, misleading debuggers into believing the register set
is available, and PTRACE_SETREGSET silently accepts writes that have
no effect (e.g. clearing SR_ELP).
Reject the access with -EINVAL when neither branch landing pads nor
shadow stack is available to userspace, using the same availability
helpers as the prctl path.
Fixes: 2af7c9cf021c ("riscv/ptrace: expose riscv CFI status and state via ptrace and in core files")
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
Link: https://patch.msgid.link/20260820063233.2567-1-cp0613@linux.alibaba.com
Cc: stable@vger.kernel.org
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/kernel/ptrace.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -299,6 +299,9 @@ static int riscv_cfi_get(struct task_str
struct user_cfi_state user_cfi;
struct pt_regs *regs;
+ if (!is_user_lpad_enabled() && !is_user_shstk_enabled())
+ return -EINVAL;
+
memset(&user_cfi, 0, sizeof(user_cfi));
regs = task_pt_regs(target);
@@ -337,6 +340,9 @@ static int riscv_cfi_set(struct task_str
struct user_cfi_state user_cfi;
struct pt_regs *regs;
+ if (!is_user_lpad_enabled() && !is_user_shstk_enabled())
+ return -EINVAL;
+
regs = task_pt_regs(target);
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &user_cfi, 0, -1);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 114/281] Bluetooth: btintel_pcie: use managed IRQ teardown
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (112 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 113/281] riscv: ptrace: reject CFI regset access when extensions are absent Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 115/281] Bluetooth: hci_sock: Serialize dead-device detachment Greg Kroah-Hartman
` (173 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
commit 25016fe8c1ed0fccae107bd629089139ffbafe08 upstream.
The PCIe driver registers its MSI-X handlers with
devm_request_threaded_irq(), but remove() uses free_irq() directly. The
devres actions then retain registrations and attempt to release them again
during device cleanup.
Use devm_free_irq() for the remove path and for already registered vectors
when a later setup request fails. This removes the managed resource at the
same time as the IRQ is released and keeps MSI-X vector teardown ordered
after IRQ ownership is gone.
Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/bluetooth/btintel_pcie.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -1715,7 +1715,7 @@ static irqreturn_t btintel_pcie_irq_msix
static int btintel_pcie_setup_irq(struct btintel_pcie_data *data)
{
int err;
- int num_irqs, i;
+ int num_irqs, i, j;
for (i = 0; i < BTINTEL_PCIE_MSIX_VEC_MAX; i++)
data->msix_entries[i].entry = i;
@@ -1744,6 +1744,10 @@ static int btintel_pcie_setup_irq(struct
KBUILD_MODNAME,
msix_entry);
if (err) {
+ for (j = 0; j < i; j++)
+ devm_free_irq(&data->pdev->dev,
+ data->msix_entries[j].vector,
+ &data->msix_entries[j]);
pci_free_irq_vectors(data->pdev);
data->alloc_vecs = 0;
return err;
@@ -3003,7 +3007,7 @@ static void btintel_pcie_remove(struct p
struct msix_entry *msix_entry;
msix_entry = &data->msix_entries[i];
- free_irq(msix_entry->vector, msix_entry);
+ devm_free_irq(&pdev->dev, msix_entry->vector, msix_entry);
}
pci_free_irq_vectors(pdev);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 115/281] Bluetooth: hci_sock: Serialize dead-device detachment
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (113 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 114/281] Bluetooth: btintel_pcie: use managed IRQ teardown Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 116/281] Bluetooth: hci_sync: Fix command skb lifetime during scan setup Greg Kroah-Hartman
` (172 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 381a0925c556a8d91a80a9b9e3e86651d60ffee3 upstream.
Rebinding an HCI socket after its controller is unregistered can race
monitor control replay and crash the kernel. hci_sock_bind() clears
hci_pi(sk)->hdev and drops the device reference under only the socket
lock, whereas send_monitor_control_replay() holds hci_sk_list.lock for
reading.
Replay can observe a non-NULL hdev, then bind can clear it and drop the
last reference before create_monitor_ctrl_open() reads hdev->id. This
can cause a NULL pointer dereference if the pointer is reloaded, or a
use-after-free if the old pointer is retained.
The kernel reported:
KASAN: null-ptr-deref in range [0x0000000000000068-0x000000000000006f]
RIP: 0010:create_monitor_ctrl_open+0x579/0x800
Call Trace:
hci_sock_bind+0xd96/0x1190
__sys_bind+0x166/0x200
__x64_sys_bind+0x6d/0xb0
do_syscall_64+0xdd/0x4a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The same missing serialization lets hci_send_to_sock() select a socket
for the old device and queue its frame after bind has detached the socket
or installed a new binding.
Take hci_sk_list.lock for writing when clearing the device pointer and
resetting the socket state. This waits for existing replay and delivery
readers to finish before detachment and prevents later readers from
using the old binding. Keep hci_dev_put() outside the critical section
because the final device release can sleep.
Fixes: e04480920d1e ("Bluetooth: defer cleanup of resources in hci_unregister_dev()")
Cc: stable@vger.kernel.org
Assisted-by: GPT-6 Astra
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_sock.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1223,8 +1223,10 @@ static int hci_sock_bind(struct socket *
*/
hdev = hci_pi(sk)->hdev;
if (hdev && hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
+ write_lock(&hci_sk_list.lock);
hci_pi(sk)->hdev = NULL;
sk->sk_state = BT_OPEN;
+ write_unlock(&hci_sk_list.lock);
hci_dev_put(hdev);
}
hdev = NULL;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 116/281] Bluetooth: hci_sync: Fix command skb lifetime during scan setup
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (114 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 115/281] Bluetooth: hci_sock: Serialize dead-device detachment Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 117/281] Bluetooth: ISO: Reject concurrent BIS listener setup Greg Kroah-Hartman
` (171 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 9af12272061d206af8bc3e40215cb694421ab73a upstream.
During PA sync scan setup, hci_le_set_ext_scan_param_sync() gets the
address used for the PA_LINK lookup from hci_sent_cmd_data(). The
returned pointer borrows storage from sent_cmd or req_skb, without
holding a reference to either skb.
The scan worker runs on req_workqueue while hci_cmd_work() runs on the
separate device workqueue. After the scan worker loads sent_cmd, the
command worker can free and replace it before hci_sent_cmd_data()
dereferences the skb. The command payload can also be freed between
returning from the helper and comparing the address. The connection
lookup's RCU critical section does not protect the command skb.
KASAN reported:
BUG: KASAN: slab-use-after-free in hci_sent_cmd_data+0x27c/0x2f0
Workqueue: hci0 hci_cmd_sync_work
Call Trace:
hci_sent_cmd_data+0x27c/0x2f0
hci_le_set_scan_param_sync+0x43a/0x850
hci_passive_scan_sync+0xb09/0x1460
hci_update_passive_scan_sync+0x47c/0x6e0
hci_le_pa_create_sync+0x200/0xa70
hci_cmd_sync_work+0x13c/0x290
Allocated by task 95:
skb_clone+0x13f/0x340
hci_cmd_work+0x2a9/0x7e0
Freed by task 95:
kmem_cache_free+0xba/0x3a0
hci_cmd_work+0x29c/0x7e0
Use hdev->lock to serialize the address snapshot with sent_cmd
replacement. Protect req_skb replacement and completion cleanup with
the same lock because the helper falls back to that skb. Copy the
address before releasing the lock and use the copy for the existing
RCU-protected connection lookup. Release the mutex before sending or
waiting for commands, preserving the lookup and completion ordering.
Fixes: 22cbf4f84c00 ("Bluetooth: hci_sync: Use QoS to determine which PHY to scan")
Cc: stable@vger.kernel.org
Assisted-by: GPT-6 Astra
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/hci_core.c | 4 ++++
net/bluetooth/hci_sync.c | 10 +++++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -4113,9 +4113,11 @@ static int hci_send_cmd_sync(struct hci_
bt_dev_dbg(hdev, "skb %p", skb);
+ hci_dev_lock(hdev);
kfree_skb(hdev->sent_cmd);
hdev->sent_cmd = skb_clone(skb, GFP_KERNEL);
+ hci_dev_unlock(hdev);
if (!hdev->sent_cmd) {
skb_queue_head(&hdev->cmd_q, skb);
queue_work(hdev->workqueue, &hdev->cmd_work);
@@ -4136,8 +4138,10 @@ static int hci_send_cmd_sync(struct hci_
if (READ_ONCE(hdev->req_status) == HCI_REQ_PEND &&
!hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) {
+ hci_dev_lock(hdev);
kfree_skb(hdev->req_skb);
hdev->req_skb = skb_get(hdev->sent_cmd);
+ hci_dev_unlock(hdev);
}
return err;
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -32,8 +32,10 @@ static void hci_cmd_sync_complete(struct
WRITE_ONCE(hdev->req_status, HCI_REQ_DONE);
/* Free the request command so it is not used as response */
+ hci_dev_lock(hdev);
kfree_skb(hdev->req_skb);
hdev->req_skb = NULL;
+ hci_dev_unlock(hdev);
if (skb) {
struct sock *sk = hci_skb_sk(skb);
@@ -3060,15 +3062,21 @@ static int hci_le_set_ext_scan_param_syn
*/
if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
struct hci_cp_le_add_to_accept_list *sent;
+ bdaddr_t bdaddr;
+ hci_dev_lock(hdev);
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_ACCEPT_LIST);
+ if (sent)
+ bacpy(&bdaddr, &sent->bdaddr);
+ hci_dev_unlock(hdev);
+
if (sent) {
struct hci_conn *conn;
rcu_read_lock();
conn = hci_conn_hash_lookup_ba(hdev, PA_LINK,
- &sent->bdaddr);
+ &bdaddr);
if (conn) {
struct bt_iso_qos *qos = &conn->iso_qos;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 117/281] Bluetooth: ISO: Reject concurrent BIS listener setup
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (115 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 116/281] Bluetooth: hci_sync: Fix command skb lifetime during scan setup Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 118/281] Bluetooth: ISO: Serialize concurrent connect calls Greg Kroah-Hartman
` (170 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 555ff78fa719f50ff4cdbdb40aa1acc6e8e327d3 upstream.
iso_sock_listen() drops the socket lock before calling iso_listen_bis()
to preserve the hdev->lock ordering. Two concurrent listen() calls on
the same broadcast socket can therefore both observe BT_BOUND. Caller
A can attach connA and release the locks, then caller B can acquire
them and attach connB before A publishes BT_LISTEN.
__iso_chan_add() checks whether connB already has a socket, but not
whether the socket already has a connection. The second attachment
overwrites iso_pi(sk)->conn, leaking the connA reference and leaving
connA->sk intact. Socket teardown follows connB, so later events on
connA can cause a stale socket access.
Recheck BT_BOUND and require iso_pi(sk)->conn to be NULL after taking
both the HCI device and socket locks in iso_listen_bis(). The connection
check also covers the interval between attachment and publication of
BT_LISTEN. Reject a competing setup with -EBADFD through the existing
unlock path before allocating another connection.
A recorded KASAN report from an instrumented kernel shows:
BUG: KASAN: slab-use-after-free in iso_sock_hold+0x119/0x1f0
Call Trace:
iso_sock_hold+0x119/0x1f0
iso_conn_del+0xe4/0x270
hci_disconn_complete_evt+0x351/0x8c0
hci_event_packet+0x71b/0xb20
hci_rx_work+0x293/0x730
Allocated by task 93:
sk_prot_alloc+0x113/0x220
sk_alloc+0x2b/0x6d0
bt_sock_alloc+0x29/0x370
iso_sock_alloc.constprop.0+0x19/0x300
iso_sock_create+0x94/0x100
Freed by task 93:
kfree+0x121/0x3c0
__sk_destruct+0x42b/0x540
iso_sock_release+0x29d/0x340
__sock_release+0xa1/0x260
sock_close+0x10/0x20
Fixes: 168e28305b87 ("Bluetooth: iso: Fix circular lock in iso_listen_bis")
Cc: stable@vger.kernel.org
Assisted-by: GPT-6 Astra
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/iso.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -1340,6 +1340,11 @@ static int iso_listen_bis(struct sock *s
hci_dev_lock(hdev);
lock_sock(sk);
+ if (sk->sk_state != BT_BOUND || iso_pi(sk)->conn) {
+ err = -EBADFD;
+ goto unlock;
+ }
+
/* Fail if user set invalid QoS */
if (iso_pi(sk)->qos_user_set && !check_bcast_qos(&iso_pi(sk)->qos)) {
iso_pi(sk)->qos = default_qos;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 118/281] Bluetooth: ISO: Serialize concurrent connect calls
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (116 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 117/281] Bluetooth: ISO: Reject concurrent BIS listener setup Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 119/281] Bluetooth: MGMT: Fix status of pending commands flushed on power off Greg Kroah-Hartman
` (169 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pauli Virtanen, Chengfeng Ye,
Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit e32d80293a0e1a160d5e5101daa8c82148c07510 upstream.
iso_sock_connect() checks the socket state before taking the socket lock
and drops the lock again before setting up a connection. Two callers can
both pass the admission check while the socket is open or bound.
Caller A can copy its destination for route selection, then caller B can
replace the socket destination before A binds or connects the CIS. A
then uses B's destination with the route selected for its own request.
B can also proceed after A attaches a connection and sets BT_CONNECT.
For deferred BIS setup, B can bind a second BIS and overwrite
iso_pi(sk)->conn, leaving the first connection's reference and conn->sk
back-pointer stranded. Concurrent CIS connects can likewise replace the
socket's connection. Later teardown only detaches the current connection,
so a callback on the old connection can race with socket release and
access a freed socket.
KASAN reported:
BUG: KASAN: slab-use-after-free in iso_sock_hold+0xf7/0x1b0
Call Trace:
iso_sock_hold+0xf7/0x1b0
iso_conn_del+0x7b/0x1d0
iso_connect_cfm+0x186/0x16a0
hci_conn_failed+0x154/0x280
hci_abort_conn_sync+0x3dc/0x7d0
hci_cmd_sync_work+0x173/0x300
Allocated by task 121:
sk_alloc+0x2b/0x6d0
bt_sock_alloc+0x29/0x370
iso_sock_alloc.constprop.0+0x19/0x300
iso_sock_create+0x94/0x100
Freed by task 121:
kfree+0x121/0x3c0
__sk_destruct+0x42b/0x540
iso_sock_release+0x29d/0x340
__sock_release+0xa1/0x260
Check admission under the socket lock and mark the connect operation in
progress before publishing its destination. Keep that flag set across
route lookup and connection setup, rejecting another connect with
-EBADFD before it can change the destination or attach a connection.
Clear the flag after either helper returns, including on failure, so a
failed setup can be retried.
A separate flag is needed because the socket lock must be released before
acquiring the HCI device lock, while BT_CONNECT requires an attached
connection. Keep the existing state transitions and the deferred CIS
completion through iso_sock_recvmsg().
Reject an existing socket attachment in __iso_chan_add() before taking
a new reference or publishing either pointer, so every caller preserves
the connection association. Keep the same-socket, same-connection success
case for deferred CIS setup. Reject an attached socket before BIS setup
so a reusable BIS is not claimed before the attachment is rejected.
In CIS setup, reject a different HCI connection before iso_conn_add()
and drop the per-attempt HCI hold directly. An unowned iso_conn may still
carry another reference after detachment, so its destruction cannot be
relied on to release that hold.
iso_listen_bis() creates a fresh PA HCI/ISO pair under the device lock,
so the temporary iso_conn_put() frees the ISO candidate and drops its
HCI hold on rejection. iso_conn_ready() uses a freshly allocated,
unpublished child with no connection, making the socket-side rejection
unreachable.
Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type")
Cc: stable@vger.kernel.org
Suggested-by: Pauli Virtanen <pav@iki.fi>
Assisted-by: GPT-6 Astra
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/iso.c | 47 +++++++++++++++++++++++++++++++++++++----------
1 file changed, 37 insertions(+), 10 deletions(-)
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -61,6 +61,7 @@ enum {
BT_SK_BIG_SYNC,
BT_SK_PA_SYNC,
BT_SK_KILLED,
+ BT_SK_CONNECTING,
};
struct iso_pinfo {
@@ -350,6 +351,9 @@ static int __iso_chan_add(struct iso_con
return -EBUSY;
}
+ if (iso_pi(sk)->conn)
+ return -EISCONN;
+
if (!conn->hcon) {
BT_ERR("conn->hcon missing");
return -EIO;
@@ -410,6 +414,11 @@ static int iso_connect_bis(struct sock *
hci_dev_lock(hdev);
lock_sock(sk);
+ if (iso_pi(sk)->conn) {
+ err = -EISCONN;
+ goto unlock;
+ }
+
if (!bis_capable(hdev)) {
err = -EOPNOTSUPP;
goto unlock;
@@ -562,6 +571,13 @@ static int iso_connect_cis(struct sock *
lockdep_assert_held(&hcon->hdev->lock);
+ /* The socket lock keeps the current attachment and its hcon stable. */
+ if (iso_pi(sk)->conn && iso_pi(sk)->conn->hcon != hcon) {
+ hci_conn_drop(hcon);
+ err = -EISCONN;
+ goto unlock;
+ }
+
conn = iso_conn_add(hcon);
if (!conn) {
hci_conn_drop(hcon);
@@ -1269,17 +1285,26 @@ static int iso_sock_connect(struct socke
addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
- if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
- return -EBADFD;
+ lock_sock(sk);
- if (sk->sk_type != SOCK_SEQPACKET)
- return -EINVAL;
+ if ((sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) ||
+ test_bit(BT_SK_CONNECTING, &iso_pi(sk)->flags)) {
+ err = -EBADFD;
+ goto done;
+ }
+
+ if (sk->sk_type != SOCK_SEQPACKET) {
+ err = -EINVAL;
+ goto done;
+ }
/* Check if the address type is of LE type */
- if (!bdaddr_type_is_le(sa->iso_bdaddr_type))
- return -EINVAL;
+ if (!bdaddr_type_is_le(sa->iso_bdaddr_type)) {
+ err = -EINVAL;
+ goto done;
+ }
- lock_sock(sk);
+ set_bit(BT_SK_CONNECTING, &iso_pi(sk)->flags);
bacpy(&iso_pi(sk)->dst, &sa->iso_bdaddr);
iso_pi(sk)->dst_type = sa->iso_bdaddr_type;
@@ -1291,16 +1316,18 @@ static int iso_sock_connect(struct socke
else
err = iso_connect_bis(sk);
- if (err)
- return err;
-
lock_sock(sk);
+ clear_bit(BT_SK_CONNECTING, &iso_pi(sk)->flags);
+ if (err)
+ goto done;
+
if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
err = bt_sock_wait_state(sk, BT_CONNECTED,
sock_sndtimeo(sk, flags & O_NONBLOCK));
}
+done:
release_sock(sk);
return err;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 119/281] Bluetooth: MGMT: Fix status of pending commands flushed on power off
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (117 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 118/281] Bluetooth: ISO: Serialize concurrent connect calls Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 120/281] Bluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata() Greg Kroah-Hartman
` (168 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iaroslav Voitovych,
Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Iaroslav Voitovych <yaroslav.voytovych@gmail.com>
commit 86ef0f58bdecdedb3a1240971c56d71b7e4ce3fc upstream.
cmd_complete_rsp() receives a struct cmd_lookup and, for a pending
command that has no cmd_complete callback, falls through to
cmd_status_rsp(cmd, data). cmd_status_rsp() reads data as a u8 *, so
the status sent comes from the first byte of match->sk's
representation, not from match->mgmt_status.
commit f53e1c9c726d ("Bluetooth: MGMT: Fix possible crash on
mgmt_index_removed") changed the callers' data from &status to &match
and updated the cmd_complete branch to match->mgmt_status, but left
the fall-through passing data unchanged.
In mgmt_index_removed() match->sk is NULL, so every such command is
answered with status 0x00 (Success) instead of
MGMT_STATUS_INVALID_INDEX. In __mgmt_power_off() it is NULL too,
unless a Set Powered command was pending: then settings_rsp() has
stored that command's socket in match->sk, and the byte sent comes
from the socket pointer. Either way the status the caller set,
MGMT_STATUS_NOT_POWERED (or MGMT_STATUS_INVALID_INDEX when the device
is being unregistered), is lost.
Pass the status the callers set.
This was seen on a QCA9377 laptop: bluetoothd's Start Discovery,
pending when the adapter was powered off, was answered with Command
Status 0x00 and no parameters, and bluetoothd 5.72 crashed on the
zero-length success. BlueZ master has since added the length check
on that path ("adapter: Fix crash on short start discovery reply",
BlueZ a734b06059cb), but userspace should still be told Not Powered,
not Success.
Tested on Ubuntu 7.0.0-31 with a virtual controller (hci_vhci):
power off is held in HCI Write Scan Enable while a Start Discovery is
submitted, and the flush answers it with status 0x00 before this
change and 0x0f (Not Powered) after.
Fixes: f53e1c9c726d ("Bluetooth: MGMT: Fix possible crash on mgmt_index_removed")
Cc: stable@vger.kernel.org
Signed-off-by: Iaroslav Voitovych <yaroslav.voytovych@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/mgmt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1489,7 +1489,7 @@ static void cmd_complete_rsp(struct mgmt
return;
}
- cmd_status_rsp(cmd, data);
+ cmd_status_rsp(cmd, &match->mgmt_status);
}
static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 120/281] Bluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (118 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 119/281] Bluetooth: MGMT: Fix status of pending commands flushed on power off Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 121/281] Bluetooth: RFCOMM: free the skb when the DLC has no owner Greg Kroah-Hartman
` (167 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pauli Virtanen, Aldo Ariel Panzardo,
Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
commit 816fb1590a4c8cf8d05cd076057616be02e276f0 upstream.
sco_recv_scodata() upgrades the weak hcon->sco_data back-pointer to a
strong reference under hdev->lock:
hci_dev_lock(hdev);
hcon = hci_conn_hash_lookup_handle(hdev, handle);
...
conn = sco_conn_hold_unless_zero(hcon->sco_data);
hci_dev_unlock(hdev);
but the pointer is cleared from the other side without that lock. When
the last sco_conn reference is dropped, sco_conn_free() ran
conn->hcon->sco_data = NULL;
with no hdev->lock held, so the RX path could read hcon->sco_data and
call kref_get_unless_zero() on an sco_conn that was concurrently freed:
BUG: KASAN: slab-use-after-free in sco_conn_hold_unless_zero+0xbe/0x160
Write of size 4 by task kworker/u17:0
Workqueue: hci0 hci_rx_work
Call Trace:
sco_conn_hold_unless_zero+0xbe/0x160
sco_recv_scodata+0x13f/0x490
hci_rx_work+0x3af/0x730
kref_get_unless_zero() only guards against a zero refcount, not against
the backing memory already being freed.
Give hcon->sco_data an actual reference on the sco_conn it points to, so
the object cannot be freed while the pointer is still installed, and only
clear and drop it from sco_conn_del(), which runs under hdev->lock (its
callers, sco_connect_cfm() and sco_disconn_cfm(), hold it). The reader in
sco_recv_scodata() also takes hdev->lock, so the store and the read are
now serialised: the RX path either observes NULL or a reference that is
guaranteed to stay valid until it drops its own.
sco_conn_add() no longer hands its kref_init() reference to the caller as
the connection's only reference; that initial reference is the one owned
by hcon->sco_data, and callers get their own via sco_conn_hold().
Because the sco_conn can now outlive the socket (the association keeps it
alive until the link goes down), the hci_conn can no longer be dropped
from sco_conn_free() without regressing socket close: closing a connected
SCO socket must still tear the link down. Move hci_conn ownership to the
socket instead: __sco_chan_add() takes an hci_conn reference and it is
released from sco_chan_del() and sco_sock_destruct(), exactly once. The
sco_conn no longer owns an hci_conn reference, so sco_conn_add() stops
consuming one and sco_connect() drops the hci_connect_sco() reference on
every path; sco_connect_cfm() no longer needs its hci_conn_hold() dance.
Fixes: e6720779ae61 ("Bluetooth: SCO: Use kref to track lifetime of sco_conn")
Cc: stable@vger.kernel.org
Suggested-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/sco.c | 87 ++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 65 insertions(+), 22 deletions(-)
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -84,12 +84,14 @@ static void sco_conn_free(struct kref *r
if (conn->sk)
sco_pi(conn->sk)->conn = NULL;
- if (conn->hcon) {
- conn->hcon->sco_data = NULL;
- hci_conn_drop(conn->hcon);
- }
+ /* hcon->sco_data is cleared and the association's reference on the
+ * sco_conn is dropped in sco_conn_del() under hdev->lock, and the
+ * hci_conn is now owned by the socket (held in __sco_chan_add() and
+ * dropped in sco_chan_del()/sco_sock_destruct()), so there is nothing
+ * left to release towards hcon here.
+ */
- /* Ensure no more work items will run since hci_conn has been dropped */
+ /* Ensure no more work items will run before the connection is freed */
disable_delayed_work_sync(&conn->timeout_work);
kfree(conn);
@@ -188,25 +190,19 @@ static void sco_sock_clear_timer(struct
}
/* ---- SCO connections ---- */
-/* Consumes a reference on @hcon, which the returned sco_conn owns until it is
- * freed. On failure (NULL return) the reference is left for the caller to drop.
+/* Returns a new reference the caller must drop with sco_conn_put(). The
+ * hcon->sco_data association holds its own reference on the sco_conn for the
+ * connection's lifetime; it is dropped in sco_conn_del() under hdev->lock.
+ * @hcon is not consumed: the hci_conn reference is taken and owned by the
+ * socket in __sco_chan_add().
*/
static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
{
struct sco_conn *conn = hcon->sco_data;
conn = sco_conn_hold_unless_zero(conn);
- if (conn) {
- if (!conn->hcon) {
- sco_conn_lock(conn);
- conn->hcon = hcon;
- sco_conn_unlock(conn);
- } else {
- /* conn already owns a reference on hcon */
- hci_conn_drop(hcon);
- }
+ if (conn)
return conn;
- }
conn = kzalloc_obj(struct sco_conn);
if (!conn)
@@ -227,7 +223,10 @@ static struct sco_conn *sco_conn_add(str
BT_DBG("hcon %p conn %p", hcon, conn);
- return conn;
+ /* kref_init() above set the association reference owned by
+ * hcon->sco_data; hand the caller its own reference.
+ */
+ return sco_conn_hold(conn);
}
/* Delete channel.
@@ -242,6 +241,19 @@ static void sco_chan_del(struct sock *sk
BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
if (conn) {
+ struct hci_conn *hcon;
+
+ sco_conn_lock(conn);
+ hcon = conn->hcon;
+ sco_conn_unlock(conn);
+
+ /* Drop the socket's hci_conn reference BEFORE clearing
+ * conn->sk, so sco_conn_del() on another CPU cannot free
+ * the hci_conn while we still hold a pointer to it.
+ */
+ if (hcon)
+ hci_conn_drop(hcon);
+
sco_conn_lock(conn);
conn->sk = NULL;
sco_conn_unlock(conn);
@@ -266,6 +278,13 @@ static void sco_conn_del(struct hci_conn
BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
+ /* Detach from the hci_conn and drop the association's reference.
+ * The caller holds hdev->lock, which serialises this against the
+ * read of hcon->sco_data in sco_recv_scodata().
+ */
+ hcon->sco_data = NULL;
+ sco_conn_put(conn);
+
sco_conn_lock(conn);
sk = sco_sock_hold(conn);
sco_conn_unlock(conn);
@@ -290,6 +309,11 @@ static void __sco_chan_add(struct sco_co
sco_pi(sk)->conn = sco_conn_hold(conn);
conn->sk = sk;
+ /* The socket owns an hci_conn reference for as long as it stays
+ * attached; it is dropped in sco_chan_del()/sco_sock_destruct().
+ */
+ hci_conn_hold(conn->hcon);
+
if (parent)
bt_accept_enqueue(parent, sk, true);
}
@@ -371,6 +395,7 @@ static int sco_connect(struct sock *sk)
if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
release_sock(sk);
sco_conn_put(conn);
+ hci_conn_drop(hcon);
err = -EBADFD;
goto unlock;
}
@@ -379,9 +404,13 @@ static int sco_connect(struct sock *sk)
sco_conn_put(conn);
if (err) {
release_sock(sk);
+ hci_conn_drop(hcon);
goto unlock;
}
+ /* __sco_chan_add() took its own hci_conn reference; drop ours. */
+ hci_conn_drop(hcon);
+
/* Update source addr of the socket */
bacpy(&sco_pi(sk)->src, &hcon->src);
@@ -495,9 +524,25 @@ static struct sock *sco_get_sock_listen(
static void sco_sock_destruct(struct sock *sk)
{
+ struct sco_conn *conn = sco_pi(sk)->conn;
+
BT_DBG("sk %p", sk);
- sco_conn_put(sco_pi(sk)->conn);
+ /* If the channel was not already torn down via sco_chan_del(), drop
+ * the socket's own references here.
+ */
+ if (conn) {
+ struct hci_conn *hcon;
+
+ sco_conn_lock(conn);
+ hcon = conn->hcon;
+ sco_conn_unlock(conn);
+
+ if (hcon)
+ hci_conn_drop(hcon);
+ sco_pi(sk)->conn = NULL;
+ sco_conn_put(conn);
+ }
skb_queue_purge(&sk->sk_receive_queue);
skb_queue_purge(&sk->sk_write_queue);
@@ -1511,12 +1556,10 @@ static void sco_connect_cfm(struct hci_c
if (!status) {
struct sco_conn *conn;
- conn = sco_conn_add(hci_conn_hold(hcon));
+ conn = sco_conn_add(hcon);
if (conn) {
sco_conn_ready(conn);
sco_conn_put(conn);
- } else {
- hci_conn_drop(hcon);
}
} else
sco_conn_del(hcon, bt_to_errno(status));
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 121/281] Bluetooth: RFCOMM: free the skb when the DLC has no owner
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (119 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 120/281] Bluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata() Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 122/281] Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex Greg Kroah-Hartman
` (166 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikhail Gavrilov, Maxim Skokov,
Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxim Skokov <skokovmaksimevg@gmail.com>
commit 9d1afbf60ed53c5b051cd124153e0ae3078c8b93 upstream.
rfcomm_recv_data() hands the skb to d->data_ready() and returns 0
without freeing it, so the callback owns the skb from that point on.
The tty implementation frees it when the DLC has been detached from its
device:
static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc,
struct sk_buff *skb)
{
struct rfcomm_dev *dev = dlc->owner;
if (!dev) {
kfree_skb(skb);
return;
}
The socket implementation returns without freeing it, and the skb is
leaked.
A connected DLC can have no owner: rfcomm_sock_destruct() clears
d->owner, while the DLC itself stays on the session until it is closed.
Data frames that arrive in that window still find d->state ==
BT_CONNECTED in rfcomm_recv_data() and are handed to the callback, one
leaked skb each.
The leak does not stop on its own either. The remote runs out of
credits only once RFCOMM_RX_THROTTLED is set, and for a socket the only
place that sets it is rfcomm_sk_data_ready() itself, below the return.
rfcomm_process_dlcs() keeps granting credits, so the remote keeps
sending and the leak keeps growing.
Free the skb, as the tty side does.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Closes: https://lore.kernel.org/linux-bluetooth/CABXGCsPe5wykd8Aj-hm+SJ7SGQyb8yoGNnx3XDpPmBathj+EGg@mail.gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Maxim Skokov <skokovmaksimevg@gmail.com>
Assisted-by: Claude:claude-opus-5
Reviewed-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/rfcomm/sock.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -48,8 +48,11 @@ static void rfcomm_sock_kill(struct sock
static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
{
struct sock *sk = d->owner;
- if (!sk)
+
+ if (!sk) {
+ kfree_skb(skb);
return;
+ }
atomic_add(skb->len, &sk->sk_rmem_alloc);
skb_queue_tail(&sk->sk_receive_queue, skb);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 122/281] Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (120 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 121/281] Bluetooth: RFCOMM: free the skb when the DLC has no owner Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 123/281] Bluetooth: RFCOMM: Fix NULL tty_dev dereference in rfcomm_dev_shutdown Greg Kroah-Hartman
` (165 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pauli Virtanen,
syzbot+74071deb72339c215b2e, Jiaming Zhang, Mikhail Gavrilov,
Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
commit ac022970e9fb0a5f7e7d1f6c8e104c1ed924dd1c upstream.
An RFCOMM connect() issued while a BR/EDR link is being authenticated
makes lockdep report a circular dependency, and the reported cycle is a
real AB/BA between rfcomm_mutex and hdev->lock.
rfcomm_security_cfm() is called from the HCI event path, which already
holds hdev->lock:
hci_rx_work()
hci_event_packet()
hci_cc_read_enc_key_size() [hdev->lock]
hci_encrypt_cfm() [hci_cb_list_lock]
rfcomm_security_cfm() [rfcomm_mutex]
while an RFCOMM connect() from userspace takes the same two locks the
other way round:
rfcomm_sock_connect()
rfcomm_dlc_open() [rfcomm_mutex]
__rfcomm_dlc_open()
rfcomm_session_create()
kernel_connect()
l2cap_sock_connect()
l2cap_chan_connect() [hdev->lock]
WARNING: possible circular locking dependency detected
kworker/u131:1/1128 is trying to acquire lock:
rfcomm_mutex, at: rfcomm_security_cfm+0x31/0x3e0 [rfcomm]
but task is already holding lock:
hci_cb_list_lock, at: hci_cc_read_enc_key_size+0x1d2/0xcc0
Chain exists of:
rfcomm_mutex --> &hdev->lock --> hci_cb_list_lock
hci_auth_complete_evt() and hci_encrypt_change_evt() reach the callback
the same way.
Both orders have to be seen in the same boot, which is why a BR/EDR
connection alone is not enough to show it: a session set up by the
remote side is created by rfcomm_accept_connection() in krfcommd, which
calls kernel_accept() and never takes hdev->lock under rfcomm_mutex.
Connecting a device that authenticates and encrypts the link and then
calling connect() on an RFCOMM socket towards any address - the connect
does not have to succeed, the order is recorded before the page timeout
- reports it every time.
Only the session socket has to be connected with the lock held, and it
does not: nothing else can see the socket before it is put on the
session list. So connect it first and take rfcomm_mutex afterwards,
which removes the rfcomm_mutex -> hdev->lock order for good, rather
than keeping the HCI event path out of rfcomm_mutex.
rfcomm_session_create() becomes rfcomm_session_connect(), which returns
the connected socket without touching the session list, and
rfcomm_dlc_open() adds the session once it holds the lock again. If
another opener added a session for the same pair while this socket was
connecting, that session is used and this socket is dropped.
__rfcomm_dlc_open() now takes the session it should use, and its state
check runs after the lock is re-acquired, so a DLC that was opened or
closed in the meantime is still handled.
Over an existing ACL link the connection can complete before the
session reaches the list, and the wakeup from the socket callback is
then lost, so krfcommd is woken once the session is visible.
Connecting without the lock opens a window in which the socket can be
closed. The DLC is not on a session yet, so rfcomm_dlc_close() finds
nothing to do and returns without touching it, and rfcomm_dlc_open()
would then attach a DLC whose owner is gone. rfcomm_dlc_close() now
marks such a DLC with RFCOMM_CLOSED, and rfcomm_dlc_open() checks the
mark once it holds rfcomm_mutex again and drops the socket instead of
attaching the DLC. The mark is cleared when an open starts, so a DLC
that is reused is not affected. This covers both callers of
rfcomm_dlc_open(), the socket and the tty layer.
Fixes: 759c185d0bbd ("Bluetooth: RFCOMM: serialize security confirmation handling")
Suggested-by: Pauli Virtanen <pav@iki.fi>
Reported-by: Pauli Virtanen <pav@iki.fi>
Closes: https://lore.kernel.org/linux-bluetooth/5e76a95e934e451e7006db28827c2d64af5a88be.camel@iki.fi/
Reported-by: syzbot+74071deb72339c215b2e@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-bluetooth/6a92fadc.08e933ee.dbf97.008f.GAE@google.com/
Reported-by: Jiaming Zhang <r772577952@gmail.com>
Closes: https://lore.kernel.org/all/CANypQFabseTuRiyz2pGkc_Qj0moGDnY7KEp1qdTOqkw6gAL3hw@mail.gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Tested-by: syzbot+74071deb72339c215b2e@syzkaller.appspotmail.com
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/net/bluetooth/rfcomm.h | 1
net/bluetooth/rfcomm/core.c | 134 +++++++++++++++++++++++++++++------------
2 files changed, 96 insertions(+), 39 deletions(-)
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -207,6 +207,7 @@ struct rfcomm_dlc {
#define RFCOMM_AUTH_REJECT 7
#define RFCOMM_DEFER_SETUP 8
#define RFCOMM_ENC_DROP 9
+#define RFCOMM_CLOSED 10
/* Scheduling flags and events */
#define RFCOMM_SCHED_WAKEUP 31
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -62,10 +62,9 @@ static void rfcomm_make_uih(struct sk_bu
static void rfcomm_process_connect(struct rfcomm_session *s);
-static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
- bdaddr_t *dst,
- u8 sec_level,
- int *err);
+static struct socket *rfcomm_session_connect(bdaddr_t *src, bdaddr_t *dst,
+ u8 sec_level, int *err);
+static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
static struct rfcomm_session *rfcomm_session_del(struct rfcomm_session *s);
@@ -365,28 +364,17 @@ static int rfcomm_check_channel(u8 chann
return channel < 1 || channel > 30;
}
-static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
+static int __rfcomm_dlc_open(struct rfcomm_dlc *d, struct rfcomm_session *s,
+ u8 channel)
{
- struct rfcomm_session *s;
- int err = 0;
u8 dlci;
- BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d",
- d, d->state, src, dst, channel);
-
- if (rfcomm_check_channel(channel))
- return -EINVAL;
+ BT_DBG("dlc %p state %ld session %p channel %d",
+ d, d->state, s, channel);
if (d->state != BT_OPEN && d->state != BT_CLOSED)
return 0;
- s = rfcomm_session_get(src, dst);
- if (!s) {
- s = rfcomm_session_create(src, dst, d->sec_level, &err);
- if (!s)
- return err;
- }
-
dlci = __dlci(__session_dir(s), channel);
/* Check if DLCI already exists */
@@ -421,14 +409,84 @@ static int __rfcomm_dlc_open(struct rfco
int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
{
- int r;
+ struct rfcomm_session *s;
+ struct socket *sock;
+ int err;
+
+ BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d",
+ d, d->state, src, dst, channel);
+
+ if (rfcomm_check_channel(channel))
+ return -EINVAL;
rfcomm_lock();
- r = __rfcomm_dlc_open(d, src, dst, channel);
+ clear_bit(RFCOMM_CLOSED, &d->flags);
+
+ /* Do not page the remote device for a DLC that cannot be opened
+ * anyway. __rfcomm_dlc_open() looks at the state again once the
+ * lock has been re-acquired below.
+ */
+ if (d->state != BT_OPEN && d->state != BT_CLOSED) {
+ rfcomm_unlock();
+ return 0;
+ }
+ s = rfcomm_session_get(src, dst);
+ if (s) {
+ err = __rfcomm_dlc_open(d, s, channel);
+ rfcomm_unlock();
+ return err;
+ }
rfcomm_unlock();
- return r;
+
+ /* There is no session for this pair yet. kernel_connect() ends up in
+ * l2cap_chan_connect(), which takes hdev->lock, and the HCI event
+ * path takes rfcomm_mutex while holding hdev->lock, so the socket has
+ * to be connected with rfcomm_mutex released.
+ */
+ sock = rfcomm_session_connect(src, dst, d->sec_level, &err);
+ if (!sock)
+ return err;
+
+ rfcomm_lock();
+
+ /* The DLC may have been closed while the socket was connecting. It
+ * was not on a session, so rfcomm_dlc_close() could only mark it;
+ * attaching it now would leave it with no owner.
+ */
+ if (test_bit(RFCOMM_CLOSED, &d->flags)) {
+ rfcomm_unlock();
+ sock_release(sock);
+ return -ECONNRESET;
+ }
+
+ /* Another opener may have added a session for the same pair in the
+ * meantime; that one is used and this socket is dropped.
+ */
+ s = rfcomm_session_get(src, dst);
+ if (!s) {
+ s = rfcomm_session_add(sock, BT_BOUND);
+ if (s) {
+ s->initiator = 1;
+ sock = NULL;
+ }
+ }
+
+ err = s ? __rfcomm_dlc_open(d, s, channel) : -ENOMEM;
+
+ rfcomm_unlock();
+
+ if (sock)
+ sock_release(sock);
+
+ /* Over an existing ACL link the connection can complete before the
+ * session reaches the list, and that wakeup is then lost, so let
+ * krfcommd look at the socket state now.
+ */
+ rfcomm_schedule();
+
+ return err;
}
static void __rfcomm_dlc_disconn(struct rfcomm_dlc *d)
@@ -508,8 +566,14 @@ int rfcomm_dlc_close(struct rfcomm_dlc *
rfcomm_lock();
s = d->session;
- if (!s)
+ if (!s) {
+ /* Not on a session yet: rfcomm_dlc_open() may be connecting a
+ * socket for it with rfcomm_mutex released. Leave a mark so
+ * that it does not attach the DLC once it holds the lock again.
+ */
+ set_bit(RFCOMM_CLOSED, &d->flags);
goto no_session;
+ }
/* after waiting on the mutex check the session still exists
* then check the dlc still exists
@@ -757,12 +821,12 @@ static struct rfcomm_session *rfcomm_ses
return rfcomm_session_del(s);
}
-static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
- bdaddr_t *dst,
- u8 sec_level,
- int *err)
+/* Creates the L2CAP socket a new session will run on and starts connecting
+ * it. Must be called with rfcomm_mutex released.
+ */
+static struct socket *rfcomm_session_connect(bdaddr_t *src, bdaddr_t *dst,
+ u8 sec_level, int *err)
{
- struct rfcomm_session *s = NULL;
struct sockaddr_l2 addr;
struct socket *sock;
struct sock *sk;
@@ -792,24 +856,16 @@ static struct rfcomm_session *rfcomm_ses
l2cap_pi(sk)->chan->mode = L2CAP_MODE_ERTM;
release_sock(sk);
- s = rfcomm_session_add(sock, BT_BOUND);
- if (!s) {
- *err = -ENOMEM;
- goto failed;
- }
-
- s->initiator = 1;
-
bacpy(&addr.l2_bdaddr, dst);
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = cpu_to_le16(L2CAP_PSM_RFCOMM);
addr.l2_cid = 0;
addr.l2_bdaddr_type = BDADDR_BREDR;
*err = kernel_connect(sock, (struct sockaddr_unsized *)&addr, sizeof(addr), O_NONBLOCK);
- if (*err == 0 || *err == -EINPROGRESS)
- return s;
+ if (*err && *err != -EINPROGRESS)
+ goto failed;
- return rfcomm_session_del(s);
+ return sock;
failed:
sock_release(sock);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 123/281] Bluetooth: RFCOMM: Fix NULL tty_dev dereference in rfcomm_dev_shutdown
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (121 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 122/281] Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 124/281] drm/fb-helper: defer setup when fbdev_probe() fails, not just on -EAGAIN Greg Kroah-Hartman
` (164 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+4a807caf7680652d53b6,
Palla Raghunath, Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Palla Raghunath <raghunathpalla.0209@gmail.com>
commit 08e90633377f1b2567ab5ad6810b74c552246a07 upstream.
syzbot hit a NULL pointer dereference in rfcomm_dev_shutdown() when an
RFCOMM tty is closed.
rfcomm_dev_add() puts the new device on rfcomm_dev_list first and only
then registers the tty device and saves it in dev->tty_dev. If that
registration fails, dev->tty_dev is never set at all. The device can be
looked up in the meantime, so an open() of /dev/rfcommN gets through
rfcomm_tty_install() and attaches to it. When that tty is closed again,
rfcomm_dev_shutdown() uses dev->tty_dev without checking it:
Oops: general protection fault, probably for non-canonical address
KASAN: null-ptr-deref in range [0x0000000000000040-0x0000000000000047]
RIP: 0010:rfcomm_dev_shutdown+0x48/0xb0 net/bluetooth/rfcomm/tty.c:131
Call Trace:
tty_port_shutdown+0x1bf/0x220 drivers/tty/tty_port.c:372
tty_port_close+0x4e/0x150 drivers/tty/tty_port.c:705
tty_release+0x359/0x1670 drivers/tty/tty_io.c:1718
__fput+0x418/0xa50 fs/file_table.c:512
rfcomm_dev_destruct() already copes with a NULL dev->tty_dev. Add the
same check to rfcomm_dev_shutdown(), so the tty device is only moved
when it was actually registered.
Fixes: cad348a17e17 ("Bluetooth: Implement .activate, .shutdown and .carrier_raised methods")
Reported-by: syzbot+4a807caf7680652d53b6@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4a807caf7680652d53b6
Cc: stable@vger.kernel.org
Signed-off-by: Palla Raghunath <raghunathpalla.0209@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/rfcomm/tty.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -128,7 +128,7 @@ static void rfcomm_dev_shutdown(struct t
{
struct rfcomm_dev *dev = container_of(port, struct rfcomm_dev, port);
- if (dev->tty_dev->parent)
+ if (dev->tty_dev && dev->tty_dev->parent)
device_move(dev->tty_dev, NULL, DPM_ORDER_DEV_LAST);
/* close the dlc */
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 124/281] drm/fb-helper: defer setup when fbdev_probe() fails, not just on -EAGAIN
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (122 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 123/281] Bluetooth: RFCOMM: Fix NULL tty_dev dereference in rfcomm_dev_shutdown Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 125/281] drm/gud: dont keep a connector without a CRTC as connector_state Greg Kroah-Hartman
` (163 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+ca23c8570669ead78867,
Nguyen Ngoc Thang, Thomas Zimmermann
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
commit 755c94d178b7e972bb766199d34e4ba4f63a89eb upstream.
__drm_fb_helper_initial_config_and_unlock() calls
drm_client_modeset_probe() first, which already fills in each
mode_set->mode/num_connectors for every connected output, and only
afterwards calls drm_fb_helper_single_fb_probe() to create
fb_helper->fb and wire it into those mode_sets via
drm_setup_crtcs_fb().
If drm_fb_helper_single_fb_probe() fails with anything other than
-EAGAIN (e.g. dev->driver->fbdev_probe() itself fails), the function
bails out before drm_setup_crtcs_fb() runs and before setting
fb_helper->deferred_setup. The client is left with mode_sets that
have a mode and connectors but mode_set->fb == NULL, and nothing
marks this fb_helper as needing a retry.
__drm_fb_helper_restore_fbdev_mode_unlocked() only skips committing
when fb_helper->deferred_setup is set, so a later .restore() call
(drm_lastclose() on process exit, in this report) commits the stale
mode_set through drm_client_modeset_commit() ->
drm_client_modeset_commit_atomic() -> __drm_atomic_helper_set_config(),
which hits WARN_ON(!set->fb).
Mark fb_helper->deferred_setup on any drm_fb_helper_single_fb_probe()
failure, not just -EAGAIN, so restore keeps skipping the commit until
a later hotplug event successfully re-probes and re-populates
mode_set->fb. The real error code is still returned to the caller
unchanged.
Reported-by: syzbot+ca23c8570669ead78867@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=ca23c8570669ead78867
Fixes: ca91a2758fce ("drm/fb-helper: Support deferred setup")
Cc: stable@vger.kernel.org
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260927075434.72658-1-ngocthang2710.1999@gmail.com
Link: https://patch.msgid.link/20260917154743.1621-1-shechenglong@xfusion.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/drm_fb_helper.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1724,10 +1724,10 @@ __drm_fb_helper_initial_config_and_unloc
ret = drm_fb_helper_single_fb_probe(fb_helper);
if (ret < 0) {
- if (ret == -EAGAIN) {
- fb_helper->deferred_setup = true;
+ /* modesets are probed but fb_helper->fb isn't; defer restore too */
+ fb_helper->deferred_setup = true;
+ if (ret == -EAGAIN)
ret = 0;
- }
mutex_unlock(&fb_helper->lock);
goto err_drm_fb_helper_release_info;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 125/281] drm/gud: dont keep a connector without a CRTC as connector_state
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (123 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 124/281] drm/fb-helper: defer setup when fbdev_probe() fails, not just on -EAGAIN Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 126/281] drm/i915/gem: Prevent overstepping exec array boundary Greg Kroah-Hartman
` (162 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Sajal Gupta, Ruben Wauters
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sajal Gupta <sajal2005gupta@gmail.com>
commit 71ec70ea26e399eb8371fe9d2d5bf5dab09570fb upstream.
If the 'for_each_new_connector_in_state()' loop finishes without
hitting the break, connector_state is left pointing at the last
connector visited, which has no CRTC, instead of
staying NULL.
That skips the "if (!connector_state)" fallback below the loop, which
looks up the active connector when the state contains none. The
function then carries on with a connector that is not driven.
Fix by resetting connector_state to NULL for each connector visited that
has no CRTC, so that it is NULL when none was found and the fallback runs.
Fixes: 40e1a70b4aed ("drm: Add GUD USB Display driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260902123254.36987-1-sajal2005gupta@gmail.com?part=1
Signed-off-by: Sajal Gupta <sajal2005gupta@gmail.com>
Acked-by: Ruben Wauters <rubenru09@aol.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Ruben Wauters <rubenru09@aol.com>
Link: https://patch.msgid.link/20260922084026.15481-1-sajal2005gupta@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/gud/gud_pipe.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -507,6 +507,7 @@ int gud_plane_atomic_check(struct drm_pl
for_each_new_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc)
break;
+ connector_state = NULL;
}
/*
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 126/281] drm/i915/gem: Prevent overstepping exec array boundary
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (124 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 125/281] drm/gud: dont keep a connector without a CRTC as connector_state Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 127/281] drm/i915/gt: Unmask interrupts only when ACTIVE is true Greg Kroah-Hartman
` (161 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Krzysztof Karas, Andi Shyti,
Jani Nikula
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Karas <krzysztof.karas@intel.com>
commit ebe162db655881a38de43301151ff7ac940602b5 upstream.
It is possible for eb_relocate_parse_slow() to call kvfree() on
entries outside the original exec array during following
scenario inside eb_relocate_parse_slow():
1) eb_copy_relocations() allocates as many as eb->buffer_count
copies for exec entries;
2) eb_parse() appends up to two VMAs, right after incrementing
eb->buffer_count;
3) cleanup under "out" label uses this incremented buffer_count
to release relocation pointers from exec array via kvfree(),
not from VMA array.
To amend this problem, ensure that relocation cleanup uses the
original exec object count, excluding the VMAs appended by the
command parser.
Fixes: 8e4ba491b0ba ("drm/i915: Parse command buffer earlier in eb_relocate(slow)")
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Assisted-by: GitHub-Copilot:gpt-6-astra
Cc: stable@vger.kernel.org # 5.10+
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://patch.msgid.link/20260911061145.3535489-1-krzysztof.karas@intel.com
(cherry picked from commit 2a0158925fb943c7ba8f3216e2734952128defc9)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -1766,6 +1766,7 @@ static int eb_reinit_userptr(struct i915
static noinline int eb_relocate_parse_slow(struct i915_execbuffer *eb)
{
+ const unsigned int count = eb->buffer_count;
bool have_copy = false;
struct eb_vma *ev;
int err = 0;
@@ -1868,7 +1869,6 @@ err:
out:
if (have_copy) {
- const unsigned int count = eb->buffer_count;
unsigned int i;
for (i = 0; i < count; i++) {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 127/281] drm/i915/gt: Unmask interrupts only when ACTIVE is true
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (125 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 126/281] drm/i915/gem: Prevent overstepping exec array boundary Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 128/281] drm/imagination: Size page table preallocation by device address Greg Kroah-Hartman
` (160 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Krzysztof Karas, Andi Shyti,
Jani Nikula
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Karas <krzysztof.karas@intel.com>
commit 5346b1cec6afa4f9b4b49a9f84e3cfef95a3f7bb upstream.
There is a small race window between intel_rps_boost() reading
a stale ACTIVE state and queuing rps->work, where ACTIVE may be
changed via asynchronous calls triggered by wakeref drop.
This means that rps_work() could be triggered after the GT has
been parked, so unmasking RPS PM interrupts would happen without
holding PM wakelock. This sequence of events may be observed
during live_rc6_ctx_wa() selftest:
1) live_rc6_ctx_wa()
-> intel_engine_pm_put()
-> wakeref_put()
ASYNC1) wakeref_put() callback
-> __engine_park()
-> intel_gt_pm_put_async()
-> intel_gt_pm_put_async_untracked()
-> intel_wakeref_put_async()
ASYNC2) wakeref_put_async() callback
-> __gt_park()
-> intel_rps_park()
-> intel_rps_clear_active() [clear ACTIVE]
WITH INTERRUPTS:
-> rps_disable_interrupts()
-> cancel_work_sync(rps->work)
-> rps_reset_interrupts() [rps->pm_iir = 0]
WITHOUT INTERRUPTS (TIMER mode):
-> rps_stop_timer()
-> cancel_work_sync(rps->work)
2) live_rc6_ctx_wa()
-> intel_gt_wait_for_idle()
-> intel_gt_retire_requests_timeout()
-> dma_fence_wait_timeout()
-> ops->wait() [i915_fence_wait()]
-> i915_request_wait_timeout()
-> intel_rps_boost()
-> intel_rps_is_active() [check ACTIVE]
[OPEN RACE WINDOW]
-> queue_work(rps->work)
-> retire_requests()
-> i915_request_retire()
-> intel_rps_dec_waiters() [from 1 to 0]
If ASYNC1 and ASYNC2 would execute during [OPEN RACE WINDOW],
then:
3) rps_work() executes from the workqueue and may satisfy
"(!pm_iir && !client_boost)" test (in TIMER mode rps->pm_iir
is zeroed by an earlier rps_work() call or never gets a new
value after previous intel_rps_unpark() event), so it jumps
to "out" label, bypassing intel_rps_is_active() guard and
executes gen6_gt_pm_unmask_irq();
4) GT is parked and runtime PM wakelock is dropped, so only
a raw reference in __gt_park() ->
intel_display_power_put_async() remains for 100ms, then the
MMIO write in gen6_gt_pm_unmask_irq() detects missing
wakelock via assert_rpm_wakelock_held() and emits
"RPM wakelock ref not held during HW access" tainting kernel.
Commit 3e7abf814193 ("drm/i915: Extract GT render power state management")
dropped the "if (rps->interrupts_enabled)" guard that
gen6_pm_rps_work() had around this unmask in i915_irq.c.
INTEL_RPS_ACTIVE brackets the same window, since it is set in
intel_rps_unpark() before rps_enable_interrupts() and
rps_start_timer() and cleared in intel_rps_park() before
rps_stop_timer() and rps_disable_interrupts().
Skip unmasking when RPS is no longer active (reaching unmask
operation is independent of INTERRUPT mode). This does not
prevent RPS operation from resuming on the next unpark.
In interrupt mode, intel_rps_unpark() calls
rps_enable_interrupts(), which enables and unmasks the PM
interrupts. In timer mode, it calls rps_start_timer(),
restarting periodic engine-busyness evaluation. The timer
generates software RPS events and queues rps_work() directly,
independently of PM interrupt delivery. Neither mode requires
the late worker to unmask interrupts while the GT is parked
Fixes: 3e7abf814193 ("drm/i915: Extract GT render power state management")
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/16562
Cc: stable@vger.kernel.org # v5.5+
Assisted-by: GitHub-Copilot:claude-opus-5
Assisted-by: GitHub-Copilot:gpt-6-astra
Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://patch.msgid.link/20260910081329.3300417-1-krzysztof.karas@intel.com
(cherry picked from commit ca4a6deadad15b91ee083afe445fa6bdbfb68206)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/i915/gt/intel_rps.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/i915/gt/intel_rps.c
+++ b/drivers/gpu/drm/i915/gt/intel_rps.c
@@ -1904,7 +1904,8 @@ static void rps_work(struct work_struct
out:
spin_lock_irq(gt->irq_lock);
- gen6_gt_pm_unmask_irq(gt, rps->pm_events);
+ if (intel_rps_is_active(rps))
+ gen6_gt_pm_unmask_irq(gt, rps->pm_events);
spin_unlock_irq(gt->irq_lock);
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 128/281] drm/imagination: Size page table preallocation by device address
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (126 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 127/281] drm/i915/gt: Unmask interrupts only when ACTIVE is true Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 129/281] drm/panthor: validate userspace queue count against initialized firmware slot count Greg Kroah-Hartman
` (159 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gyeyoung Baek, Brajesh Gupta,
Alessio Belle
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gyeyoung Baek <gye976@gmail.com>
commit 789f290b2e81d42820bddcb4010ffbc2ae2ded54 upstream.
Commit 0a8224058a58 ("drm/imagination: Fix page count for page table for
map() interface") passed the device address to
pvr_mmu_op_context_create(), but the preallocation is still sized from
device_addr + sgt_offset with an exclusive end. The offset into the
object's pages has no place in a device-virtual range, and the exclusive
end allocates one table too many when the range ends on a table
boundary.
Count the tables from device_addr and the inclusive end of the range.
The new calculation does not take page table indices into account. This
fixes another issue with the previous implementation, where the
difference between start and end indices could underflow when a mapping
crossed a page table boundary. This would lead to the driver
preallocating a huge number of MMU pages, exhausting system memory and
triggering an out of memory panic.
Fixes: 0a8224058a58 ("drm/imagination: Fix page count for page table for map() interface")
Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code")
Signed-off-by: Gyeyoung Baek <gye976@gmail.com>
Reviewed-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Cc: stable@vger.kernel.org
[Alessio: add paragraph to point out OOM bug being fixed, cc stable]
Link: https://patch.msgid.link/20261001-pvr-fixes-a-v2-2-f58254e5dfb8@gmail.com
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/imagination/pvr_mmu.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
--- a/drivers/gpu/drm/imagination/pvr_mmu.c
+++ b/drivers/gpu/drm/imagination/pvr_mmu.c
@@ -2337,7 +2337,7 @@ void pvr_mmu_op_context_destroy(struct p
* @ctx: MMU context associated with owning VM context.
* @sgt: Scatter gather table containing pages pinned for use by this context.
* @device_addr: Virtual device address at the start of the requested mapping.
- * @sgt_offset: Start offset of the requested device-virtual memory mapping.
+ * @sgt_offset: Offset into @sgt of the start of the requested mapping.
* @size: Size in bytes of the requested device-virtual memory mapping. For an
* unmapping, this should be zero so that no page tables are allocated.
*
@@ -2350,7 +2350,6 @@ struct pvr_mmu_op_context *
pvr_mmu_op_context_create(struct pvr_mmu_context *ctx, struct sg_table *sgt,
u64 device_addr, u64 sgt_offset, u64 size)
{
- u64 start_addr = device_addr + sgt_offset;
int err;
struct pvr_mmu_op_context *op_ctx = kzalloc_obj(*op_ctx);
@@ -2365,18 +2364,18 @@ pvr_mmu_op_context_create(struct pvr_mmu
if (size) {
/*
- * The number of page table objects we need to prealloc is
- * indicated by the mapping size, start address and the sizes
- * of the areas mapped per PT or PD. The range calculation is
- * identical to that for the index into a table for a device
- * address, so we reuse those functions here.
+ * The page tables needed are set by the device-virtual range
+ * being mapped: one level 1 table per 1GiB region and one
+ * level 0 table per 2MiB region the range touches. Tables that
+ * already exist are not consumed, so this is an upper bound.
*/
- const u32 l1_start_idx = pvr_page_table_l2_idx(start_addr);
- const u32 l1_end_idx = pvr_page_table_l2_idx(start_addr + size);
- const u32 l1_count = l1_end_idx - l1_start_idx + 1;
- const u32 l0_start_idx = pvr_page_table_l1_idx(start_addr);
- const u32 l0_end_idx = pvr_page_table_l1_idx(start_addr + size);
- const u32 l0_count = l0_end_idx - l0_start_idx + 1;
+ const u64 last_addr = device_addr + size - 1;
+ const u64 l1_count =
+ (last_addr >> ROGUE_MMUCTRL_VADDR_PC_INDEX_SHIFT) -
+ (device_addr >> ROGUE_MMUCTRL_VADDR_PC_INDEX_SHIFT) + 1;
+ const u64 l0_count =
+ (last_addr >> ROGUE_MMUCTRL_VADDR_PD_INDEX_SHIFT) -
+ (device_addr >> ROGUE_MMUCTRL_VADDR_PD_INDEX_SHIFT) + 1;
/*
* Alloc and push page table entries until we have enough of
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 129/281] drm/panthor: validate userspace queue count against initialized firmware slot count
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (127 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 128/281] drm/imagination: Size page table preallocation by device address Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 130/281] drm/vc4: drain the hangcheck timer and works on V3D unbind Greg Kroah-Hartman
` (158 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot, Osama Abdelkader,
Steven Price, Liviu Dudau, Boris Brezillon
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Osama Abdelkader <osama.abdelkader@gmail.com>
commit ec86c43dcfff68eab4db9bdafcd3e2b16e342e18 upstream.
In panthor_drv.c:panthor_ioctl_group_create(),
the queue count is validated against the hardcoded maximum:
if (!args->queues.count || args->queues.count > MAX_CS_PER_CSG)
return -EINVAL;
However, if the firmware reports fewer slots than MAX_CS_PER_CSG,
panthor_fw_init_ifaces() will only initialize that smaller number of
stream interfaces.
If unprivileged userspace requests more queues than the firmware reported
(but no more than MAX_CS_PER_CSG), cs_slot_prog_locked() fetches an
uninitialized stream interface and may crash when dereferencing
cs_iface->input->ringbuf_base.
Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260803141149.68182-1-osama.abdelkader@gmail.com?part=1
Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Link: https://patch.msgid.link/20260804160048.174148-1-osama.abdelkader@gmail.com
Signed-off-by: Steven Price <steven.price@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/panthor/panthor_sched.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/gpu/drm/panthor/panthor_sched.c
+++ b/drivers/gpu/drm/panthor/panthor_sched.c
@@ -3675,6 +3675,9 @@ int panthor_group_create(struct panthor_
hweight64(group_args->tiler_core_mask) < group_args->max_tiler_cores)
return -EINVAL;
+ if (group_args->queues.count > sched->cs_slot_count)
+ return -EINVAL;
+
group = kzalloc_obj(*group);
if (!group)
return -ENOMEM;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 130/281] drm/vc4: drain the hangcheck timer and works on V3D unbind
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (128 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 129/281] drm/panthor: validate userspace queue count against initialized firmware slot count Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 131/281] drm/vc4: Fix firmware reference leak in vc4_drm_bind() Greg Kroah-Hartman
` (157 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Song Li, Fan Wu, Maíra Canal
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 94cf5971b1d04c6382437387c4dc3836cc7a1437 upstream.
Nothing stops the hangcheck timer that submitted jobs arm, or the
job_done_work that the render-done interrupt queues, at teardown:
vc4_irq_disable() cancels only overflow_mem_work, and vc4_gem_destroy()
runs from the drm-managed release, after vc4_v3d_unbind() has already
uninstalled the V3D interrupt and cleared vc4->v3d. A timer still armed
by then reads V3D registers through the NULL vc4->v3d pointer, and the
late callbacks run on the vc4_dev embedding them after it has been
freed.
Drain them in vc4_v3d_unbind(): shut the timer down and cancel
reset_work before the interrupt is taken down, because its
vc4_irq_reset() re-enables it, then flush job_done_work so that
completions queued at teardown still release their jobs.
This issue was found by an in-house static analysis tool.
Fixes: d5b1a78a772f ("drm/vc4: Add support for drawing 3D frames.")
Cc: stable@vger.kernel.org # 6.2+
Assisted-by: Codex:gpt-5.6
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260915095103.156007-1-fanwu01@zju.edu.cn
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/vc4/vc4_v3d.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -9,6 +9,7 @@
#include <linux/component.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/timer.h>
#include <drm/drm_print.h>
@@ -497,8 +498,15 @@ static void vc4_v3d_unbind(struct device
struct drm_device *drm = data;
struct vc4_dev *vc4 = to_vc4_dev(drm);
+ /* A straggler vc4_reset() re-enables the interrupt. */
+ timer_shutdown_sync(&vc4->hangcheck.timer);
+ cancel_work_sync(&vc4->hangcheck.reset_work);
+
vc4_irq_uninstall(drm);
+ /* Flush rather than cancel, so queued completions release their jobs. */
+ flush_work(&vc4->job_done_work);
+
/* Disable the binner's overflow memory address, so the next
* driver probe (if any) doesn't try to reuse our old
* allocation.
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 131/281] drm/vc4: Fix firmware reference leak in vc4_drm_bind()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (129 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 130/281] drm/vc4: drain the hangcheck timer and works on V3D unbind Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 132/281] drm/vmwgfx: validate pitch coming from userspace Greg Kroah-Hartman
` (156 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Maíra Canal
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
commit b816da5d5df1461446a0a5f3fe2b4948a659a790 upstream.
The firmware reference obtained via rpi_firmware_get() is leaked when
aperture_remove_all_conflicting_devices() fails, as the error label
returns without putting it. This happens before the firmware is
consumed and put further down in the function.
Put the firmware reference before jumping to err.
Fixes: c406ad5e4a85 ("drm/vc4: Notify the firmware when DRM is in charge")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260916154015.2056797-1-vulab@iscas.ac.cn
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/vc4/vc4_drv.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -360,8 +360,11 @@ static int vc4_drm_bind(struct device *d
}
ret = aperture_remove_all_conflicting_devices(driver->name);
- if (ret)
+ if (ret) {
+ if (firmware)
+ rpi_firmware_put(firmware);
goto err;
+ }
if (firmware) {
ret = rpi_firmware_property(firmware,
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 132/281] drm/vmwgfx: validate pitch coming from userspace
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (130 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 131/281] drm/vc4: Fix firmware reference leak in vc4_drm_bind() Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 133/281] drm/xe/i2c: cancel the client work on remove Greg Kroah-Hartman
` (155 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Youness HFA, Zack Rusin,
Maaz Mombasawala
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zack Rusin <zack.rusin@broadcom.com>
commit 21bc51cb89ced74d6645a138cc2f21184bc75094 upstream.
Validate the pitch, alongside the box dimensions before trying
to copy data from the underlying surface. Fixes possible
out of bounds reads with cursor snooping.
Fixes: 2ac863719e51 ("vmwgfx: Snoop DMA transfers with non-covering sizes")
Cc: stable@vger.kernel.org
Reported-by: Youness HFA <hfa.youness@gmail.com>
Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
Reviewed-by: Maaz Mombasawala <maaz.mombasawala@broadcom.com>
Link: https://patch.msgid.link/20260809204515.211045-1-zack.rusin@broadcom.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c
@@ -324,6 +324,7 @@ void vmw_kms_cursor_snoop(struct vmw_sur
unsigned long kmap_num;
SVGA3dCopyBox *box;
u32 box_count;
+ u64 src_extent;
void *virtual;
bool is_iomem;
struct vmw_dma_cmd {
@@ -335,6 +336,8 @@ void vmw_kms_cursor_snoop(struct vmw_sur
vmw_surface_get_desc(VMW_CURSOR_SNOOP_FORMAT);
const u32 image_pitch = VMW_CURSOR_SNOOP_WIDTH * desc->pitchBytesPerBlock;
+ BUILD_BUG_ON(sizeof(*srf->snooper.image) != desc->pitchBytesPerBlock);
+
cmd = container_of(header, struct vmw_dma_cmd, header);
/* No snooper installed, nothing to copy */
@@ -372,8 +375,19 @@ void vmw_kms_cursor_snoop(struct vmw_sur
return;
}
+ if (box->w == 0 || box->h == 0)
+ return;
+
+ src_extent = (u64)(box->h - 1) * cmd->dma.guest.pitch +
+ (u64)box->w * desc->pitchBytesPerBlock;
+ if (src_extent > bo->base.size) {
+ DRM_ERROR("Cursor snoop source of %llu bytes exceeds the %zu byte buffer\n",
+ src_extent, bo->base.size);
+ return;
+ }
+
kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
- kmap_num = (VMW_CURSOR_SNOOP_HEIGHT * image_pitch) >> PAGE_SHIFT;
+ kmap_num = PFN_UP(src_extent);
ret = ttm_bo_reserve(bo, true, false, NULL);
if (unlikely(ret != 0)) {
@@ -387,14 +401,16 @@ void vmw_kms_cursor_snoop(struct vmw_sur
virtual = ttm_kmap_obj_virtual(&map, &is_iomem);
- if (box->w == VMW_CURSOR_SNOOP_WIDTH && cmd->dma.guest.pitch == image_pitch) {
+ if (box->w == VMW_CURSOR_SNOOP_WIDTH &&
+ box->h == VMW_CURSOR_SNOOP_HEIGHT &&
+ cmd->dma.guest.pitch == image_pitch) {
memcpy(srf->snooper.image, virtual,
VMW_CURSOR_SNOOP_HEIGHT * image_pitch);
} else {
- /* Image is unsigned pointer. */
+ /* The destination stride is in pixels. */
for (i = 0; i < box->h; i++)
- memcpy(srf->snooper.image + i * image_pitch,
- virtual + i * cmd->dma.guest.pitch,
+ memcpy(srf->snooper.image + i * VMW_CURSOR_SNOOP_WIDTH,
+ virtual + (size_t)i * cmd->dma.guest.pitch,
box->w * desc->pitchBytesPerBlock);
}
srf->snooper.id++;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 133/281] drm/xe/i2c: cancel the client work on remove
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (131 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 132/281] drm/vmwgfx: validate pitch coming from userspace Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 134/281] drm/xe: Fix shrinker accounting double-subtraction on nested external pins Greg Kroah-Hartman
` (154 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Song Li, Fan Wu, Heikki Krogerus,
Rodrigo Vivi
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 611857adc9e7b0ee1239a0baf38498922ca5a12e upstream.
xe_i2c_notifier() stores the DesignWare adapter in i2c->adapter and
schedules i2c->work when the adapter is registered under the xe I2C
platform device, and xe_i2c_client_work() then instantiates the AMC
client device on that adapter.
xe_i2c_remove() tears down the AMC, unregisters the client devices,
the bus notifier and the adapter platform device, but it never drains
i2c->work. A work item that is still queued or running when the
adapter is unregistered dereferences i2c->adapter in
i2c_new_client_device() after platform_device_unregister() has
released the adapter. The work item is also embedded in the
devm-allocated struct xe_i2c, so a work item still queued after the
drm device devm unwind frees that allocation runs its callback on
freed memory.
The bus notifier is the only thing that schedules this work, and it is
unregistered after the client devices. An instance that is still queued
when the teardown runs can therefore write
i2c->client[XE_I2C_CLIENT_AMC] while the loop is unregistering and
clearing the same array, and an AMC client it instantiates late is only
cleaned up by the adapter's own child sweep in i2c_del_adapter().
Move bus_unregister_notifier() in front of the client teardown loop
and cancel the work right after it, so no new instance can be
scheduled and a queued instance is drained before the client array is
touched. A running instance still finds a live adapter, since the
adapter is unregistered later.
Fixes: f0e53aadd702 ("drm/xe: Support for I2C attached MCUs")
Link: https://lore.kernel.org/intel-xe/20260912085932.101598-1-fanwu01@zju.edu.cn/
Cc: stable@vger.kernel.org
Assisted-by: LLM, in-house static analysis tool
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20260928013030.612592-1-fanwu01@zju.edu.cn
Link: https://patch.msgid.link/20261006000413.318561-2-rodrigo.vivi@intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
(cherry picked from commit a23f27d5ec11c3f418c5e5531eea34ccda2b5b20)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/xe/xe_i2c.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/xe/xe_i2c.c
+++ b/drivers/gpu/drm/xe/xe_i2c.c
@@ -330,12 +330,15 @@ static void xe_i2c_remove(void *data)
xe_i2c_irq_reset(xe);
xe_amc_exit(i2c);
+ /* Stop the notifier from arming the client work before teardown. */
+ bus_unregister_notifier(&i2c_bus_type, &i2c->bus_notifier);
+ cancel_work_sync(&i2c->work);
+
for (i = 0; i < XE_I2C_MAX_CLIENTS; i++) {
i2c_unregister_device(i2c->client[i]);
i2c->client[i] = NULL;
}
- bus_unregister_notifier(&i2c_bus_type, &i2c->bus_notifier);
xe_i2c_unregister_adapter(i2c);
xe->i2c = NULL;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 134/281] drm/xe: Fix shrinker accounting double-subtraction on nested external pins
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (132 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 133/281] drm/xe/i2c: cancel the client work on remove Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 135/281] drm/xe: Fix stale pinned_link entry when fb-pin performs the final unpin Greg Kroah-Hartman
` (153 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thomas Hellström, Matthew Brost,
Rodrigo Vivi, intel-xe, Matthew Auld, Himal Prasad Ghimiray
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellström <thomas.hellstrom@linux.intel.com>
commit 83d5acca1f4f6132038ea88c72c5844f62e42d44 upstream.
xe_bo_pin_external() and xe_bo_unpin_external() support nested pins,
since the underlying ttm_bo_pin()/ttm_bo_unpin() maintain a pin_count
refcount rather than a boolean. However, the shrinker accounting calls
xe_ttm_tt_account_subtract() and xe_ttm_tt_account_add() are invoked
unconditionally on every pin_external()/unpin_external() call, instead
of only on the transition into and out of the pinned state.
An external BO (dma-buf) can be pinned more than once while already
pinned, for example when it has multiple attachments/importers, each
independently calling xe_bo_pin_external(). Each such nested pin
subtracts the BO's pages from the shrinker's accounting again, even
though the BO's pages were already removed from consideration by the
first pin. Symmetrically, each nested unpin adds them back again
before the BO is actually unpinned. This desynchronizes the
shrinker's page and object counts from reality, and since they are
declared as signed long but interpreted as unsigned long in
xe_shrinker_count(), the underflow can turn into an enormous
shrinkable/purgeable page count, causing the shrinker to be invoked
excessively under memory pressure.
Guard the accounting calls with the same pin-count transition checks
already used to guard the pinned_link list maintenance, so accounting
is only updated on the outermost pin and the final unpin.
While centralizing this logic into xe_bo_account_pin()/
xe_bo_account_unpin(), also close a second, related accounting gap
affecting imported dma-bufs. For an imported bo's ttm_tt, xe's
ttm_tt_populate hook (xe_ttm_tt_populate()) early-returns without
calling xe_ttm_tt_account_add(), since TTM_TT_FLAG_EXTERNAL is set
without TTM_TT_FLAG_EXTERNAL_MAPPABLE. However, TTM core's
ttm_tt_populate() wrapper unconditionally marks the tt as populated
on driver-hook success, so ttm_tt_is_populated() still reports true
for it. xe_bo_account_pin()/xe_bo_account_unpin() trusted
ttm_tt_is_populated() as a proxy for "these pages are accounted for
by the shrinker", and would subtract/add pages for such a tt that
were never added in the first place, again underflowing the
shrinker's counts. This is reachable today via xe_bo_pin_external(),
and would have become newly reachable via the fb-pin path once this
patch routes __xe_pin_fb_vma() through xe_bo_pin_account() below, so
fix it here rather than in a later patch, to avoid a commit in this
series that introduces the regression before fixing it. Skip the
accounting for imported bos, using the same EXTERNAL &&
!EXTERNAL_MAPPABLE test xe_ttm_tt_populate()/xe_ttm_tt_unpopulate()
use to decide whether to act, via a new xe_ttm_bo_is_imported()
helper (hoisted up from its only prior use site).
v2:
- Fix the critical issue caught by Sashiko AI review: the pin-count
transition check introduced here was still bypassed by the fb-pin
path (__xe_pin_fb_vma()/__xe_unpin_fb_vma()), which could leave a
stale pinned_link entry and a permanent shrinker accounting leak
when the fb-unpin performed the true last unpin. Addressed in a
separate follow-up patch in this series rather than folded in here,
since it is a distinct bug with its own Fixes: tag.
- Drop the unneeded local "last_unpin" variable in
xe_bo_unpin_external(), restoring the original inline
bo->ttm.pin_count == 1 check; it was a no-op rename not used by any
of the new accounting helpers, and was going to be deleted again by
the follow-up patch anyway.
v3:
- Exclude imported dma-bufs from the pin/unpin shrinker accounting,
fixing another underflow caught by Sashiko AI review.
- Add a short comment on the backup-object pin site noting it's
already populated/accounted at pin time, addressing (as a
false-positive clarification, no code fix needed) a separate
Medium-severity accounting-leak concern also caught by Sashiko AI
review.
Fixes: 00c8efc3180f ("drm/xe: Add a shrinker for xe bos")
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: intel-xe@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v6.15+
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Assisted-by: LLM
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Link: https://patch.msgid.link/20261002100830.12297-2-thomas.hellstrom@linux.intel.com
(cherry picked from commit 6a117a2bb7ca657e3a19f83f4c06265d38dee06c)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/xe/display/xe_fb_pin.c | 6 -
drivers/gpu/drm/xe/xe_bo.c | 116 +++++++++++++++++++++++++--------
drivers/gpu/drm/xe/xe_bo.h | 2
3 files changed, 95 insertions(+), 29 deletions(-)
--- a/drivers/gpu/drm/xe/display/xe_fb_pin.c
+++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c
@@ -356,7 +356,7 @@ static struct i915_vma *__xe_pin_fb_vma(
drm_exec_retry_on_contention(&exec);
xe_validation_retry_on_oom(&ctx, &ret);
if (!ret)
- ttm_bo_pin(&bo->ttm);
+ xe_bo_pin_account(bo);
}
if (ret)
goto err;
@@ -373,7 +373,7 @@ static struct i915_vma *__xe_pin_fb_vma(
err_unpin:
ttm_bo_reserve(&bo->ttm, false, false, NULL);
- ttm_bo_unpin(&bo->ttm);
+ xe_bo_unpin_account(bo);
ttm_bo_unreserve(&bo->ttm);
err:
kfree(vma);
@@ -393,7 +393,7 @@ static void __xe_unpin_fb_vma(struct i91
xe_ggtt_node_remove(vma->node, false);
ttm_bo_reserve(&vma->bo->ttm, false, false, NULL);
- ttm_bo_unpin(&vma->bo->ttm);
+ xe_bo_unpin_account(vma->bo);
ttm_bo_unreserve(&vma->bo->ttm);
kfree(vma);
}
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -443,6 +443,85 @@ static void xe_ttm_tt_account_subtract(s
xe_shrinker_mod_pages(xe->mem.shrinker, -(long)tt->num_pages, 0);
}
+static bool xe_ttm_bo_is_imported(struct ttm_buffer_object *tbo)
+{
+ dma_resv_assert_held(tbo->base.resv);
+
+ return tbo->ttm &&
+ (tbo->ttm->page_flags & (TTM_TT_FLAG_EXTERNAL | TTM_TT_FLAG_EXTERNAL_MAPPABLE)) ==
+ TTM_TT_FLAG_EXTERNAL;
+}
+
+/*
+ * Account @bo's pages as pinned for the shrinker. Removes @bo's pages
+ * from the shrinker's shrinkable / purgeable counts on the transition
+ * from unpinned to pinned. Must be called with @bo's dma-resv held,
+ * after &ttm_buffer_object.pin_count has been incremented by
+ * ttm_bo_pin(). Safe to call unconditionally regardless of which pin
+ * path (kernel, external, framebuffer, backup object, ...) is pinning
+ * @bo, since it only acts on the true 0->1 pin_count transition.
+ *
+ * Imported bos (xe_ttm_bo_is_imported()) are excluded: for those,
+ * xe_ttm_tt_populate() never actually populates the tt or calls
+ * xe_ttm_tt_account_add(), but TTM core's ttm_tt_populate() still
+ * unconditionally marks the tt as populated on driver-hook success.
+ * Relying on ttm_tt_is_populated() for these would subtract pages that
+ * were never added, underflowing the shrinker's counts.
+ */
+static void xe_bo_account_pin(struct xe_bo *bo)
+{
+ struct xe_device *xe = xe_bo_device(bo);
+
+ if (bo->ttm.pin_count == 1 && bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm) &&
+ !xe_ttm_bo_is_imported(&bo->ttm))
+ xe_ttm_tt_account_subtract(xe, bo->ttm.ttm);
+}
+
+/*
+ * Counterpart to xe_bo_account_pin(). Must be called with @bo's dma-resv
+ * held, before &ttm_buffer_object.pin_count is decremented by
+ * ttm_bo_unpin(), so that the check against the true 1->0 transition sees
+ * the pin count that is about to be released. See xe_bo_account_pin() for
+ * why imported bos are excluded.
+ */
+static void xe_bo_account_unpin(struct xe_bo *bo)
+{
+ struct xe_device *xe = xe_bo_device(bo);
+
+ if (bo->ttm.pin_count == 1 && bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm) &&
+ !xe_ttm_bo_is_imported(&bo->ttm))
+ xe_ttm_tt_account_add(xe, bo->ttm.ttm);
+}
+
+/**
+ * xe_bo_pin_account() - Pin a bo and account its pages for the shrinker
+ * @bo: The buffer object to pin.
+ *
+ * Pins @bo via ttm_bo_pin() and updates the shrinker's shrinkable /
+ * purgeable page accounting to match. Must be called with @bo's dma-resv
+ * held. Safe to call regardless of which pin path (kernel, external,
+ * framebuffer, backup object, ...) is pinning @bo.
+ */
+void xe_bo_pin_account(struct xe_bo *bo)
+{
+ ttm_bo_pin(&bo->ttm);
+ xe_bo_account_pin(bo);
+}
+
+/**
+ * xe_bo_unpin_account() - Unpin a bo and account its pages for the shrinker
+ * @bo: The buffer object to unpin.
+ *
+ * Counterpart to xe_bo_pin_account(). Updates the shrinker's shrinkable /
+ * purgeable page accounting to match, then unpins @bo via ttm_bo_unpin().
+ * Must be called with @bo's dma-resv held.
+ */
+void xe_bo_unpin_account(struct xe_bo *bo)
+{
+ xe_bo_account_unpin(bo);
+ ttm_bo_unpin(&bo->ttm);
+}
+
static void update_global_total_pages(struct ttm_device *ttm_dev,
long num_pages)
{
@@ -1377,7 +1456,8 @@ int xe_bo_notifier_prepare_pinned(struct
}
backup->parent_obj = xe_bo_get(bo); /* Released by bo_destroy */
- ttm_bo_pin(&backup->ttm);
+ /* Note: XE_BO_FLAG_SYSTEM resolves to XE_PL_TT so already populated. */
+ xe_bo_pin_account(backup);
bo->backup_obj = backup;
}
@@ -1397,7 +1477,7 @@ int xe_bo_notifier_unprepare_pinned(stru
{
xe_bo_lock(bo, false);
if (bo->backup_obj) {
- ttm_bo_unpin(&bo->backup_obj->ttm);
+ xe_bo_unpin_account(bo->backup_obj);
xe_bo_put(bo->backup_obj);
bo->backup_obj = NULL;
}
@@ -1608,7 +1688,7 @@ out_backup:
xe_bo_vunmap(backup);
if (!bo->backup_obj) {
if (xe_bo_is_pinned(backup))
- ttm_bo_unpin(&backup->ttm);
+ xe_bo_unpin_account(backup);
xe_bo_put(backup);
}
out_unlock_bo:
@@ -2000,15 +2080,6 @@ static vm_fault_t xe_err_to_fault_t(int
return VM_FAULT_SIGBUS;
}
-static bool xe_ttm_bo_is_imported(struct ttm_buffer_object *tbo)
-{
- dma_resv_assert_held(tbo->base.resv);
-
- return tbo->ttm &&
- (tbo->ttm->page_flags & (TTM_TT_FLAG_EXTERNAL | TTM_TT_FLAG_EXTERNAL_MAPPABLE)) ==
- TTM_TT_FLAG_EXTERNAL;
-}
-
static vm_fault_t xe_bo_cpu_fault_fastpath(struct vm_fault *vmf, struct xe_device *xe,
struct xe_bo *bo, bool needs_rpm)
{
@@ -2975,12 +3046,13 @@ uint64_t vram_region_gpu_offset(struct t
int xe_bo_pin_external(struct xe_bo *bo, bool in_place, struct drm_exec *exec)
{
struct xe_device *xe = xe_bo_device(bo);
+ bool first_pin = !xe_bo_is_pinned(bo);
int err;
xe_assert(xe, !bo->vm);
xe_assert(xe, xe_bo_is_user(bo));
- if (!xe_bo_is_pinned(bo)) {
+ if (first_pin) {
if (!in_place) {
err = xe_bo_validate(bo, NULL, false, exec);
if (err)
@@ -2992,9 +3064,7 @@ int xe_bo_pin_external(struct xe_bo *bo,
spin_unlock(&xe->pinned.lock);
}
- ttm_bo_pin(&bo->ttm);
- if (bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm))
- xe_ttm_tt_account_subtract(xe, bo->ttm.ttm);
+ xe_bo_pin_account(bo);
/*
* FIXME: If we always use the reserve / unreserve functions for locking
@@ -3050,9 +3120,7 @@ int xe_bo_pin(struct xe_bo *bo, struct d
spin_unlock(&xe->pinned.lock);
}
- ttm_bo_pin(&bo->ttm);
- if (bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm))
- xe_ttm_tt_account_subtract(xe, bo->ttm.ttm);
+ xe_bo_pin_account(bo);
/*
* FIXME: If we always use the reserve / unreserve functions for locking
@@ -3086,9 +3154,7 @@ void xe_bo_unpin_external(struct xe_bo *
list_del_init(&bo->pinned_link);
spin_unlock(&xe->pinned.lock);
- ttm_bo_unpin(&bo->ttm);
- if (bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm))
- xe_ttm_tt_account_add(xe, bo->ttm.ttm);
+ xe_bo_unpin_account(bo);
/*
* FIXME: If we always use the reserve / unreserve functions for locking
@@ -3113,14 +3179,12 @@ void xe_bo_unpin(struct xe_bo *bo)
if (bo->backup_obj) {
if (xe_bo_is_pinned(bo->backup_obj))
- ttm_bo_unpin(&bo->backup_obj->ttm);
+ xe_bo_unpin_account(bo->backup_obj);
xe_bo_put(bo->backup_obj);
bo->backup_obj = NULL;
}
}
- ttm_bo_unpin(&bo->ttm);
- if (bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm))
- xe_ttm_tt_account_add(xe, bo->ttm.ttm);
+ xe_bo_unpin_account(bo);
}
/**
--- a/drivers/gpu/drm/xe/xe_bo.h
+++ b/drivers/gpu/drm/xe/xe_bo.h
@@ -228,6 +228,8 @@ int xe_bo_pin_external(struct xe_bo *bo,
int xe_bo_pin(struct xe_bo *bo, struct drm_exec *exec);
void xe_bo_unpin_external(struct xe_bo *bo);
void xe_bo_unpin(struct xe_bo *bo);
+void xe_bo_pin_account(struct xe_bo *bo);
+void xe_bo_unpin_account(struct xe_bo *bo);
int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict,
struct drm_exec *exec);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 135/281] drm/xe: Fix stale pinned_link entry when fb-pin performs the final unpin
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (133 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 134/281] drm/xe: Fix shrinker accounting double-subtraction on nested external pins Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 136/281] drm/bridge: th1520-dw-hdmi: Fix error check on dw_hdmi_probe() return value Greg Kroah-Hartman
` (152 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maarten Lankhorst, Rodrigo Vivi,
intel-xe, Matthew Auld, Himal Prasad Ghimiray,
Thomas Hellström
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellström <thomas.hellstrom@linux.intel.com>
commit cf238c067eaae1cbfb00738e29219b9568d2313e upstream.
xe_bo_pin_external() and xe_bo_unpin_external() maintain the bo's
pinned_link list membership in xe->pinned.late.external, based on
whether the current call is the outermost pin or the final unpin.
However, the same external bo's pin_count can also be raised and
lowered directly by __xe_pin_fb_vma()/__xe_unpin_fb_vma(), which pin
the bo as a display scanout buffer without going through
xe_bo_pin_external()/xe_bo_unpin_external() at all, and have no
notion of, or ownership over, pinned_link.
If a bo is pinned both externally (e.g. dma-buf export) and as an fb,
and the external unpin happens first, xe_bo_unpin_external() correctly
observes pin_count > 1 and leaves the bo on pinned_link. When the fb
unpin later performs the true last unpin (pin_count 1 -> 0), it never
touches pinned_link, leaving the bo linked on xe->pinned.late.external
indefinitely. Once the bo is subsequently freed, this stale list entry
points into freed memory, corrupting the list and risking a
use-after-free the next time the list is walked or spliced.
The backup object pin/unpin sites in xe_bo_notifier_prepare_pinned()/
xe_bo_notifier_unprepare_pinned() have the same bypass characteristic,
though they never add their bo to a pinned list, so are not affected
by this particular list-corruption issue.
Move the pinned_link removal into xe_bo_account_unpin(), which already
runs on every unpin path (kernel, external, framebuffer, backup
object) right before the true 1 -> 0 pin_count transition. Since
list_del_init() only operates on the node itself, this removal is
list-agnostic and safe to perform regardless of which list (external
or kernel_bo_present) the bo happens to be linked on, or which code
path is performing the final unpin. Drop the now-redundant explicit
list_del_init() calls in xe_bo_unpin_external() and xe_bo_unpin().
v2:
- New patch
v3:
- Rebased on changes to previous patch.
Fixes: 44e694958b95 ("drm/xe/display: Implement display support")
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: intel-xe@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v6.8+
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Assisted-by: LLM
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Link: https://patch.msgid.link/20261002100830.12297-3-thomas.hellstrom@linux.intel.com
(cherry picked from commit ca58d36a1f93af586ee93b340c9f9fd81312cc01)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/xe/xe_bo.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -483,12 +483,27 @@ static void xe_bo_account_pin(struct xe_
* ttm_bo_unpin(), so that the check against the true 1->0 transition sees
* the pin count that is about to be released. See xe_bo_account_pin() for
* why imported bos are excluded.
+ *
+ * On the true last unpin, also removes @bo from whichever pinned-bo list
+ * (external or kernel_bo_present) it may currently be linked on, since a
+ * bo's final unpin can happen through a pin path (e.g. framebuffer,
+ * backup object) that has no notion of, or ownership over, that list.
+ * This is safe and list-agnostic: list_del_init() only needs the node
+ * itself, not knowledge of which list it is threaded through, and is a
+ * no-op if @bo is not linked.
*/
static void xe_bo_account_unpin(struct xe_bo *bo)
{
struct xe_device *xe = xe_bo_device(bo);
+ bool last_unpin = bo->ttm.pin_count == 1;
+
+ if (last_unpin && !list_empty(&bo->pinned_link)) {
+ spin_lock(&xe->pinned.lock);
+ list_del_init(&bo->pinned_link);
+ spin_unlock(&xe->pinned.lock);
+ }
- if (bo->ttm.pin_count == 1 && bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm) &&
+ if (last_unpin && bo->ttm.ttm && ttm_tt_is_populated(bo->ttm.ttm) &&
!xe_ttm_bo_is_imported(&bo->ttm))
xe_ttm_tt_account_add(xe, bo->ttm.ttm);
}
@@ -3149,11 +3164,6 @@ void xe_bo_unpin_external(struct xe_bo *
xe_assert(xe, xe_bo_is_pinned(bo));
xe_assert(xe, xe_bo_is_user(bo));
- spin_lock(&xe->pinned.lock);
- if (bo->ttm.pin_count == 1 && !list_empty(&bo->pinned_link))
- list_del_init(&bo->pinned_link);
- spin_unlock(&xe->pinned.lock);
-
xe_bo_unpin_account(bo);
/*
@@ -3172,10 +3182,7 @@ void xe_bo_unpin(struct xe_bo *bo)
xe_assert(xe, xe_bo_is_pinned(bo));
if (mem_type_is_vram(place->mem_type) || bo->flags & XE_BO_FLAG_GGTT) {
- spin_lock(&xe->pinned.lock);
xe_assert(xe, !list_empty(&bo->pinned_link));
- list_del_init(&bo->pinned_link);
- spin_unlock(&xe->pinned.lock);
if (bo->backup_obj) {
if (xe_bo_is_pinned(bo->backup_obj))
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 136/281] drm/bridge: th1520-dw-hdmi: Fix error check on dw_hdmi_probe() return value
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (134 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 135/281] drm/xe: Fix stale pinned_link entry when fb-pin performs the final unpin Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 137/281] drm/bridge: th1520-dw-hdmi: Fix remove() callback Greg Kroah-Hartman
` (151 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Gu, Dmitry Baryshkov,
Icenowy Zheng
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <ustc.gu@gmail.com>
commit add916cfcec5b71cb242db85b91b2437be7390cf upstream.
The error check after calling dw_hdmi_probe() was incorrectly checking
the struct pointer hdmi instead of the probe result hdmi->dw_hdmi.
Fix this by checking the correct variable.
Fixes: 96f30ee0fb9d ("drm/bridge: add a driver for T-Head TH1520 HDMI controller")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Cc: stable@vger.kernel.org
Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Link: https://patch.msgid.link/20260321-th1520-v1-1-ec877197770d@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/bridge/th1520-dw-hdmi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/th1520-dw-hdmi.c b/drivers/gpu/drm/bridge/th1520-dw-hdmi.c
index cbea8b14cd4b..3464720b4e13 100644
--- a/drivers/gpu/drm/bridge/th1520-dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/th1520-dw-hdmi.c
@@ -135,8 +135,8 @@ static int th1520_dw_hdmi_probe(struct platform_device *pdev)
plat_data->priv_data = hdmi;
hdmi->dw_hdmi = dw_hdmi_probe(pdev, plat_data);
- if (IS_ERR(hdmi))
- return PTR_ERR(hdmi);
+ if (IS_ERR(hdmi->dw_hdmi))
+ return PTR_ERR(hdmi->dw_hdmi);
platform_set_drvdata(pdev, hdmi);
--
2.56.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 137/281] drm/bridge: th1520-dw-hdmi: Fix remove() callback
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (135 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 136/281] drm/bridge: th1520-dw-hdmi: Fix error check on dw_hdmi_probe() return value Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 138/281] drm/amdkfd: align SDMA doorbell base for shader doorbell writes Greg Kroah-Hartman
` (150 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Gu, Dmitry Baryshkov,
Icenowy Zheng
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <ustc.gu@gmail.com>
commit 01c83795d50ccdb441f60e89ff50767cb2f6045a upstream.
This driver stores struct th1520_hdmi * in platform drvdata, but
th1520_dw_hdmi_remove() was reading it back as struct dw_hdmi *
and passing it to dw_hdmi_remove(), so teardown runs on the wrong
pointer.
Retrieve struct th1520_hdmi * from platform drvdata and pass
hdmi->dw_hdmi to dw_hdmi_remove().
Fixes: 96f30ee0fb9d ("drm/bridge: add a driver for T-Head TH1520 HDMI controller")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Cc: stable@vger.kernel.org
Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Link: https://patch.msgid.link/20260321-th1520-v1-2-ec877197770d@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/bridge/th1520-dw-hdmi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/th1520-dw-hdmi.c b/drivers/gpu/drm/bridge/th1520-dw-hdmi.c
index 3464720b4e13..2fa7f2d46b3d 100644
--- a/drivers/gpu/drm/bridge/th1520-dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/th1520-dw-hdmi.c
@@ -145,9 +145,9 @@ static int th1520_dw_hdmi_probe(struct platform_device *pdev)
static void th1520_dw_hdmi_remove(struct platform_device *pdev)
{
- struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
+ struct th1520_hdmi *hdmi = platform_get_drvdata(pdev);
- dw_hdmi_remove(hdmi);
+ dw_hdmi_remove(hdmi->dw_hdmi);
}
static const struct of_device_id th1520_dw_hdmi_of_table[] = {
--
2.56.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 138/281] drm/amdkfd: align SDMA doorbell base for shader doorbell writes
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (136 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 137/281] drm/bridge: th1520-dw-hdmi: Fix remove() callback Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 139/281] drm/amdkfd: fix dma_buf reference leak in get_dmabuf_info Greg Kroah-Hartman
` (149 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Saleel Kudchadker, Felix Kuehling,
Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saleel Kudchadker <Saleel.Kudchadker@amd.com>
commit f145d5b3f740de05d85257acdc82f6877180f5c6 upstream.
On GC 9.4.3, 9.4.4 and 9.5.0, doorbell writes issued from shaders are
routed to an SDMA engine at 32-byte (4 doorbell index) granularity.
SDMA engine doorbell ranges are 10 indices apart, so the range of every
odd engine starts 2 indices into a 4-index block that begins in the
previous engine's range. A shader ringing the doorbell of a queue on an
odd engine therefore rings the previous engine instead. The intended
queue never sees the doorbell, so its work stalls and the application
hangs.
Align the per-engine doorbell base up to a 4-index boundary on these
ASICs. Each engine only uses 4 of its 10 indices, so the aligned base
plus the queue offset stays within the engine's range. Even engines are
already aligned, so only the doorbell IDs of odd-engine queues change.
Only doorbells rung by the device itself are routed this way. Doorbell
writes from the host, including the kernel's own SDMA rings, are not
affected.
The doorbell ID of an SDMA queue is saved in CRIU checkpoints and
checked again on restore. A checkpoint taken before this change that
contains an SDMA queue on an odd engine will fail to restore with
-EINVAL. This is intentional: the restored process still holds the old
doorbell address, so accepting the stale ID would bring back the same
stall.
Tested on MI300X with a shader-rung SDMA doorbell test: queues on odd
engines hung before this change and complete with it.
v2: use u32 instead of uint32_t for the new locals (checkpatch)
v3: name the routing granularity, use dev->node_id, document the
layout invariants, describe impact
v4: express the granularity in doorbell indices, drop unrelated
cleanups, explain the CRIU restore behavior, add test note
Fixes: 6df442a03d1a ("drm/amdgpu: add new doorbell assignment table for aqua_vanjaram")
Signed-off-by: Saleel Kudchadker <Saleel.Kudchadker@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ee1379e6d7da47bdf7a8d5b89c2d1b28473701fb)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 32 ++++++++++++++----
drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 7 +++
2 files changed, 33 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -599,12 +599,32 @@ static int allocate_doorbell(struct qcm_
* we need the physical sdma engine id in order to get the
* correct doorbell offset.
*/
- uint32_t valid_id = idx_offset[qpd->dqm->dev->node_id *
- get_num_all_sdma_engines(qpd->dqm) +
- q->properties.sdma_engine_id]
- + (q->properties.sdma_queue_id & 1)
- * KFD_QUEUE_DOORBELL_MIRROR_OFFSET
- + (q->properties.sdma_queue_id >> 1);
+ u32 engine_base = idx_offset[dev->node_id *
+ get_num_all_sdma_engines(qpd->dqm) +
+ q->properties.sdma_engine_id];
+ u32 valid_id;
+
+ /*
+ * With the aqua_vanjaram doorbell layout, a shader doorbell
+ * write whose 32-byte block starts in the previous engine's
+ * range rings that engine instead. Engine ranges are 10
+ * indices apart (sdma_doorbell_range = 20 dwords, halved for
+ * 8-byte doorbells, in aqua_vanjaram_doorbell_index_init()),
+ * which puts odd engines 2 indices into a shared block.
+ * Aligning costs at most 2 indices, and 8 queues per engine use
+ * only 4 of the 10, so the aligned base stays in range. The
+ * 512-index mirror offset keeps the alignment.
+ */
+ if (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 3) ||
+ KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 4) ||
+ KFD_GC_VERSION(dev) == IP_VERSION(9, 5, 0))
+ engine_base = ALIGN(engine_base,
+ KFD_SDMA_SHADER_DOORBELL_GRANULARITY);
+
+ valid_id = engine_base +
+ (q->properties.sdma_queue_id & 1) *
+ KFD_QUEUE_DOORBELL_MIRROR_OFFSET +
+ (q->properties.sdma_queue_id >> 1);
if (restore_id && *restore_id != valid_id)
return -EINVAL;
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -132,6 +132,13 @@
*/
#define KFD_QUEUE_DOORBELL_MIRROR_OFFSET 512
+/*
+ * On GC 9.4.3, 9.4.4 and 9.5.0, doorbell writes issued from shaders are
+ * routed to an SDMA engine at 32-byte granularity, i.e. 4 indices with the
+ * 8-byte SDMA doorbells used on SOC15.
+ */
+#define KFD_SDMA_SHADER_DOORBELL_GRANULARITY 4
+
/**
* enum kfd_ioctl_flags - KFD ioctl flags
* Various flags that can be set in &amdkfd_ioctl_desc.flags to control how
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 139/281] drm/amdkfd: fix dma_buf reference leak in get_dmabuf_info
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (137 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 138/281] drm/amdkfd: align SDMA doorbell base for shader doorbell writes Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 140/281] drm/amdgpu: serialize vblank counter reads against GPU reset Greg Kroah-Hartman
` (148 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Haojie Li, Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haojie Li <lihaojie@kylinos.cn>
commit e6895021a328594368a2a19406a53ffca1ce51c7 upstream.
When kzalloc fails for metadata_buffer in
amdgpu_amdkfd_get_dmabuf_info(), the function returns -ENOMEM directly
without calling dma_buf_put(), leaking the dma_buf reference obtained
earlier via dma_buf_get().
Fix both issues by:
- Adding an error check after the first amdgpu_bo_get_metadata() call
- Replacing the direct return with r = -ENOMEM and goto out_put to
ensure dma_buf_put() is called on all error paths
Fixes: f54ce9e8cbd3 ("drm/amdkfd: Let driver decide buffer size at AMDKFD_IOC_GET_DMABUF_INFO ioctl")
Signed-off-by: Haojie Li <lihaojie@kylinos.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ffa699553332f8caf8688d312279ddcea9e3c141)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -597,14 +597,18 @@ int amdgpu_amdkfd_get_dmabuf_info(struct
/* first get metadata_size by buffer = NULL */
r = amdgpu_bo_get_metadata(bo, NULL, 0,
metadata_size, NULL);
+ if (r)
+ goto out_put;
/* user buf_size is bigger than bo metadata_size
* allocate a buf at kernel space and copy */
if (*metadata_size <= buffer_size) {
*metadata_buffer = kzalloc(*metadata_size, GFP_KERNEL);
- if (!*metadata_buffer)
- return -ENOMEM;
+ if (!*metadata_buffer) {
+ r = -ENOMEM;
+ goto out_put;
+ }
r = amdgpu_bo_get_metadata(bo, *metadata_buffer, *metadata_size,
NULL, &metadata_flags);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 140/281] drm/amdgpu: serialize vblank counter reads against GPU reset
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (138 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 139/281] drm/amdkfd: fix dma_buf reference leak in get_dmabuf_info Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 141/281] drm/amdgpu: make Mac FB workaround generic Greg Kroah-Hartman
` (147 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Alex Deucher,
Harry Wentland, Sunpeng Li, Vitaly Prosyak
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vitaly Prosyak <vitaly.prosyak@amd.com>
commit 1a6023edfbb5673f55fab6348f135fb3b1428ea5 upstream.
The vblank counter callback reads display registers and scanout
position without holding reset_domain->sem. During GPU recovery,
display commit work can call the callback while reset owns the
semaphore for writing. The hardware access then triggers the
lockdep_assert_held() in amdgpu_device_skip_hw_access() and sets
TAINT_WARN when lockdep is enabled.
Try to acquire the reset semaphore for reading before accessing the
hardware, and hold it across the counter and scanout-position reads.
If reset is already in progress, return DRM's cached software vblank
count instead. This avoids blocking behind reset and avoids accessing
display hardware while it is being reset.
The cached count is less accurate than the hardware count, but is
used only when reset prevents a safe hardware read. This addresses
the reset-time warning from this vblank path; it does not suppress or
fix unrelated lockdep warnings.
Cc: Christian König <christian.koenig@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Harry Wentland <harry.wentland@amd.com>
Cc: Sunpeng Li <sunpeng.li@amd.com>
Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Reviewed-by: Sunpeng Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 51a4359f7431a4be5e42803c8bdaf7e0e5be2934)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -30,6 +30,7 @@
#include <drm/amdgpu_drm.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
+#include <drm/drm_vblank.h>
#include "amdgpu_uvd.h"
#include "amdgpu_vce.h"
#include "atom.h"
@@ -1631,6 +1632,9 @@ u32 amdgpu_get_vblank_counter_kms(struct
DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
}
+ if (!down_read_trylock(&adev->reset_domain->sem))
+ return drm_crtc_vblank_count(crtc);
+
/* The hw increments its frame counter at start of vsync, not at start
* of vblank, as is required by DRM core vblank counter handling.
@@ -1676,6 +1680,7 @@ u32 amdgpu_get_vblank_counter_kms(struct
DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n");
}
+ up_read(&adev->reset_domain->sem);
return count;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 141/281] drm/amdgpu: make Mac FB workaround generic
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (139 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 140/281] drm/amdgpu: serialize vblank counter reads against GPU reset Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 142/281] drm/amdgpu: copy debugfs register data outside the GRBM/SRBM locks Greg Kroah-Hartman
` (146 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ayhan Çiçek, Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <alexander.deucher@amd.com>
commit c7f44ec5c4ec760e74351f1843dcb8322f67cbf6 upstream.
Rather than adding a case of every chip where this is seen
just check if the FB is at 0 and the ssid is apple. This
should cover all chips which fall into this case.
Tested-by: Ayhan Çiçek <ayhancicek@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit c54e4d10507722398dc90cf3c532e50b86cf425a)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -1089,20 +1089,17 @@ void amdgpu_gmc_init_vga_resv_regions(st
case CHIP_RENOIR:
adev->mman.keep_stolen_vga_memory = true;
break;
- case CHIP_POLARIS10:
- case CHIP_POLARIS11:
- case CHIP_POLARIS12:
- /* MacBookPros with switchable graphics put VRAM at 0 when
- * the iGPU is enabled which results in cursor issues if
- * the cursor ends up at 0. Reserve vram at 0 in that case.
- */
- if (adev->gmc.vram_start == 0)
- adev->mman.keep_stolen_vga_memory = true;
- break;
default:
adev->mman.keep_stolen_vga_memory = false;
break;
}
+ /* MacBookPros with switchable graphics put VRAM at 0 when
+ * the iGPU is enabled which results in cursor issues if
+ * the cursor ends up at 0. Reserve vram at 0 in that case.
+ */
+ if ((adev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
+ (adev->gmc.vram_start == 0))
+ adev->mman.keep_stolen_vga_memory = true;
if (amdgpu_sriov_vf(adev) ||
!amdgpu_device_has_display_hardware(adev)) {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 142/281] drm/amdgpu: copy debugfs register data outside the GRBM/SRBM locks
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (140 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 141/281] drm/amdgpu: make Mac FB workaround generic Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 143/281] drm/amdgpu/userq: only accept doorbell BOs as queue doorbell Greg Kroah-Hartman
` (145 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Tom St Denis,
Vitaly Prosyak, Mikhail Gavrilov, Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
commit 16c64495859f13f75602f439588883f2a4a4d6a6 upstream.
Reading or writing a register through the amdgpu_regs2 debugfs file
with GRBM bank selection, which umr does for every banked access (a
single "umr -b x x x -r <reg>" is enough, as is the wave dump with
"-O halt_waves"), makes lockdep report a circular locking dependency,
after which lockdep stays off until reboot:
WARNING: possible circular locking dependency detected
umr/63306 is trying to acquire lock:
ffff8882cf4b8350 (&mm->mmap_lock){++++}-{4:4}, at: __might_fault+0x9b/0x140
but task is already holding lock:
ffff8881aec010d0 (&amdgpu_grbm_lock_key){+.+.}-{4:4}, at: amdgpu_debugfs_regs2_op.isra.0+0x20d/0xd00 [amdgpu]
...
Chain exists of:
&mm->mmap_lock --> &amdgpu_srbm_lock_key --> &amdgpu_grbm_lock_key
...
__might_fault+0xc5/0x140
amdgpu_debugfs_regs2_op.isra.0+0x441/0xd00 [amdgpu]
full_proxy_write+0x10e/0x1d0
vfs_write+0x1d0/0xf50
ksys_write+0x116/0x250
amdgpu_debugfs_regs2_op() and amdgpu_debugfs_process_reg_op() call
get_user()/put_user() for every dword while holding grbm_idx_mutex or
srbm_mutex, and pm.mutex if requested, so a fault there takes mmap_lock
inside those locks. The lock hierarchy in amdgpu_lockdep.c puts
srbm_mutex and grbm_idx_mutex below notifier_lock, which
amdgpu_cs_submit() takes with the BO reservations held, and
dma_resv_lockdep() orders the reservations inside mmap_lock. So
mmap_lock is outside grbm_idx_mutex and srbm_mutex, and these two
debugfs paths nest it the other way round. The copies under the locks
are as old as the bank selection in both files; commit 1d0f5838b126
("drm/amdgpu: Add lockdep annotations for lock ordering validation")
only made them visible to lockdep.
Copy the user buffer in before any of the locks is taken and the result
out after all of them are dropped, as amdgpu_debugfs_wave_read(),
amdgpu_debugfs_gpr_read() and amdgpu_debugfs_gprwave_read() already do.
The buffer is sized by the count passed to read() or write(), so an
access larger than PAGE_SIZE is now rejected with -EINVAL; umr reads and
writes one register at a time. A fault on the user buffer of a write now
fails with -EFAULT before any register is written, instead of after a
partial write.
Fixes: 566281595037 ("drm/amd/amdgpu: Add bank selection for MMIO debugfs (v3)")
Fixes: 37df9560cd3e ("drm/amd/amdgpu: New debugfs interface for MMIO registers (v5)")
Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Tom St Denis <tom.stdenis@amd.com>
Reviewed-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ccf9e35ed6811f2c25ba6368e7dc6481da17159d)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 77 ++++++++++++++++------------
1 file changed, 46 insertions(+), 31 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -120,6 +120,20 @@ static int amdgpu_debugfs_process_reg_o
*pos &= (1UL << 22) - 1;
+ if (size > PAGE_SIZE)
+ return -EINVAL;
+
+ /*
+ * Access the user buffer only while none of the locks below are held:
+ * a fault takes mmap_lock, and grbm_idx_mutex and srbm_mutex nest
+ * inside it.
+ */
+ u32 *data __free(kfree) = kmalloc(size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ if (!read && copy_from_user(data, buf, size))
+ return -EFAULT;
+
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -151,28 +165,16 @@ static int amdgpu_debugfs_process_reg_o
mutex_lock(&adev->pm.mutex);
while (size) {
- uint32_t value;
-
- if (read) {
- value = RREG32(*pos >> 2);
- r = put_user(value, (uint32_t *)buf);
- } else {
- r = get_user(value, (uint32_t *)buf);
- if (!r)
- amdgpu_mm_wreg_mmio_rlc(adev, *pos >> 2, value, 0);
- }
- if (r) {
- result = r;
- goto end;
- }
+ if (read)
+ data[result >> 2] = RREG32(*pos >> 2);
+ else
+ amdgpu_mm_wreg_mmio_rlc(adev, *pos >> 2, data[result >> 2], 0);
result += 4;
- buf += 4;
*pos += 4;
size -= 4;
}
-end:
if (use_bank) {
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, 0);
mutex_unlock(&adev->grbm_idx_mutex);
@@ -187,6 +189,10 @@ end:
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
amdgpu_virt_disable_access_debugfs(adev);
+
+ if (read && copy_to_user(buf, data, result))
+ return -EFAULT;
+
return result;
}
@@ -237,11 +243,24 @@ static ssize_t amdgpu_debugfs_regs2_op(s
struct amdgpu_device *adev = rd->adev;
ssize_t result = 0;
int r;
- uint32_t value;
if (size & 0x3 || offset & 0x3)
return -EINVAL;
+ if (size > PAGE_SIZE)
+ return -EINVAL;
+
+ /*
+ * Access the user buffer only while none of the locks below are held:
+ * a fault takes mmap_lock, and grbm_idx_mutex and srbm_mutex nest
+ * inside it.
+ */
+ u32 *data __free(kfree) = kmalloc(size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ if (write_en && copy_from_user(data, buf, size))
+ return -EFAULT;
+
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -280,24 +299,16 @@ static ssize_t amdgpu_debugfs_regs2_op(s
mutex_lock(&adev->pm.mutex);
while (size) {
- if (!write_en) {
- value = RREG32(offset >> 2);
- r = put_user(value, (uint32_t *)buf);
- } else {
- r = get_user(value, (uint32_t *)buf);
- if (!r)
- amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, value, rd->id.xcc_id);
- }
- if (r) {
- result = r;
- goto end;
- }
+ if (!write_en)
+ data[result >> 2] = RREG32(offset >> 2);
+ else
+ amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, data[result >> 2],
+ rd->id.xcc_id);
offset += 4;
size -= 4;
result += 4;
- buf += 4;
}
-end:
+
if (rd->id.use_grbm) {
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, rd->id.xcc_id);
mutex_unlock(&adev->grbm_idx_mutex);
@@ -316,6 +327,10 @@ end:
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
amdgpu_virt_disable_access_debugfs(adev);
+
+ if (!write_en && copy_to_user(buf, data, result))
+ return -EFAULT;
+
return result;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 143/281] drm/amdgpu/userq: only accept doorbell BOs as queue doorbell
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (141 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 142/281] drm/amdgpu: copy debugfs register data outside the GRBM/SRBM locks Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 144/281] drm/amdgpu/userq: return the memdup_user() error for the user MQD Greg Kroah-Hartman
` (144 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Jesse Zhang,
Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
commit 7f7c88dbf4d543f6703e53bdeed380e886733167 upstream.
amdgpu_userq_get_doorbell_index() pins any BO passed as doorbell_handle
into the doorbell domain. For a regular BO, TTM moves it with
ttm_bo_move_null() and its contents are lost. Since an importer on the
same device gets the exporter's GEM object, a client can do this to a
buffer another client shared with it.
Reject BOs that were not created in the doorbell domain.
v2: drop the error message, use a local abo variable (Christian)
Fixes: f09c1e6077ab ("drm/amdgpu: generate doorbell index for userqueue")
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit f7497bbc19db4821c62b9d97b31c9086feb2d917)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -439,6 +439,7 @@ amdgpu_userq_get_doorbell_index(struct a
u64 doorbell_index;
struct drm_gem_object *gobj;
struct amdgpu_userq_obj *db_obj = db_info->db_obj;
+ struct amdgpu_bo *abo;
int r, db_size;
gobj = drm_gem_object_lookup(filp, db_info->doorbell_handle);
@@ -447,7 +448,17 @@ amdgpu_userq_get_doorbell_index(struct a
return -EINVAL;
}
- db_obj->obj = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
+ /*
+ * Pinning a regular BO into the doorbell domain would discard its
+ * contents, possibly those of a buffer shared by another client.
+ */
+ abo = gem_to_amdgpu_bo(gobj);
+ if (!(abo->preferred_domains & AMDGPU_GEM_DOMAIN_DOORBELL)) {
+ drm_gem_object_put(gobj);
+ return -EINVAL;
+ }
+
+ db_obj->obj = amdgpu_bo_ref(abo);
drm_gem_object_put(gobj);
r = amdgpu_bo_reserve(db_obj->obj, true);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 144/281] drm/amdgpu/userq: return the memdup_user() error for the user MQD
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (142 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 143/281] drm/amdgpu/userq: only accept doorbell BOs as queue doorbell Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 145/281] drm/amd/display: Fix direct scanout alpha on some DRM_FORMATs Greg Kroah-Hartman
` (143 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Jesse Zhang,
Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
commit 76ceb6ed610cbf14341a9ba78c5c0b2199b9030a upstream.
mes_userq_mqd_create() returns -ENOMEM when copying the user MQD fails,
even though memdup_user() returns -EFAULT for a bad pointer or -EINTR
when interrupted by a signal. Return PTR_ERR() instead.
While at it drop the error messages. Neither case is a driver error and
userspace shouldn't be able to spam the log with invalid IOCTL
parameters.
v2: drop the error messages (Christian)
Fixes: 2c695d7c0720 ("drm/amdgpu: enable compute/gfx usermode queue")
Fixes: 543b61453774 ("drm/amdgpu: enable SDMA usermode queues")
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 49a443fcb829be9fc780f10850652ddea2fe81f0)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -304,8 +304,7 @@ static int mes_userq_mqd_create(struct a
compute_mqd = memdup_user(u64_to_user_ptr(mqd_user->mqd), mqd_user->mqd_size);
if (IS_ERR(compute_mqd)) {
- DRM_ERROR("Failed to read user MQD\n");
- r = -ENOMEM;
+ r = PTR_ERR(compute_mqd);
goto free_mqd;
}
@@ -349,8 +348,7 @@ static int mes_userq_mqd_create(struct a
mqd_gfx_v11 = memdup_user(u64_to_user_ptr(mqd_user->mqd), mqd_user->mqd_size);
if (IS_ERR(mqd_gfx_v11)) {
- DRM_ERROR("Failed to read user MQD\n");
- r = -ENOMEM;
+ r = PTR_ERR(mqd_gfx_v11);
goto free_mqd;
}
@@ -394,8 +392,7 @@ static int mes_userq_mqd_create(struct a
mqd_sdma_v11 = memdup_user(u64_to_user_ptr(mqd_user->mqd), mqd_user->mqd_size);
if (IS_ERR(mqd_sdma_v11)) {
- DRM_ERROR("Failed to read sdma user MQD\n");
- r = -ENOMEM;
+ r = PTR_ERR(mqd_sdma_v11);
goto free_mqd;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 145/281] drm/amd/display: Fix direct scanout alpha on some DRM_FORMATs
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (143 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 144/281] drm/amdgpu/userq: return the memdup_user() error for the user MQD Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 146/281] drm/amd/display: disable self-refresh on tearing flips Greg Kroah-Hartman
` (142 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Leo Li, Harry Wentland, Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Li <sunpeng.li@amd.com>
commit 7744262f5d63f9faa4d59dec127ae1c8b2d56495 upstream.
[Why]
DM was declaring it's own list of has_alpha DRM formats to check against
for enabling alpha blending, when the format->has_alpha already does
that for us.
The self-declared list missed some has_alpha formats, causing
direct-scanout planes with such formats to appear opaque.
[How]
Drop the self-declared list, instead use the format->has_alpha field
directly.
Signed-off-by: Leo Li <sunpeng.li@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 9ecdac91ed43d836683d5daa467f4907405420e2)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 20 ----------------
1 file changed, 1 insertion(+), 19 deletions(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -110,25 +110,7 @@ void amdgpu_dm_plane_fill_blending_from_
if (plane_state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI ||
plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE) {
- static const uint32_t alpha_formats[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGBA8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_ARGB2101010,
- DRM_FORMAT_ABGR2101010,
- DRM_FORMAT_ARGB16161616,
- DRM_FORMAT_ABGR16161616,
- DRM_FORMAT_ARGB16161616F,
- };
- uint32_t format = plane_state->fb->format->format;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(alpha_formats); ++i) {
- if (format == alpha_formats[i]) {
- *per_pixel_alpha = true;
- break;
- }
- }
+ *per_pixel_alpha = plane_state->fb->format->has_alpha;
if (*per_pixel_alpha && plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE)
*pre_multiplied_alpha = false;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 146/281] drm/amd/display: disable self-refresh on tearing flips
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (144 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 145/281] drm/amd/display: Fix direct scanout alpha on some DRM_FORMATs Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 147/281] mount: keep a copied mount unbindable Greg Kroah-Hartman
` (141 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Timur Kristóf, Harry Wentland,
Leo Li, Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Li <sunpeng.li@amd.com>
commit 2e54a92e0136c3ff5c7b542b95bf0940ad6687bf upstream.
[Why & How]
Immediate (tearing) flips breaks self refresh state machine assumptions,
so disable PSR/Replay for them.
Tested-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit acbdd213b37e095f15685f3e3ee6d35defa05616)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10397,6 +10397,13 @@ static void amdgpu_dm_enable_self_refres
struct amdgpu_dm_connector *aconn =
(struct amdgpu_dm_connector *)acrtc_state->stream->dm_stream_context;
+ if (!acrtc_state->base.async_flip) {
+ amdgpu_dm_psr_set_event(dm, acrtc_state->stream, false,
+ psr_event_immediate_flip, false);
+ amdgpu_dm_replay_set_event(dm, acrtc_state->stream, false,
+ replay_event_immediate_flip, false);
+ }
+
/* Decrement skip count when SR is enabled and we're doing fast updates. */
if (acrtc_state->update_type == UPDATE_TYPE_FAST &&
(psr->psr_feature_enabled || pr->replay_feature_enabled)) {
@@ -10810,6 +10817,18 @@ static void amdgpu_dm_commit_planes(stru
spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
}
mutex_lock(&dm->dc_lock);
+ /*
+ * Tearing (immediate) flips cannot work with panel self-refresh
+ * features. The event is cleared by
+ * amdgpu_dm_enable_self_refresh() once async flips stop.
+ */
+ if (immediate_flip) {
+ dc_exit_ips_for_hw_access(dm->dc);
+ amdgpu_dm_psr_set_event(dm, acrtc_state->stream, true,
+ psr_event_immediate_flip, true);
+ amdgpu_dm_replay_set_event(dm, acrtc_state->stream, true,
+ replay_event_immediate_flip, true);
+ }
update_planes_and_stream_adapter(dm->dc,
acrtc_state->update_type,
planes_count,
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 147/281] mount: keep a copied mount unbindable
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (145 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 146/281] drm/amd/display: disable self-refresh on tearing flips Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 148/281] fs: dont silently unmount busy mounts Greg Kroah-Hartman
` (140 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 1ab8904ae61b076d1242e1f48537698c77074b5c upstream.
It's groundhog day.
MNT_UNBINDABLE used to be set in in mnt->mnt.mnt_flags and was not part
of MNT_INTERNAL_FLAGS. clone_mnt() copied it with all the other flags to
the new mount. This guaranteed that the copy of an unbindable mount
became unbindable as well. Unbindable copies that ended up as shared
lost the unbindable property.
But then commit 406fea799925 ("mount: separate the flags accessed only
under namespace_sem") moved MNT_UNBINDABLE from mnt->mnt.mnt_flags into
mnt->mnt_t_flags as T_UNBINDABLE.
clone_mnt() doesn't copy from mnt_t_flags and specifically doesn't copy
T_UNBINDABLE. The only place a mount gets marked unbindable is in
change_mnt_propagation() for MS_UNBINDABLE.
This reintroduced an earlier bug we had already fixed. It resurfaces in
copy_mnt_ns() which clones unbindable mounts via CL_COPY_UNBINDABLE. So
since v6.17 a mount namespace created via clone(CLONE_NEWNS) or
unshare(CLONE_NEWNS) contain private and bindable copies of every
unbindable mount. The following snippet:
mount --make-unbindable /mnt
unshare -m --propagation unchanged
mount --bind /mnt /tmp/x
succeeds. This used to fail with EINVAL. This also applies to
recursively binding a tree that contains an unbindable the mount. Such
subtrees used to be pruned when they were moved onto a shared mount.
And Documentation/filesystems/sharedsubtree.rst still says that the copy
of an unbindable mount is unbindable.
So once again let's fix this. Copy T_UNBINDABLE in clone_mnt(). Let
set_mnt_shared() mask it off whenever a mount is made shared.
This restores what the old MNT_INTERNAL_FLAGS mask did.
Link: https://patch.msgid.link/20260923-work-mount-fixes-v1-1-f424cf8d3242@kernel.org
Fixes: 406fea799925 ("mount: separate the flags accessed only under namespace_sem")
Cc: stable@vger.kernel.org # v6.17+
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1254,6 +1254,7 @@ static struct mount *clone_mnt(struct mo
mnt->mnt.mnt_flags = READ_ONCE(old->mnt.mnt_flags) &
~MNT_INTERNAL_FLAGS;
+ mnt->mnt_t_flags = old->mnt_t_flags & T_UNBINDABLE;
if (flag & (CL_SLAVE | CL_PRIVATE))
mnt->mnt_group_id = 0; /* not a peer of original */
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 148/281] fs: dont silently unmount busy mounts
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (146 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 147/281] mount: keep a copied mount unbindable Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 149/281] namespace: reset the old parents ->overmount in mnt_change_mountpoint() Greg Kroah-Hartman
` (139 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 6857e209015f95be7a8f19a9cd5dac345b9b9859 upstream.
The propagate_mount_busy() helper exists to decide whether a synchronous
can suceed. It does that by looking at the copies of the victims in the
mounts its parent propagates to. One of those functions from propagation
hell.
It skips a copy that has child mounts except for the case of a single
child mount covering the copy's root. That algorithm used to be exact.
It isn't anymore.
Originally only childless copies were unmounted during propagation.
And 1064f874abc0 ("mnt: Tuck mounts under others instead of creating
shadow/side mounts.") ended up adding covered mounts to both sides in
one go.
Along came 99b19d16471e ("mnt: In propgate_umount handle visiting mounts
in any order") and that started to unmount more than before:
[1]: A copy of a mount is unmounted when each of its children is either
its overmount or a copy of the victim itself. In the former case
the overmount gets reparented. In the latter case the copy of the
victim will end up being unmounted.
So propagate_umount() ended up being rewritten without adjusting
propagate_mount_busy(). And currently propagate_mount_busy() doesn't
look at copies of the victim that have two or more children nor a single
child that is not the overmount.
So any such copy in [1] is not checked for
references. The result is that a synchronous unmount succeeds, pulling
out a mount that is still in use.
A container can run into this with its own mounts. The host shares a
tree with the container and the host has a mount in that tree:
mount -t tmpfs none /mnt
mount --make-shared /mnt
mount -t tmpfs none /mnt/a
The container's /mnt is a slave copy of the host mount. The container
now takes a detached copy of the tree and mounts that copy beneath its
propagated copy of /mnt/a and keeps the file descriptor to the tree
open:
unshare -m --propagation unchanged
mount --make-rslave /
fd = open_tree(AT_FDCWD, "/mnt", OPEN_TREE_CLONE | AT_RECURSIVE)
move_mount(fd, "", AT_FDCWD, "/mnt/a", MOVE_MOUNT_BENEATH)
grep /mnt /proc/self/mountinfo
775 355 ... /mnt ... master:646
777 775 ... /mnt/a ... master:646
776 777 ... /mnt/a ... master:647
778 777 ... /mnt/a/a ... master:647
The now attached tree (777) is now mounted beneath the container's copy
of /mnt/a. That's also where the host mount sits (as seen from the host
mount namespace). So the propagated copy (776) of the host's mount is on
top of its root and the copy of that (778) is inside it. Now the host
runs:
umount /mnt/a
and it succeeds. The moved tree tree and the copy inside of it are gone
from the container. Now only the propagated copy is left and it got
reparented to where it was before:
grep /mnt /proc/self/mountinfo
775 355 ... /mnt ... master:646
776 775 ... /mnt/a ...
But the file descriptor still refers to the moved tree. So a synchronous
umount detached a mount that is still in use.
Teach propagate_mount_busy() the same checks that propagate_umount()
does. It now checks for a single victim mount without children
for which it can assume that MNT_LOCKED is cleared on every copy like
propagate_umount() does. The copies form chains. IOW, when a copy itself
receives propagation from the victim's parent then the mount at the same
mountpoint inside that copy is a copy as well. Whether a mount receives
propagation from the victim's can simply be checked by walking its
masters. Walk each chain once from its top so we are sure that nested
copies stay linear. Check every reference once of every copy that gets
unmounted.
Link: https://patch.msgid.link/20260923-work-mount-fixes-v1-5-f424cf8d3242@kernel.org
Fixes: 99b19d16471e ("mnt: In propgate_umount handle visiting mounts in any order")
Cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/pnode.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 91 insertions(+), 19 deletions(-)
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -410,19 +410,99 @@ bool propagation_would_overmount(const s
return false;
}
+/* Does @m receive propagation from @parent? */
+static bool receives_from(struct mount *m, struct mount *parent)
+{
+ if (m == parent)
+ return false;
+ for (; m; m = m->mnt_master)
+ if (m == parent || peers(m, parent))
+ return true;
+ return false;
+}
+
+/*
+ * Does @m receive propagation from the victim's parent as well? If so, then
+ * the mount at the victim's mountpoint inside of @m is a umount candidate as
+ * well. So it's the next candidate in the chain. Otherwise the chain ends at
+ * @m.
+ */
+static struct mount *next_candidate(struct mount *m, struct mount *victim)
+{
+ if (!receives_from(m, victim->mnt_parent))
+ return NULL;
+ return __lookup_mnt(&m->mnt, victim->mnt_mountpoint);
+}
+
+/*
+ * Would propagate_umount() pull out a mount of the chain of candidates that
+ * starts at @c, and does that mount have references beyond its own?
+ *
+ * This mirrors how trim_one(), trim_ancestors() and handle_locked() handle a
+ * synchronous umount:
+ *
+ * - single victim
+ * - without children
+ * - with MNT_LOCKED already cleared on every candidate by propagate_mount_unlock()
+ *
+ * A copy of the victim gets unmounted when each of its children is
+ * the next candidate in the chain or its overmount, unless the next
+ * unmount candidate is not its overmount and some unmount candidate further
+ * down has a child outside the chain. Keep this in sync with
+ * Documentation/filesystems/propagate_umount.txt.
+ */
+static bool chain_busy(struct mount *c, struct mount *victim)
+{
+ struct mount *m, *n, *next, *deepest = NULL;
+ bool above;
+
+ /* the deepest candidate with a child outside the chain */
+ for (m = c; m; m = next) {
+ next = next_candidate(m, victim);
+ list_for_each_entry(n, &m->mnt_mounts, mnt_child) {
+ if (n != next && n != victim) {
+ deepest = m;
+ break;
+ }
+ }
+ }
+
+ above = deepest != NULL; /* @deepest is at or below @m */
+ for (m = c; m; m = next) {
+ bool goes = true;
+
+ next = next_candidate(m, victim);
+ list_for_each_entry(n, &m->mnt_mounts, mnt_child) {
+ if (n != next && n != m->overmount && n != victim) {
+ goes = false;
+ break;
+ }
+ }
+ if (goes && next && next != m->overmount && above && m != deepest)
+ goes = false;
+ if (m == deepest)
+ above = false;
+ if (goes && do_refcount_check(m, 1))
+ return true;
+ }
+ return false;
+}
+
/*
* check if the mount 'mnt' can be unmounted successfully.
* @mnt: the mount to be checked for unmount
* NOTE: unmounting 'mnt' would naturally propagate to all
* other mounts its parent propagates to.
- * Check if any of these mounts that **do not have submounts**
- * have more references than 'refcnt'. If so return busy.
+ * Check if any of the mounts that propagate_umount() would pull out
+ * along with it have more references than their own. If so return busy.
*
* vfsmount lock must be held for write
*/
int propagate_mount_busy(struct mount *mnt, int refcnt)
{
struct mount *parent = mnt->mnt_parent;
+ struct dentry *mp = mnt->mnt_mountpoint;
+ struct mount *m;
/*
* quickly check if the current mount can be unmounted.
@@ -435,24 +515,16 @@ int propagate_mount_busy(struct mount *m
if (mnt == parent)
return 0;
- for (struct mount *m = propagation_next(parent, parent); m;
- m = propagation_next(m, parent)) {
- struct list_head *head;
- struct mount *child = __lookup_mnt(&m->mnt, mnt->mnt_mountpoint);
-
- if (!child)
+ /* the candidates are the mounts at @mp below the receivers */
+ for (m = propagation_next(parent, parent); m;
+ m = propagation_next(m, parent)) {
+ struct mount *c = __lookup_mnt(&m->mnt, mp);
+
+ /* each chain once, from its top: skip receivers that are candidates */
+ if (!c || (mnt_has_parent(m) && m->mnt_mountpoint == mp &&
+ receives_from(m->mnt_parent, parent)))
continue;
-
- head = &child->mnt_mounts;
- if (!list_empty(head)) {
- /*
- * a mount that covers child completely wouldn't prevent
- * it being pulled out; any other would.
- */
- if (!list_is_singular(head) || !child->overmount)
- continue;
- }
- if (do_refcount_check(child, 1))
+ if (chain_busy(c, mnt))
return 1;
}
return 0;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 149/281] namespace: reset the old parents ->overmount in mnt_change_mountpoint()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (147 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 148/281] fs: dont silently unmount busy mounts Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 150/281] statmount: read the parent of an unmounted mount under mount_lock Greg Kroah-Hartman
` (138 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 476ef286a7a5db8bda51325dc0c45887b4d99d9a upstream.
__umount_mnt() resets ->overmount of the parent when it unmounts the
mount that overmounts it. mnt_change_mountpoint() doesn't. It moves the
mount to its new parent and leaves the old one pointing at it.
For a mount that is moved beneath in attach_recursive_mnt() that doesn't
matter. The new mount has already reset ->overmount of the old parent by
the time the old top mount is moved onto it.
It matters for reparent() though. propagate_umount() moves a surviving
overmount onto the first ancestor that isn't going to be unmounted. The
mount it was taken from is unmounted immediately afterwards. If a file
descriptor keeps that unmounted mount alive ->overmount points at the
moved mount. That's a dangling pointer and UAF as the moved mount is
unmounted and freed.
do_lock_mount() follows ->overmount from the target path under
mount_lock. With a file descriptor on such a mount as the target of a
mount beneath topmost_overmount() walks into the freed mount and
do_lock_mount() takes references on whatever it finds there.
So reset ->overmount of the old parent in mnt_change_mountpoint() the
same way __umount_mnt() does. A mount's ->overmount is then always a
mount that is attached to it.
Fixes: ffdc52fbbd58 ("prevent mount hash conflicts")
Cc: stable@vger.kernel.org # v6.17+
Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-1-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 3 +++
1 file changed, 3 insertions(+)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1058,7 +1058,10 @@ static void attach_mnt(struct mount *mnt
void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp, struct mount *mnt)
{
struct mountpoint *old_mp = mnt->mnt_mp;
+ struct mount *old_parent = mnt->mnt_parent;
+ if (old_parent->overmount == mnt)
+ old_parent->overmount = NULL;
list_del_init(&mnt->mnt_child);
hlist_del_init(&mnt->mnt_mp_list);
hlist_del_init_rcu(&mnt->mnt_hash);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 150/281] statmount: read the parent of an unmounted mount under mount_lock
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (148 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 149/281] namespace: reset the old parents ->overmount in mnt_change_mountpoint() Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 151/281] namespace: dont inherit MNT_UMOUNT in clone_mnt() Greg Kroah-Hartman
` (137 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit bb46094057520304073130920c223451c2a694a7 upstream.
statmount_mnt_basic() reads the ids of the parent through m->mnt_parent
with namespace_sem held for reading. That's fine for a mount that is
in a namespace. Everything above it is pinned by that namespace.
STATMOUNT_BY_FD also accepts a file descriptor on a mount that has
been unmounted on purpose and that only the file descriptor keeps alive.
If that mount stayed attached to its parent when it was unmounted the
parent is unmounted as well and nothing pins it for the child.
The final mntput() unmounts the children under mount_lock alone and
frees the parent afterwards. Concurrently, statmount_mnt_basic() reads
m->mnt_parent twice while that can happen and can easily dereference a
mount that's already gone.
Read the parent of an unmounted mount under mount_lock. The parent
can't be put while it is held and both ids come from the same mount. A
mounted mount's parent is pinned by the namespace and a mount can't
leave its namespace while namespace_sem is held, so the common case
takes no global lock.
Fixes: 0e5032237ee5 ("statmount: accept fd as a parameter")
Cc: stable@vger.kernel.org # v7.0+
Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-2-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -5316,15 +5316,25 @@ static void statmount_sb_basic(struct ks
s->sm.sb_flags = sb->s_flags & (SB_RDONLY|SB_SYNCHRONOUS|SB_DIRSYNC|SB_LAZYTIME);
}
+static void statmount_mnt_parent(struct kstatmount *s, const struct mount *m)
+{
+ s->sm.mnt_parent_id = m->mnt_parent->mnt_id_unique;
+ s->sm.mnt_parent_id_old = m->mnt_parent->mnt_id;
+}
+
static void statmount_mnt_basic(struct kstatmount *s)
{
struct mount *m = real_mount(s->mnt);
s->sm.mask |= STATMOUNT_MNT_BASIC;
s->sm.mnt_id = m->mnt_id_unique;
- s->sm.mnt_parent_id = m->mnt_parent->mnt_id_unique;
s->sm.mnt_id_old = m->mnt_id;
- s->sm.mnt_parent_id_old = m->mnt_parent->mnt_id;
+ /* An unmounted mount is cut loose from its parent under mount_lock alone. */
+ if (likely(is_mounted(s->mnt)))
+ statmount_mnt_parent(s, m);
+ else
+ scoped_guard(mount_locked_reader)
+ statmount_mnt_parent(s, m);
s->sm.mnt_attr = mnt_to_attr_flags(&m->mnt);
s->sm.mnt_propagation = mnt_to_propagation_flags(m);
s->sm.mnt_peer_group = m->mnt_group_id;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 151/281] namespace: dont inherit MNT_UMOUNT in clone_mnt()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (149 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 150/281] statmount: read the parent of an unmounted mount under mount_lock Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 152/281] namespace: dont copy an unmounted mount tree Greg Kroah-Hartman
` (136 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit e2c6d326216642011da318b9edfd5d57ebd5a56f upstream.
MNT_UMOUNT gets raised on a mount that umount_tree() or umount_one() has
taken out of its namespace. It's never cleared. __detach_mounts()
unhooks a mount that carries it instead of unmounting it.
disconnect_mount() lets an unmounted child stay attached only if its
parent carries it. propagate_umount() takes it as the sign that a mount
is going to be unmounted when it decides what else can be unmounted,
where a chain of locked mounts ends and where a for reparenting an
overmount.
clone_mnt() copies the flags of the source and only masks
MNT_INTERNAL_FLAGS which doesn't include MNT_UMOUNT. A mount that was
lazily unmounted but is kept alive by a file descriptor can still be
copied when its root is an nsfs or pidfs file because may_copy_tree()
accepts those before checking whether the source is mounted at all:
mount --bind /proc/self/ns/net /tmp/x
exec 3< /tmp/x
umount -l /tmp/x
mount --bind /proc/self/fd/3 /tmp/y
The mount on /tmp/y is attached to the caller's namespace with
MNT_UMOUNT already set and every copy of it inherits the flag again.
That causes a number of bugs:
- Unlink its mountpoint from a mount namespace where it isn't one.
__detach_mounts() takes it for a mount that was unmounted earlier,
unhooks it from its parent and drops the reference the namespace
holds on it. It stays in the namespace with one reference too few
and as its own parent, so it can't be unmounted through the file
descriptor anymore and the namespace never finds it again. When the
namespace goes away it's leaked and points to a freed struct
mnt_namespace that may_change_propagation() and anon_ns_root() read
on the next propagation change or mount_setattr() through the file
descriptor.
- Make it shared and unmount a peer. trace_transfers() follows the
flag from the peer into it and strips it from its peer group.
- Let a propagated umount reach it. gather_candidates() marks it with
T_UMOUNT_CANDIDATE but never puts it on the candidate list, so the
mark is never cleared and every later propagated umount skips it. If
it's the parent of a locked mount handle_locked() takes it as the
cutoff and commits the locked child that should have stayed and
disconnect_mount() leaves that child attached to it, unmounted under
a mounted parent, which is what disconnect_mount() exists to
prevent. When the namespace goes away umount_tree() visits the child
a second time. And once __detach_mounts() has made it its own parent
reparent() never finds the end of the chain of unmounted parents.
A clone is a new mount that has never been unmounted. Add MNT_UMOUNT
to MNT_INTERNAL_FLAGS so clone_mnt() never copies it. And warn when
umount_tree() reaches a mount that already has it set.
Fixes: 590ce4bcbfb4 ("mnt: Add MNT_UMOUNT flag")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-3-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 2 ++
include/linux/mount.h | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1787,6 +1787,8 @@ static void umount_tree(struct mount *mn
/* Gather the mounts to umount */
for (p = mnt; p; p = next_mnt(p, mnt)) {
+ /* A mount is unmounted once. */
+ VFS_WARN_ON_ONCE(p->mnt.mnt_flags & MNT_UMOUNT);
p->mnt.mnt_flags |= MNT_UMOUNT;
if (mnt_ns_attached(p))
move_from_ns(p);
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -52,7 +52,7 @@ enum mount_flags {
MNT_ATIME_MASK = MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME,
MNT_INTERNAL_FLAGS = MNT_INTERNAL | MNT_DOOMED |
- MNT_SYNC_UMOUNT | MNT_LOCKED
+ MNT_SYNC_UMOUNT | MNT_LOCKED | MNT_UMOUNT
};
struct vfsmount {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 152/281] namespace: dont copy an unmounted mount tree
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (150 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 151/281] namespace: dont inherit MNT_UMOUNT in clone_mnt() Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 153/281] fs: refuse fspick() on internal superblocks Greg Kroah-Hartman
` (135 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 8bacbf6be959973b28b691713a872c12eae69eec upstream.
may_copy_tree() accepts a mount whose root is an nsfs or pidfs file
before it checks whether that mount is mounted. This exception exists
for nsfs and pidfs mounts. They are part of no mount namespace so
neither check_mnt() nor is_mounted() would let them through and
bind-mounting a nsfsfd or a pidfd wouldn't work.
Problem is that exception also admits a bind mount of such a file when
it was lazily unmounted and is only kept alive by a file descriptor:
mount --bind /proc/self/ns/net /tmp/x
exec 3< /tmp/x
umount -l /tmp/x
mount --rbind /proc/self/fd/3 /tmp/y
With MS_REC or AT_RECURSIVE copy_tree() doesn't stop at the unmounted
mount. It copies every mount that stayed attached to it as well. So if
you have a bunch of overmounts over the nsfsfd or the pidfd the whole
unmounted stack is copied. That's a bug.
So refuse to walk an unmounted tree. Copying its root alone stays
possible. So a bind mount of a namespace that is gone can still be
recreated from a file descriptor on the old one. The file descriptor
pins that mount and its root and __has_locked_children() only reads the
direct children which don't leave the parent's list without
namespace_sem. The internal mounts carry MNT_NS_INTERNAL instead of NULL
and are still walked. Copying an unmounted tree recursively fails with
EINVAL.
Fixes: e149ed2b805f ("take the targets of /proc/*/ns/* symlinks to separate fs")
Fixes: ef4144ac2dec ("pidfs: allow bind-mounts")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-4-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 3 +++
1 file changed, 3 insertions(+)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2992,6 +2992,9 @@ static struct mount *__do_loopback(const
if (!may_copy_tree(old_path))
return ERR_PTR(-EINVAL);
+ if (recurse && !old->mnt_ns)
+ return ERR_PTR(-EINVAL);
+
if (!recurse && __has_locked_children(old, old_path->dentry))
return ERR_PTR(-EINVAL);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 153/281] fs: refuse fspick() on internal superblocks
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (151 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 152/281] namespace: dont copy an unmounted mount tree Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 154/281] namespace: check the target before walking it in do_mount_setattr() Greg Kroah-Hartman
` (134 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 02587a4af82adccaef8e3b3624b4e7f1c401632d upstream.
There's a few instances where a internal superblock is reachable by
fspick(). Block that. graft_tree() and fsmount() already refuse them.
fanotify refuses mount and superblock marks on them for the same reason.
Fixes: cf3cba4a429b ("vfs: syscall: Add fspick() to select a superblock for reconfiguration")
Cc: stable@vger.kernel.org # v5.2+
Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-6-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/fsopen.c | 3 +++
1 file changed, 3 insertions(+)
--- a/fs/fsopen.c
+++ b/fs/fsopen.c
@@ -190,6 +190,9 @@ SYSCALL_DEFINE3(fspick, int, dfd, const
ret = -EINVAL;
if (target.mnt->mnt_root != target.dentry)
goto err_path;
+ /* kernel-internal superblocks are nobody's to reconfigure */
+ if (target.dentry->d_sb->s_flags & SB_NOUSER)
+ goto err_path;
fc = fs_context_for_reconfigure(target.dentry, 0, 0);
if (IS_ERR(fc)) {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 154/281] namespace: check the target before walking it in do_mount_setattr()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (152 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 153/281] fs: refuse fspick() on internal superblocks Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 155/281] namespace: queue a mount only once for mount notifications Greg Kroah-Hartman
` (133 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 08f4288a37ef4b3d19b4a9599ec3048219cac828 upstream.
When mount_setattr() changes the propagation type to MS_SHARED
do_mount_setattr() takes namespace_sem and calls invent_group_ids()
which walks the whole target tree with next_mnt() and allocates a peer
group id for every mount that doesn't have one.
Whether the caller may touch the target at all is only checked
afterwards under mount_lock. If it may not, cleanup_group_ids() walks
the tree a second time on the way out to free the ids again.
A detached tree that a file descriptor keeps alive, a mount in another
mount namespace or a mount below the root of an anonymous mount
namespace does a bunch of allocation work that is completely useless
because it will fail and revert right after.
Do the right thing and check the target right after taking namespace_sem
instead. A mount leaves its namespace only under namespace_sem so the
mount stays stable. The check under mount_lock stays for the case where
no propagation change is requested and namespace_sem isn't taken.
Callers get the same EINVAL as before.
Fixes: 2a1867219c7b ("fs: add mount_setattr()")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260926-work-mount-fixes-2-v1-5-f357abf3d17b@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -4957,6 +4957,11 @@ static int do_mount_setattr(const struct
* propagation.
*/
namespace_lock();
+ /* invent_group_ids() walks the tree, only walk a mounted one */
+ if (!anon_ns_root(mnt) && !check_mnt(mnt)) {
+ namespace_unlock();
+ return -EINVAL;
+ }
if (kattr->propagation == MS_SHARED) {
err = invent_group_ids(mnt, kattr->kflags & MOUNT_KATTR_RECURSE);
if (err) {
@@ -4969,6 +4974,7 @@ static int do_mount_setattr(const struct
err = -EINVAL;
lock_mount_hash();
+ /* Checked under namespace_sem already if the propagation changes. */
if (!anon_ns_root(mnt) && !check_mnt(mnt))
goto out;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 155/281] namespace: queue a mount only once for mount notifications
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (153 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 154/281] namespace: check the target before walking it in do_mount_setattr() Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 156/281] namespace: check a submount for references right before unmounting it Greg Kroah-Hartman
` (132 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit bd2feb7796b6585938a4241e7b7c4148a6f7b762 upstream.
mnt_notify_add() puts a mount on notify_list. It doesn't check whether
the mount is on the list already. That's fine as long as every mount is
queued at most once per namespace_sem hold. It isn't.
propagate_umount() moves a surviving overmount off a stack of mounts
that are going away and queues it as moved. shrink_submounts() and
mark_mounts_for_expiry() call umount_tree() for several mounts under a
single namespace_sem hold. So the second umount_tree() can take down
exactly the mount the first one reparented, reparent it once more and so
end up queueing it a second time.
The second list_add_tail() cuts the mounts queued in between out of the
list while the head still points at the last of them. notify_mnt_list()
then only visits that one mount and the others are freed after the grace
period with notify_list still pointing at them. Every later mount
operation on the host walks freed memory:
BUG: KASAN: slab-use-after-free in __list_add_valid_or_report
Read of size 8 at addr ffff8881003d57e0 by task notify_dq/162
__list_add_valid_or_report+0x15c/0x1a0
mnt_add_to_ns+0x322/0x890
attach_recursive_mnt.isra.0+0xf2a/0x1a00
path_mount+0x139c/0x1d40
This needs a mount with MNT_SHRINKABLE to bind from. That's what
finish_automount() creates (submounts of NFS, AFS and CIFS and the
tracefs mount below debugfs). Bind mounts inherit the flag. A mount
namespace with a FAN_MARK_MNTNS mark does the rest and root in a user
namespace can have both.
Initialize to_notify in alloc_vfsmnt() and leave a mount alone that is
queued already. mnt_notify() looks at the state the mount has when the
list is drained so a single entry per mount is enough. The move event
for a mount that is unmounted under the same hold is lost. That's fine.
The detach is what matters.
Fixes: bf630c401641 ("vfs: add notifications for mount attach and detach")
Cc: stable@vger.kernel.org # v6.15+
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-1-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/mount.h | 3 +++
fs/namespace.c | 3 +++
2 files changed, 6 insertions(+)
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -233,6 +233,9 @@ static inline struct mnt_namespace *to_m
#ifdef CONFIG_FSNOTIFY
static inline void mnt_notify_add(struct mount *m)
{
+ /* queued already under this namespace_sem hold */
+ if (!list_empty(&m->to_notify))
+ return;
/* Optimize the case where there are no watches */
if ((m->mnt_ns && m->mnt_ns->n_fsnotify_marks) ||
(m->prev_ns && m->prev_ns->n_fsnotify_marks))
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -322,6 +322,9 @@ static struct mount *alloc_vfsmnt(const
INIT_HLIST_NODE(&mnt->mnt_mp_list);
INIT_HLIST_HEAD(&mnt->mnt_stuck_children);
INIT_HLIST_NODE(&mnt->mnt_ns_visible);
+#ifdef CONFIG_FSNOTIFY
+ INIT_LIST_HEAD(&mnt->to_notify);
+#endif
RB_CLEAR_NODE(&mnt->mnt_node);
mnt->mnt.mnt_idmap = &nop_mnt_idmap;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 156/281] namespace: check a submount for references right before unmounting it
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (154 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 155/281] namespace: queue a mount only once for mount notifications Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 157/281] namespace: check a recursive bind mount for mount namespace loops Greg Kroah-Hartman
` (131 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 32bf92416614a1e3ff3524fc6b780259c7aad3ef upstream.
shrink_submounts() and mark_mounts_for_expiry() first collect all the
mounts they are allowed to unmount and then unmount them.
Whether a mount is busy is decided by propagate_mount_busy() on the
tree. But unmounting the first mount changes the tree that the second
one propagates into. propagate_umount()
moves a surviving overmount off a copy it unmounts and mounts it where
the copy was mounted. If that's where the propagated copy of the second
victim is looked up the overmount becomes a candidate of the second
umount_tree(). It's childless and so trim_one() commits it without
looking at its reference count.
So a synchronous umount pulls out a busy mount that is in use somewhere
else and marks it MNT_SYNC_UMOUNT while it has users:
umount2(/tmp/plshrink/p1, 0) = 0 errno 0
cwd is (unreachable)
The same two umounts requested one after the other fail with EBUSY.
This needs a mount with MNT_SHRINKABLE, i.e., automounted submounts of
NFS, AFS and CIFS or the tracefs mount below debugfs. Bind mounts
inherit the flag.
Check each mount right before it is unmounted under the same hold of
namespace_sem and mount_lock as the umount itself. Make sure that the
algorithm stays linear.
Fixes: 1064f874abc0 ("mnt: Tuck mounts under others instead of creating shadow/side mounts.")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-2-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 78 ++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 53 insertions(+), 25 deletions(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3965,6 +3965,11 @@ void mark_mounts_for_expiry(struct list_
}
while (!list_empty(&graveyard)) {
mnt = list_first_entry(&graveyard, struct mount, mnt_expire);
+ /* an earlier umount_tree() may have moved a busy mount here */
+ if (propagate_mount_busy(mnt, 1)) {
+ list_move(&mnt->mnt_expire, mounts);
+ continue;
+ }
touch_mnt_namespace(mnt->mnt_ns);
umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
}
@@ -3973,16 +3978,36 @@ void mark_mounts_for_expiry(struct list_
EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);
/*
+ * Unmount @mnt if it's a shrinkable mount without children that nobody uses.
+ *
+ * mount_lock must be held for write
+ */
+static bool shrink_submount(struct mount *mnt)
+{
+ if (propagate_mount_busy(mnt, 1))
+ return false;
+ touch_mnt_namespace(mnt->mnt_ns);
+ umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
+ return true;
+}
+
+/*
* Ripoff of 'select_parent()'
*
- * search the list of submounts for a given mountpoint, and move any
- * shrinkable submounts to the 'graveyard' list.
+ * unmount the shrinkable submounts of @parent that aren't busy, children
+ * before their parent, and say whether anything went
+ *
+ * The cursor into the children of @this_parent survives the umount of a
+ * child mount without child mounts. The mounts that get umounted together with
+ * it are located under receiving mounts of @this_parent and never under
+ * @this_parent itself. The one exception is @this_parent getting unmounted
+ * then the walk starts over.
*/
-static int select_submounts(struct mount *parent, struct list_head *graveyard)
+static bool __shrink_submounts(struct mount *parent)
{
struct mount *this_parent = parent;
struct list_head *next;
- int found = 0;
+ bool shrunk = false;
repeat:
next = this_parent->mnt_mounts.next;
@@ -4001,42 +4026,45 @@ resume:
this_parent = mnt;
goto repeat;
}
-
- if (!propagate_mount_busy(mnt, 1)) {
- list_move_tail(&mnt->mnt_expire, graveyard);
- found++;
- }
+ if (!shrink_submount(mnt))
+ continue;
+ shrunk = true;
+ if (unlikely(this_parent->mnt.mnt_flags & MNT_UMOUNT))
+ return true;
}
/*
* All done at this level ... ascend and resume the search
*/
if (this_parent != parent) {
- next = this_parent->mnt_child.next;
- this_parent = this_parent->mnt_parent;
+ struct mount *mnt = this_parent;
+
+ next = mnt->mnt_child.next;
+ this_parent = mnt->mnt_parent;
+ /* its children are gone, maybe it can go as well */
+ if (shrink_submount(mnt)) {
+ shrunk = true;
+ if (unlikely(this_parent->mnt.mnt_flags & MNT_UMOUNT))
+ return true;
+ }
goto resume;
}
- return found;
+ return shrunk;
}
/*
- * process a list of expirable mountpoints with the intent of discarding any
- * submounts of a specific parent mountpoint
+ * unmount the shrinkable submounts of @mnt that aren't busy
+ *
+ * The busy check and the umount of a mount are adjacent. An umount can
+ * still empty or move a mount in a part of the tree that was walked
+ * already, so walk again until nothing goes.
*
* mount_lock must be held for write
*/
static void shrink_submounts(struct mount *mnt)
{
- LIST_HEAD(graveyard);
- struct mount *m;
-
- /* extract submounts of 'mountpoint' from the expiration list */
- while (select_submounts(mnt, &graveyard)) {
- while (!list_empty(&graveyard)) {
- m = list_first_entry(&graveyard, struct mount,
- mnt_expire);
- touch_mnt_namespace(m->mnt_ns);
- umount_tree(m, UMOUNT_PROPAGATE|UMOUNT_SYNC);
- }
+ for (;;) {
+ if (!__shrink_submounts(mnt))
+ break;
}
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 157/281] namespace: check a recursive bind mount for mount namespace loops
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (155 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 156/281] namespace: check a submount for references right before unmounting it Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 158/281] namespace: keep covered mounts covered in OPEN_TREE_NAMESPACE Greg Kroah-Hartman
` (130 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit c640a01a78e42302879006ed7b7d5a9a943ba815 upstream.
do_loopback() refuses to bind mount the file of a mount namespace that
is as old as the caller's or older because a mount namespace that holds
a mount of its own file, or of an ancestor's, would cause a cycle. But
it only checks the dentry the bind mount starts from. With MS_REC
everything below it is copied and do_loopback() passes
CL_COPY_MNT_NS_FILE so mount namespace files below the source are
copied.
That's fine for a source in the caller's own mount namespace. Every
mount namespace file in there passed the same check when it was
bind-mounted. It isn't fine for a source in another mount namespace.
may_copy_tree() accepts a bind mount of any nsfs or pidfs file no matter
what mount namespace it lives in so that /proc/<pid>/ns/<ns> and pidfds
can be bind mounted. If we create a bind-mount stack of mount namespaces
file descriptors the kernel will copy them irrespective of their
ancestoral relationship to the mount namespace in question:
151 146 0:7 net:[4026531833] /tmp/nrc/y rw - nsfs nsfs rw
152 151 0:7 mnt:[4026532293] /tmp/nrc/y rw - nsfs nsfs rw
Mount 152 is a mount of the mount namespace file of mount namespace
4026532293 inside mount namespace 4026532293. That namespace and every
mount in it are leaked... All it takes is a process in an older mount
namespace that stacks the file and repeating it leaks without limit:
after control: Shmem: 380 kB
child: mount(/proc/self/fd/6, MS_BIND|MS_REC): ok
after cycle: Shmem: 65916 kB
do_move_mount() runs check_for_nsfs_mounts() over a detached tree for
exactly that reason. Do the same for the copy before it is grafted.
Fixes: e149ed2b805f ("take the targets of /proc/*/ns/* symlinks to separate fs")
Fixes: ef4144ac2dec ("pidfs: allow bind-mounts")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-4-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3037,7 +3037,11 @@ static int do_loopback(const struct path
if (IS_ERR(mnt))
return PTR_ERR(mnt);
- err = graft_tree(mnt, &mp);
+ /* the copy may carry mount namespace files from below the source */
+ if (recurse && !check_for_nsfs_mounts(mnt))
+ err = -EINVAL;
+ else
+ err = graft_tree(mnt, &mp);
if (err) {
lock_mount_hash();
umount_tree(mnt, UMOUNT_SYNC);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 158/281] namespace: keep covered mounts covered in OPEN_TREE_NAMESPACE
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (156 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 157/281] namespace: check a recursive bind mount for mount namespace loops Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 159/281] namespace: look at the topmost mount for a mount namespace file Greg Kroah-Hartman
` (129 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 0febe278ec45b1ccdbe9bd5ff1ba365d8fd55e2a upstream.
open_tree(OPEN_TREE_NAMESPACE) creates a new mount namespace from a
copy of the tree at the given path. The caller needs to be privileged
over its current user namespace because the new mount namespace will be
owned by it. It doesn't need to be privileged over the mount namespace
the tree is copied from. An unprivileged user just needs to create a
user namespace first.
The copy follows the rules of a detached bind mount. Without
AT_RECURSIVE only the mount itself is cloned and its children are left
out. With AT_RECURSIVE unbindable mounts are skipped. Both is fine when
the caller has privileges over the source mount namespace because it
could unmount those mounts anyway. Not so for an unprivileged user in
that mount namespace. For them a mount namespace copy is what unshare()
does. copy_mnt_ns() copies everything including unbindable mounts and
lock_mnt_tree() makes sure nothing can be unmounted in the copy. Nothing
that was covered gets revealed.
create_new_namespace() only does the locking and so the covered content
is right there in the new mount namespace:
# mount -t tmpfs none /tmp/otn; mkdir /tmp/otn/covered
# echo hidden > /tmp/otn/covered/under.txt
# mount -t tmpfs none /tmp/otn/covered
uid 1000, after unshare(CLONE_NEWUSER):
fd = open_tree(AT_FDCWD, "/tmp/otn", OPEN_TREE_NAMESPACE);
setns(fd, CLONE_NEWNS);
open("/covered/under.txt", O_RDONLY) -> "hidden"
Covering paths with mounts is how container runtimes mask parts of
/proc and /sys and how admins hide things.
When the caller's user namespace doesn't own the source mount namespace
copy the way unshare() does and refuse a non-recursive copy of a mount
that has anything mounted below the requested directory and copy
unbindable mounts in a recursive copy. A caller that is privileged over
the source mount namespace sees no change.
Fixes: 9b8a0ba68246 ("mount: add OPEN_TREE_NAMESPACE")
Cc: stable@vger.kernel.org # v7.0+
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-6-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2354,6 +2354,18 @@ bool has_locked_children(struct mount *m
return __has_locked_children(mnt, dentry);
}
+/* locks: namespace_shared && pinned(mnt) || mount_locked_reader */
+static bool __has_children(struct mount *mnt, struct dentry *dentry)
+{
+ struct mount *child;
+
+ list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
+ if (is_subdir(child->mnt_mountpoint, dentry))
+ return true;
+ }
+ return false;
+}
+
/*
* Check that there aren't references to earlier/same mount namespaces in the
* specified subtree. Such references can act as pins for mount namespaces
@@ -3123,12 +3135,18 @@ static struct mnt_namespace *create_new_
struct mount *mnt;
unsigned int copy_flags = 0;
bool locked = false, recurse = flags & MOUNT_COPY_RECURSIVE;
+ bool foreign = user_ns != ns->user_ns;
if (unlikely(!d_can_lookup(path->dentry)))
return ERR_PTR(-ENOTDIR);
- if (user_ns != ns->user_ns)
- copy_flags |= CL_SLAVE;
+ /*
+ * Without privileges over the mount namespace the copy is made from
+ * nothing mounted below @path may be left out. It would reveal what
+ * it covers. That's what unshare() gives such a caller as well.
+ */
+ if (foreign)
+ copy_flags |= CL_SLAVE | CL_COPY_UNBINDABLE;
new_ns = alloc_mnt_ns(user_ns, false);
if (IS_ERR(new_ns))
@@ -3162,10 +3180,14 @@ static struct mnt_namespace *create_new_
/*
* We don't emulate unshare()ing a mount namespace. We stick to
* the restrictions of creating detached bind-mounts. It has a
- * lot saner and simpler semantics.
+ * lot saner and simpler semantics. A caller without privileges
+ * over the mount namespace can't leave out any child though.
*/
if (flags & MOUNT_COPY_NEW)
mnt = clone_mnt(real_mount(path->mnt), path->dentry, copy_flags);
+ else if (foreign && !recurse &&
+ __has_children(real_mount(path->mnt), path->dentry))
+ mnt = ERR_PTR(-EINVAL);
else
mnt = __do_loopback(path, recurse, copy_flags);
scoped_guard(mount_writer) {
@@ -3182,7 +3204,7 @@ static struct mnt_namespace *create_new_
* of the real rootfs we created.
*/
attach_mnt(mnt, new_ns_root, mp.mp);
- if (user_ns != ns->user_ns)
+ if (foreign)
lock_mnt_tree(new_ns_root);
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 159/281] namespace: look at the topmost mount for a mount namespace file
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (157 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 158/281] namespace: keep covered mounts covered in OPEN_TREE_NAMESPACE Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 160/281] namespace: dont reconfigure internal superblocks via remount and umount Greg Kroah-Hartman
` (128 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 8714b44adac7b10506e1db3ef1710689751f0f10 upstream.
attach_recursive_mnt() preallocates a mountpoint for the root of the
topmost mount of the source so that a mount that already sits at the
destination can be put on top of the source or on top of one of its
propagated copies.
The copies are made without CL_COPY_MNT_NS_FILE so their chain of
overmounts is shorter than the source's. It ends below the first bind
mount of a mount namespace file. So while the loop walks up the chain of
the source it remembers the mountpoint of that mount in "shorter" and
the existing mount is put there for the copies.
But the loop ends at the topmost mount without ever looking at it. If
the topmost mount is the only mount namespace file in the chain
"shorter" stays NULL and mnt_change_mountpoint() attaches the existing
mount of the copy below the root of the mount namespace file. That's a
dentry of nsfs. No path walk in the copy's mount namespace ever gets
there. The mount is gone until its parent goes and the copy that took
its place can't be unmounted synchronously because it has a child:
S bind mount of a file
N bind mount of a mount namespace file on top of S
A shared mount, B a slave of A, Q mounted on B/file
move_mount(S, A/file)
cat B/file -> the content of S instead of Q
umount B/file -> EBUSY
Look at every mount of the chain including the topmost one.
Fixes: 96f5d2e05165 ("attach_recursive_mnt(): unify the mnt_change_mountpoint() logics")
Cc: stable@vger.kernel.org # v6.17+
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-8-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2602,9 +2602,11 @@ static int attach_recursive_mnt(struct m
* Preallocate a mountpoint in case the new mounts need to be
* mounted beneath mounts on the same mountpoint.
*/
- for (top = source_mnt; unlikely(top->overmount); top = top->overmount) {
+ for (top = source_mnt; ; top = top->overmount) {
if (!shorter && is_mnt_ns_file(top->mnt.mnt_root))
shorter = top->mnt_mp;
+ if (likely(!top->overmount))
+ break;
}
err = get_mountpoint(top->mnt.mnt_root, &root);
if (err)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 160/281] namespace: dont reconfigure internal superblocks via remount and umount
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (158 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 159/281] namespace: look at the topmost mount for a mount namespace file Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 161/281] namespace: remove the fsnotify marks of a mount namespace in process context Greg Kroah-Hartman
` (127 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit d791606bb915a8f27e36657696fd1d9a216c5c08 upstream.
Commit 02587a4af82a ("fs: refuse fspick() on internal superblocks")
blocked fspick() on SB_NOUSER superblocks. But that's not the only way
to reconfigure_super(). mount(MS_REMOUNT) and umount() of the caller's
root without MNT_DETACH. The root of an empty mount namespace is a
nullfs mount and all mount namespaces share that superblock:
nullfs: fspick: FAIL errno=22 (Invalid argument)
nullfs: mount(MS_REMOUNT|MS_RDONLY): ok(0)
nullfs after remount: statfs(/): magic=0x4e554c4c flags=0x21 RDONLY
nullfs: umount2("/", 0): ok(0)
Refuse both like fspick() does. Only root in the initial user namespace
can do this and nullfs is empty and immutable so the flags don't buy
anything. But they show up in statfs() for the root of every mount
namespace on the host.
Fixes: 9d4e752a24f7 ("namespace: allow creating empty mount namespaces")
Cc: stable@vger.kernel.org # v7.1+
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-11-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/fs_context.c | 4 ++++
fs/fsopen.c | 3 ---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/fs_context.c b/fs/fs_context.c
index 23ad66cd94e1..a50584df97be 100644
--- a/fs/fs_context.c
+++ b/fs/fs_context.c
@@ -315,6 +315,10 @@ struct fs_context *fs_context_for_reconfigure(struct dentry *dentry,
unsigned int sb_flags,
unsigned int sb_flags_mask)
{
+ /* kernel-internal superblocks are nobody's to reconfigure */
+ if (dentry->d_sb->s_flags & SB_NOUSER)
+ return ERR_PTR(-EINVAL);
+
return alloc_fs_context(dentry->d_sb->s_type, dentry, sb_flags,
sb_flags_mask, FS_CONTEXT_FOR_RECONFIGURE);
}
diff --git a/fs/fsopen.c b/fs/fsopen.c
index 9d5a7a22b529..ae19e5136598 100644
--- a/fs/fsopen.c
+++ b/fs/fsopen.c
@@ -190,9 +190,6 @@ SYSCALL_DEFINE3(fspick, int, dfd, const char __user *, path, unsigned int, flags
ret = -EINVAL;
if (target.mnt->mnt_root != target.dentry)
goto err_path;
- /* kernel-internal superblocks are nobody's to reconfigure */
- if (target.dentry->d_sb->s_flags & SB_NOUSER)
- goto err_path;
fc = fs_context_for_reconfigure(target.dentry, 0, 0);
if (IS_ERR(fc)) {
--
2.56.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 161/281] namespace: remove the fsnotify marks of a mount namespace in process context
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (159 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 160/281] namespace: dont reconfigure internal superblocks via remount and umount Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 162/281] namespace: check the mounts before reading their parents in pivot_root() Greg Kroah-Hartman
` (126 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amir Goldstein,
Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 1a116222acdcc1bc1a8350727ae6f28907d44594 upstream.
mnt_ns_release() drops the last passive reference of a mount namespace
and removes its fanotify marks via fsnotify_mntns_delete(). That takes
the mutex of every group with a mark on the namespace and the spinlock
of the connector. Fine from process context. But mnt_ns_tree_remove()
hands the reference the namespace was allocated with to call_rcu() and
so the marks are removed from the RCU softirq:
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:623
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 0, name: swapper/3
__mutex_lock+0x113/0x24b0
fsnotify_destroy_marks+0x11b/0x3d0
mnt_ns_release_rcu+0x57/0xa0
rcu_core+0x6b6/0x1e40
and lockdep complains about the connector lock being taken from softirq
context. A fanotify group with a FAN_MARK_MNTNS mark on the mount
namespace of another task is all that's needed. Root in a user
namespace can do that for a mount namespace it owns. The task exits and
the namespace is freed with the mark still on it.
Remove the marks in free_mnt_ns() before the namespace is handed to RCU.
That runs in process context once the last active reference is gone. A
mark is added through a file descriptor to the namespace which holds an
active reference so no mark can show up after that.
Fixes: bf630c401641 ("vfs: add notifications for mount attach and detach")
Cc: stable@vger.kernel.org # v6.15+
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-13-be34c83956ae@kernel.org
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -130,7 +130,6 @@ static void mnt_ns_release(struct mnt_na
{
/* keep alive for {list,stat}mount() */
if (ns && refcount_dec_and_test(&ns->passive)) {
- fsnotify_mntns_delete(ns);
put_user_ns(ns->user_ns);
kfree(ns);
}
@@ -4257,6 +4256,8 @@ static void free_mnt_ns(struct mnt_names
if (!is_anon_ns(ns))
ns_common_free(ns);
dec_mnt_namespaces(ns->ucounts);
+ /* the last active reference is gone, no mark can show up anymore */
+ fsnotify_mntns_delete(ns);
mnt_ns_tree_remove(ns);
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 162/281] namespace: check the mounts before reading their parents in pivot_root()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (160 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 161/281] namespace: remove the fsnotify marks of a mount namespace in process context Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:37 ` [PATCH 7.2 163/281] dcache: dont put a mountpoint on a dentry thats being removed Greg Kroah-Hartman
` (125 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 6b7c001eb5857fa09041f47673666060a2e5fc1c upstream.
path_pivot_root() reads the parents of new_root and of the caller's root
and checks whether they are shared before it checks that either mount is
in the caller's mount namespace. Only namespace_sem is held. That's fine
for a mount that is in the caller's mount namespace.
But new_root can be a file descriptor to a mount that has been unmounted
and that only the file descriptor keeps alive. If that mount stayed
attached to its parent when it was unmounted nothing pins the parent for
it. The final mntput() of the parent unhooks the children under
mount_lock alone and frees the parent afterwards:
pivot_root() close(fd), last ref on the parent
------------ ---------------------------------
ex_parent = new_mnt->mnt_parent
mntput_no_expire_slowpath()
__umount_mnt(new_mnt)
cleanup_mnt()
call_rcu()
IS_MNT_SHARED(ex_parent)
BUG: KASAN: slab-use-after-free in path_pivot_root+0xf1a/0x1840
Read of size 4 at addr ffff8881047382f8 by task pivot_widen/157
path_pivot_root+0xf1a/0x1840
__x64_sys_pivot_root+0x165/0x190
The same goes for the caller's root via chroot(). Both outcomes of the
check end in EINVAL so nothing but the read itself goes wrong. It's the
same thing commit bb4609405752 ("statmount: read the parent of an
unmounted mount under mount_lock") fixed for statmount().
Check that both mounts are in the caller's namespace before their
parents are read. Every path returns EINVAL either way.
Fixes: e0c9c0afd2fc ("mnt: Update detach_mounts to leave mounts connected")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-10-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -4759,14 +4759,15 @@ int path_pivot_root(struct path *new, st
new_mnt = real_mount(new->mnt);
root_mnt = real_mount(root.mnt);
+ /* only a mounted mount has a parent that namespace_sem pins */
+ if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
+ return -EINVAL;
ex_parent = new_mnt->mnt_parent;
root_parent = root_mnt->mnt_parent;
if (IS_MNT_SHARED(old_mnt) ||
IS_MNT_SHARED(ex_parent) ||
IS_MNT_SHARED(root_parent))
return -EINVAL;
- if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
- return -EINVAL;
if (new_mnt->mnt.mnt_flags & MNT_LOCKED)
return -EINVAL;
if (d_unlinked(new->dentry))
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 163/281] dcache: dont put a mountpoint on a dentry thats being removed
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (161 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 162/281] namespace: check the mounts before reading their parents in pivot_root() Greg Kroah-Hartman
@ 2026-10-13 11:37 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 164/281] unshare: dont drop active namespace references that were never taken Greg Kroah-Hartman
` (124 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:37 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 75f4197f1e11d2eb75c2d6f916a7d4764db621e5 upstream.
rmdir(), unlink() and rename() call dont_mount() on the victim and then
detach_mounts() with the victim's inode locked. do_lock_mount() takes
the inode lock of the mountpoint and checks cant_mount() so a mount
can't show up after detach_mounts().
But attach_recursive_mnt() makes a second mountpoint for the root of the
source mount so that the mounts already located at the destination can
be put on top of it. No inode is locked for that one and d_set_mounted()
only refuses a dentry that is unlinked. Between detach_mounts() and
d_delete() the victim is still hashed:
rmrace: b passed dont_mount() and detach_mounts(), sleeping
T2: move_mount(S, /tmp/plcant/x, BENEATH) = 0 errno 0 ()
T1: rmdir(/tmp/plcant/d/b) = 0 errno 0
109 107 0:61 /d/b//deleted /tmp/plcant/x rw,relatime - tmpfs tmpfs rw
108 109 0:63 / /tmp/plcant/x rw,relatime - tmpfs T rw
A bind mount of the directory that's being removed is moved beneath an
existing mount while the rmdir() is located between the two calls. The
mount ends up on the removed directory and nothing will ever detach it.
Check cant_mount() in d_set_mounted() as well. dont_mount() raises the
flag under d_lock before detach_mounts() runs so either the mountpoint
is set first and detach_mounts() finds the mount or the flag is seen and
the mount is refused.
Fixes: 1064f874abc0 ("mnt: Tuck mounts under others instead of creating shadow/side mounts.")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-15-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/dcache.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1583,6 +1583,8 @@ EXPORT_SYMBOL(path_has_submounts);
*
* Only one of d_invalidate() and d_set_mounted() must succeed. For
* this reason take rename_lock and d_lock on dentry and ancestors.
+ * Likewise for dont_mount() which marks a dentry that is being removed
+ * under d_lock.
*/
int d_set_mounted(struct dentry *dentry)
{
@@ -1599,7 +1601,7 @@ int d_set_mounted(struct dentry *dentry)
spin_unlock(&p->d_lock);
}
spin_lock(&dentry->d_lock);
- if (!d_unlinked(dentry)) {
+ if (!d_unlinked(dentry) && !cant_mount(dentry)) {
ret = -EBUSY;
if (!d_mountpoint(dentry)) {
dentry->d_flags |= DCACHE_MOUNTED;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 164/281] unshare: dont drop active namespace references that were never taken
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (162 preceding siblings ...)
2026-10-13 11:37 ` [PATCH 7.2 163/281] dcache: dont put a mountpoint on a dentry thats being removed Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 165/281] namespace: dont let a pseudo dentry become the root of a mount Greg Kroah-Hartman
` (123 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 0b6f31a3c0b16066f812e94b52a704174a6f23cd upstream.
Active references on the namespaces of an nsproxy are taken when the
nsproxy is installed into a task in switch_task_namespaces() and
copy_namespaces() and dropped again by put_nsproxy() through
deactivate_nsproxy().
But ksys_unshare() calls put_nsproxy() on an nsproxy that was never
installed when set_cred_ucounts() fails. The new namespaces of that
nsproxy go from zero to minus one and the namespaces shared with the
caller lose a reference that belongs to the nsproxy the caller keeps
using:
WARNING: kernel/nscommon.c:171 at __ns_ref_active_put+0x1cd/0x230
nsproxy_ns_active_put
deactivate_nsproxy
ksys_unshare
Afterwards the namespaces the caller lives in aren't listed by listns()
anymore. set_cred_ucounts() only fails when alloc_ucounts() can't
allocate and it only allocates when the real uid of the caller differs
from its effective uid.
Commit cefd55bd2159 ("nsproxy: fix free_nsproxy() and simplify
create_new_namespaces()") separated the two cases on purpose.
nsproxy_free() frees an nsproxy that was prepared but never installed
and that's what a failed setns() uses in put_nsset(). Export it and use
it for a failed unshare() as well.
Fixes: a98621a0f187 ("unshare: fix nsproxy leak in ksys_unshare() on set_cred_ucounts() failure")
Cc: stable@vger.kernel.org # v7.1+
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-16-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/nsproxy.h | 1 +
kernel/fork.c | 3 ++-
kernel/nsproxy.c | 2 +-
3 files changed, 4 insertions(+), 2 deletions(-)
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -100,6 +100,7 @@ void exit_cred_namespaces(struct task_st
void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
int exec_task_namespaces(void);
void deactivate_nsproxy(struct nsproxy *ns);
+void nsproxy_free(struct nsproxy *ns);
int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
struct cred *, struct fs_struct *);
int __init nsproxy_cache_init(void);
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -3326,8 +3326,9 @@ int ksys_unshare(unsigned long unshare_f
perf_event_namespaces(current);
bad_unshare_cleanup_nsproxy:
+ /* never installed, so no active references to drop */
if (new_nsproxy)
- put_nsproxy(new_nsproxy);
+ nsproxy_free(new_nsproxy);
bad_unshare_cleanup_cred:
if (new_cred)
put_cred(new_cred);
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -61,7 +61,7 @@ static inline struct nsproxy *create_nsp
return nsproxy;
}
-static inline void nsproxy_free(struct nsproxy *ns)
+void nsproxy_free(struct nsproxy *ns)
{
put_mnt_ns(ns->mnt_ns);
put_uts_ns(ns->uts_ns);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 165/281] namespace: dont let a pseudo dentry become the root of a mount
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (163 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 164/281] unshare: dont drop active namespace references that were never taken Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 166/281] namespace: unhash a dentry before detaching the mounts on it Greg Kroah-Hartman
` (122 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit b138e16fb1e81376cea89f727dda7bfccd140de4 upstream.
d_alloc_pseudo() hands out dentries for pipes, sockets and other files
that are never anyone's child or parent. They carry DCACHE_NORCU and
dentry_free() frees them right away because no lockless path walk can
ever reach them. That holds as long as such a dentry isn't the root of
a mount. But bind mounting /proc/self/fd/<fd> of such a file does
exactly that.
Most callers of alloc_file_pseudo() put their files on kernel-internal
mounts and may_copy_tree() refuses those. bpf_token_create() doesn't. It
places the token file on the bpffs mount the caller handed it and that
mount is in the caller's mount namespace so the clone goes through:
mount --bind /proc/self/fd/<token> <file>
open_tree(tokfd, "", AT_EMPTY_PATH | OPEN_TREE_CLONE) + move_mount()
__follow_mount_rcu() then loads ->mnt_root of that mount, reads d_seq
and d_flags of the dentry and only then checks mount_lock. The dentry
can be gone by then. The final mntput() of an unmounted parent unhooks
a child that stayed attached to it under mount_lock alone. When the
child's holder does the final put right after that the root is dput()
and freed immediately while a walker that found the mount hashed still
looks at it.
Refuse to clone a mount with a DCACHE_NORCU dentry as its root. Nothing
sensible can be done with a bind mount of a bpf token anyway.
Fixes: 35f96de04127 ("bpf: Introduce BPF token object")
Cc: stable@vger.kernel.org # v6.9+
Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-17-be34c83956ae@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3008,6 +3008,10 @@ static struct mount *__do_loopback(const
if (!may_copy_tree(old_path))
return ERR_PTR(-EINVAL);
+ /* a pseudo dentry is freed without an RCU delay, no walk may find it */
+ if (old_path->dentry->d_flags & DCACHE_NORCU)
+ return ERR_PTR(-EINVAL);
+
if (recurse && !old->mnt_ns)
return ERR_PTR(-EINVAL);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 166/281] namespace: unhash a dentry before detaching the mounts on it
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (164 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 165/281] namespace: dont let a pseudo dentry become the root of a mount Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 167/281] namei: dont reveal overmounted entries in refwalk Greg Kroah-Hartman
` (121 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 528b383dc35d1e5caf64ddf5d35f983ae543b0d0 upstream.
unlink(), rmdir() and rename() remove the entry from the filesystem,
call detach_mounts() on the entry with the inode locked and then call
d_delete() once the inode is unlocked.
The thing is that between detach_mounts() and d_delete() the dentry is
still hashed and positive. But after detach_mounts() nothing covers the
dentry anymore. A lookup that finds this dentry in the dcache can
uncover what the mounts hid.
That's a problem when unlinking files or directories that are
mountpoints in other mount namespaces. Everybody who had the underlying
entry covered can race the detach_mount() call until d_delete() has run.
The race window isn't all that small. It encompasses namespace_unlock()
with a full synchronize_rcu_expedited() grace period and the
inode_unlock() of the entry.
In my experiments three walkers that kept trying read an overmounted
file in 11938 of the 16140 unlinks that removed its mountpoint from a
bind mount of the filesystem within a minute.
Fun fact, d_invalidate() has the same ordering problem but gets it
right. It unhashes the dentry first and detaches the mounts afterwards.
Let's do the same in __detach_mounts():
- A lookup that hasn't found the dentry yet misses it in the dcache and
waits for the directory lock that the caller holds until the name is
gone for good.
- A lockless lookup that found it already fails the mount_lock check
while the dentry still counts as a mountpoint and the d_seq check once
it doesn't, and retries.
This fixes the lockless path. We still need to fix the reference count
lookup in a follow-up patch.
So d_drop() the dentry. The dentry stays positive and held but can't be
found anymore. Then proceed with the detach and unlink.
Reproducer:
The reads were counted with the program below, three walkers for 60 s
in a VM with 4 CPUs. The race window is stretched with the debug patch
pasted here. fs.detach_race_walk_us sleeps in lookup_fast() once it
found a mountpoint dentry and before its mounts are crossed.
fs.detach_race_unlink_us sleeps in vfs_unlink() between detach_mounts()
and d_delete().
// SPDX-License-Identifier: GPL-2.0
/*
* unlink_covered: unlink a file that is a mountpoint in a detached copy of
* its mount, against lookups that open it through that copy.
*
* A is a tmpfs with the file f1 (content SECRET_F) and the plain file
* MARK_A. A' is an open_tree(OPEN_TREE_CLONE) copy of A with MARK_A bound
* on A'/f1, held through an O_PATH fd on its root once the tree fd is
* closed. Walkers open f1 through that fd while the driver unlinks A/f1,
* where nothing is mounted on it. A walker may read MARK_A or get ENOENT.
* A read of SECRET_F is a hit: the name was found after its mount was
* gone. The lockless walks use openat2(RESOLVE_CACHED).
*
* usage: unlink_covered [-t seconds] [-w walkers]
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <linux/openat2.h>
#ifndef __NR_open_tree
#define __NR_open_tree 428
#endif
#ifndef __NR_move_mount
#define __NR_move_mount 429
#endif
#ifndef __NR_openat2
#define __NR_openat2 437
#endif
#ifndef OPEN_TREE_CLONE
#define OPEN_TREE_CLONE 1
#endif
#ifndef OPEN_TREE_CLOEXEC
#define OPEN_TREE_CLOEXEC O_CLOEXEC
#endif
#ifndef MOVE_MOUNT_F_EMPTY_PATH
#define MOVE_MOUNT_F_EMPTY_PATH 0x00000004
#endif
#define WORK "/tmp/uc"
#define ADIR WORK "/A"
static int duration = 60, nwalkers = 3;
static atomic_int stop, writer_waiting;
static pthread_rwlock_t cur_lock = PTHREAD_RWLOCK_INITIALIZER;
static int cur_fd = -1; /* the root of A', -1 while there is none */
static atomic_long n_unlink, n_walk, n_mark, n_enoent, n_other, n_secret,
n_secret_cached;
static void die(const char *what)
{
fprintf(stderr, "FATAL %s: %s\n", what, strerror(errno));
exit(2);
}
static void put_file(int dfd, const char *name, const char *content)
{
int fd = openat(dfd, name, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC,
0644);
if (fd < 0 || write(fd, content, strlen(content)) < 0)
die(name);
close(fd);
}
/* "plain/../" @n times, then f1: a longer walk that checks nothing on its way */
static char *longpath(int n)
{
char *p = malloc(n * 9 + 3), *q = p;
for (int i = 0; i < n; i++, q += 9)
memcpy(q, "plain/../", 9);
strcpy(q, "f1");
return p;
}
static void try_read(int dfd, const char *path, int cached)
{
struct open_how how = { .flags = O_RDONLY | O_CLOEXEC,
.resolve = RESOLVE_CACHED };
char buf[32] = "";
long n;
int fd;
if (cached)
fd = syscall(__NR_openat2, dfd, path, &how, sizeof(how));
else
fd = openat(dfd, path, O_RDONLY | O_CLOEXEC);
atomic_fetch_add(&n_walk, 1);
if (fd < 0) {
if (errno == ENOENT)
atomic_fetch_add(&n_enoent, 1);
else if (!cached || errno != EAGAIN)
atomic_fetch_add(&n_other, 1);
return;
}
n = read(fd, buf, sizeof(buf) - 1);
close(fd);
if (n >= 6 && !strncmp(buf, "SECRET", 6)) {
if (cached)
atomic_fetch_add(&n_secret_cached, 1);
if (!atomic_fetch_add(&n_secret, 1))
printf("HIT: read \"%s\" through %s (%s walk)\n", buf,
path, cached ? "lockless" : "any");
} else {
atomic_fetch_add(&n_mark, 1);
}
}
static void *walker(void *arg)
{
unsigned int r = (long)arg * 2654435761u;
while (!atomic_load(&stop)) {
char *p_long, *p_short;
int dfd;
while (atomic_load(&writer_waiting) && !atomic_load(&stop))
usleep(20);
pthread_rwlock_rdlock(&cur_lock);
dfd = cur_fd;
if (dfd < 0) {
pthread_rwlock_unlock(&cur_lock);
usleep(100);
continue;
}
r = r * 1103515245u + 12345u;
p_long = longpath(1 + (r >> 8) % 400);
p_short = longpath(0);
try_read(dfd, p_long, 0);
try_read(dfd, p_short, 0);
try_read(dfd, p_long, 1);
pthread_rwlock_unlock(&cur_lock);
free(p_long);
free(p_short);
}
return NULL;
}
/* hand the walkers a new A' (or none), close the old one */
static void publish(int fd)
{
int old;
atomic_fetch_add(&writer_waiting, 1);
pthread_rwlock_wrlock(&cur_lock);
old = cur_fd;
cur_fd = fd;
pthread_rwlock_unlock(&cur_lock);
atomic_fetch_sub(&writer_waiting, 1);
if (old >= 0)
close(old);
}
static void *driver(void *arg __attribute__((unused)))
{
int a;
if (mkdir(ADIR, 0755) && errno != EEXIST)
die("mkdir A");
if (mount("A", ADIR, "tmpfs", 0, "size=4M"))
die("mount A");
a = open(ADIR, O_PATH | O_DIRECTORY | O_CLOEXEC);
if (a < 0 || mkdirat(a, "plain", 0755))
die("A/plain");
put_file(a, "MARK_A", "MARK_A");
while (!atomic_load(&stop)) {
int t, m, fd_a;
put_file(a, "f1", "SECRET_F");
t = syscall(__NR_open_tree, a, "",
OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC | AT_EMPTY_PATH);
if (t < 0)
die("open_tree A");
m = syscall(__NR_open_tree, a, "MARK_A",
OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
if (m < 0)
die("open_tree MARK_A");
if (syscall(__NR_move_mount, m, "", t, "f1",
MOVE_MOUNT_F_EMPTY_PATH))
die("move_mount");
close(m);
fd_a = openat(t, ".", O_PATH | O_DIRECTORY | O_CLOEXEC);
if (fd_a < 0)
die("open A'");
publish(fd_a);
usleep(200 + rand() % 1000);
close(t); /* A' is unmounted, fd_a holds it */
usleep(200 + rand() % 1000);
if (unlinkat(a, "f1", 0)) /* through A, a plain file there */
die("unlink f1");
atomic_fetch_add(&n_unlink, 1);
usleep(rand() % 300);
publish(-1);
}
close(a);
umount2(ADIR, MNT_DETACH);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t d, *w;
int c, i;
setvbuf(stdout, NULL, _IOLBF, 0);
while ((c = getopt(argc, argv, "t:w:")) != -1) {
switch (c) {
case 't':
duration = atoi(optarg);
break;
case 'w':
nwalkers = atoi(optarg);
break;
default:
fprintf(stderr, "usage: unlink_covered [-t seconds] [-w walkers]\n");
return 2;
}
}
if (unshare(CLONE_NEWNS) ||
mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL))
die("unshare");
if (mkdir(WORK, 0755) && errno != EEXIST)
die("mkdir");
w = calloc(nwalkers, sizeof(*w));
for (i = 0; i < nwalkers; i++)
if (pthread_create(&w[i], NULL, walker, (void *)(long)i))
die("pthread_create");
if (pthread_create(&d, NULL, driver, NULL))
die("pthread_create");
sleep(duration);
atomic_store(&stop, 1);
pthread_join(d, NULL);
for (i = 0; i < nwalkers; i++)
pthread_join(w[i], NULL);
printf("unlink_covered: %d s, %d walkers: unlinks %ld walks %ld mark %ld enoent %ld other %ld SECRET %ld (lockless %ld)\n",
duration, nwalkers, atomic_load(&n_unlink), atomic_load(&n_walk),
atomic_load(&n_mark), atomic_load(&n_enoent),
atomic_load(&n_other), atomic_load(&n_secret),
atomic_load(&n_secret_cached));
return atomic_load(&n_secret) ? 1 : 0;
}
# diff --git a/fs/namei.c b/fs/namei.c
# --- a/fs/namei.c
# +++ b/fs/namei.c
# @@ -35,6 +35,7 @@
# #include <linux/fcntl.h>
# #include <linux/device_cgroup.h>
# #include <linux/fs_struct.h>
# +#include <linux/delay.h>
# #include <linux/posix_acl.h>
# #include <linux/hash.h>
# #include <linux/bitops.h>
# @@ -1205,9 +1206,26 @@ static int sysctl_protected_symlinks __read_mostly;
# static int sysctl_protected_hardlinks __read_mostly;
# static int sysctl_protected_fifos __read_mostly;
# static int sysctl_protected_regular __read_mostly;
# +/* debug: widen the two windows of the detach_mounts() race */
# +static int sysctl_detach_race_walk_us __read_mostly;
# +static int sysctl_detach_race_unlink_us __read_mostly;
#
# #ifdef CONFIG_SYSCTL
# static const struct ctl_table namei_sysctls[] = {
# + {
# + .procname = "detach_race_walk_us",
# + .data = &sysctl_detach_race_walk_us,
# + .maxlen = sizeof(int),
# + .mode = 0644,
# + .proc_handler = proc_dointvec,
# + },
# + {
# + .procname = "detach_race_unlink_us",
# + .data = &sysctl_detach_race_unlink_us,
# + .maxlen = sizeof(int),
# + .mode = 0644,
# + .proc_handler = proc_dointvec,
# + },
# {
# .procname = "protected_symlinks",
# .data = &sysctl_protected_symlinks,
# @@ -1878,6 +1896,10 @@ static struct dentry *lookup_fast(struct nameidata *nd)
# dentry = __d_lookup(parent, &nd->last);
# if (unlikely(!dentry))
# return NULL;
# + /* debug: between finding a mountpoint and crossing its mounts */
# + if (unlikely(sysctl_detach_race_walk_us) && d_mountpoint(dentry))
# + usleep_range(sysctl_detach_race_walk_us,
# + sysctl_detach_race_walk_us + 10);
# status = d_revalidate(nd->inode, &nd->last, dentry, nd->flags);
# }
# if (unlikely(status <= 0)) {
# @@ -5693,6 +5715,10 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir,
# if (!error) {
# dont_mount(dentry);
# detach_mounts(dentry);
# + /* debug: the mounts are gone, d_delete() is still to come */
# + if (unlikely(sysctl_detach_race_unlink_us))
# + usleep_range(sysctl_detach_race_unlink_us,
# + sysctl_detach_race_unlink_us + 10);
# }
# }
# }
Fixes: 8ed936b5671b ("vfs: Lazily remove mounts on unlinked files and directories.")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-1-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1984,6 +1984,9 @@ out:
* detach_mounts allows lazily unmounting those mounts instead of
* leaking them.
*
+ * The dentry is unhashed before the mounts go so that no lookup finds
+ * what they covered. The caller removes it for good afterwards.
+ *
* The caller may hold dentry->d_inode->i_rwsem.
*/
void __detach_mounts(struct dentry *dentry)
@@ -1997,6 +2000,8 @@ void __detach_mounts(struct dentry *dent
if (!lookup_mountpoint(dentry, &mp))
return;
+ /* the name goes first, what covered it goes second */
+ d_drop(dentry);
event++;
while (mp.node.next) {
mnt = hlist_entry(mp.node.next, struct mount, mnt_mp_list);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 167/281] namei: dont reveal overmounted entries in refwalk
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (165 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 166/281] namespace: unhash a dentry before detaching the mounts on it Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 168/281] fcntl: refuse F_SET_RW_HINT on an immutable inode Greg Kroah-Hartman
` (120 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 8189ab688f5a2c745dc90b63374da02f213d6994 upstream.
In rcuwalk the dentry is validated before it is accepted. step_into()
step_into() rechecks d_seq and __follow_mount_rcu() rechecks mount_lock.
An entry that gets unlinked in between causes the lookup to retry and
miss.
A refwalk doesn't do this. lookup_fast() takes a reference on the hashed
dentry and simply accepts it. So an unlink that happens after the
reference was taken isn't seen by refwalk. That's fine for a simple
file. We just happened to open it before it was unlinked, no problem.
For a mountpoint and specifically a locked mountpoint it very much
isn't. The unlink detaches all mounts and then removes the name. Any
refwalk that hasn't traversed the mounts yet simply reveals the
underlying entry. It's a very narrow window but it can be hit:
reads of a covered file in 60 s, 3 walkers, ~15000 unlinks
no widening 27
that step + 200 us 3741
See the appended patch for a more reliable reproducer.
So check the entry after step_into(). unlink(), rmdir() and rename()
mark the dentry with dont_mount() before they detach the mounts and
remove the dentry.
So a dentry that is marked with DCACHE_CANT_MOUNT and is unhashed by the
time its mounts were looked at is a name that was unlinked under the
refwalk. DCACHE_CANT_MOUNT is read after the mounts were looked up and
it is set before they are detached by detach_mounts(). A refwalk that
missed the mounts will see DCACHE_CANT_MOUNT.
Plain d_unlinked() is fine. A rename takes the dentry off its hash chain
but ___d_drop() leaves d_hash.pprev set. So only __d_drop() and a rename
over the dentry unhash it. The only move that flips IS_ROOT splices in a
disconnected alias. That doesn't have DCACHE_CANT_MOUNT set.
Add the to step_into_slowpath(). ".." and LOOKUP_DOWN may legitimately
land on an unhashed directory. A refwalk that crossed onto a mount has
path.mnt different from nd->path.mnt. A dentry that a filesystem dropped
on its own (d_invalidate(), d_drop()) doesn't have the flag set and is
treated as before.
// SPDX-License-Identifier: GPL-2.0
/*
* unlink_covered: unlink a file that is a mountpoint in a detached copy of
* its mount, against walkers that open it through that copy.
*
* A is a tmpfs with the file f1 (content SECRET_F) and the plain file
* MARK_A. A' is an open_tree(OPEN_TREE_CLONE) copy of A with MARK_A bound
* on A'/f1, held through an O_PATH fd on its root once the tree fd is
* closed. Walkers open f1 through that fd while the driver unlinks A/f1,
* where nothing is mounted on it. A walker may read MARK_A or get ENOENT.
* A read of SECRET_F is a hit: the name was found after its mount was
* gone. The lockless walks use openat2(RESOLVE_CACHED).
*
* usage: unlink_covered [-t seconds] [-w walkers]
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <linux/openat2.h>
#ifndef __NR_open_tree
#define __NR_open_tree 428
#endif
#ifndef __NR_move_mount
#define __NR_move_mount 429
#endif
#ifndef __NR_openat2
#define __NR_openat2 437
#endif
#ifndef OPEN_TREE_CLONE
#define OPEN_TREE_CLONE 1
#endif
#ifndef OPEN_TREE_CLOEXEC
#define OPEN_TREE_CLOEXEC O_CLOEXEC
#endif
#ifndef MOVE_MOUNT_F_EMPTY_PATH
#define MOVE_MOUNT_F_EMPTY_PATH 0x00000004
#endif
#define WORK "/tmp/uc"
#define ADIR WORK "/A"
static int duration = 60, nwalkers = 3;
static atomic_int stop, writer_waiting;
static pthread_rwlock_t cur_lock = PTHREAD_RWLOCK_INITIALIZER;
static int cur_fd = -1; /* the root of A', -1 while there is none */
static atomic_long n_unlink, n_walk, n_mark, n_enoent, n_other, n_secret,
n_secret_cached;
static void die(const char *what)
{
fprintf(stderr, "FATAL %s: %s\n", what, strerror(errno));
exit(2);
}
static void put_file(int dfd, const char *name, const char *content)
{
int fd = openat(dfd, name, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC,
0644);
if (fd < 0 || write(fd, content, strlen(content)) < 0)
die(name);
close(fd);
}
/* "plain/../" @n times, then f1: a longer walk that checks nothing on its way */
static char *longpath(int n)
{
char *p = malloc(n * 9 + 3), *q = p;
for (int i = 0; i < n; i++, q += 9)
memcpy(q, "plain/../", 9);
strcpy(q, "f1");
return p;
}
static void try_read(int dfd, const char *path, int cached)
{
struct open_how how = { .flags = O_RDONLY | O_CLOEXEC,
.resolve = RESOLVE_CACHED };
char buf[32] = "";
long n;
int fd;
if (cached)
fd = syscall(__NR_openat2, dfd, path, &how, sizeof(how));
else
fd = openat(dfd, path, O_RDONLY | O_CLOEXEC);
atomic_fetch_add(&n_walk, 1);
if (fd < 0) {
if (errno == ENOENT)
atomic_fetch_add(&n_enoent, 1);
else if (!cached || errno != EAGAIN)
atomic_fetch_add(&n_other, 1);
return;
}
n = read(fd, buf, sizeof(buf) - 1);
close(fd);
if (n >= 6 && !strncmp(buf, "SECRET", 6)) {
if (cached)
atomic_fetch_add(&n_secret_cached, 1);
if (!atomic_fetch_add(&n_secret, 1))
printf("HIT: read \"%s\" through %s (%s walk)\n", buf,
path, cached ? "lockless" : "any");
} else {
atomic_fetch_add(&n_mark, 1);
}
}
static void *walker(void *arg)
{
unsigned int r = (long)arg * 2654435761u;
while (!atomic_load(&stop)) {
char *p_long, *p_short;
int dfd;
while (atomic_load(&writer_waiting) && !atomic_load(&stop))
usleep(20);
pthread_rwlock_rdlock(&cur_lock);
dfd = cur_fd;
if (dfd < 0) {
pthread_rwlock_unlock(&cur_lock);
usleep(100);
continue;
}
r = r * 1103515245u + 12345u;
p_long = longpath(1 + (r >> 8) % 400);
p_short = longpath(0);
try_read(dfd, p_long, 0);
try_read(dfd, p_short, 0);
try_read(dfd, p_long, 1);
pthread_rwlock_unlock(&cur_lock);
free(p_long);
free(p_short);
}
return NULL;
}
/* hand the walkers a new A' (or none), close the old one */
static void publish(int fd)
{
int old;
atomic_fetch_add(&writer_waiting, 1);
pthread_rwlock_wrlock(&cur_lock);
old = cur_fd;
cur_fd = fd;
pthread_rwlock_unlock(&cur_lock);
atomic_fetch_sub(&writer_waiting, 1);
if (old >= 0)
close(old);
}
static void *driver(void *arg __attribute__((unused)))
{
int a;
if (mkdir(ADIR, 0755) && errno != EEXIST)
die("mkdir A");
if (mount("A", ADIR, "tmpfs", 0, "size=4M"))
die("mount A");
a = open(ADIR, O_PATH | O_DIRECTORY | O_CLOEXEC);
if (a < 0 || mkdirat(a, "plain", 0755))
die("A/plain");
put_file(a, "MARK_A", "MARK_A");
while (!atomic_load(&stop)) {
int t, m, fd_a;
put_file(a, "f1", "SECRET_F");
t = syscall(__NR_open_tree, a, "",
OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC | AT_EMPTY_PATH);
if (t < 0)
die("open_tree A");
m = syscall(__NR_open_tree, a, "MARK_A",
OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
if (m < 0)
die("open_tree MARK_A");
if (syscall(__NR_move_mount, m, "", t, "f1",
MOVE_MOUNT_F_EMPTY_PATH))
die("move_mount");
close(m);
fd_a = openat(t, ".", O_PATH | O_DIRECTORY | O_CLOEXEC);
if (fd_a < 0)
die("open A'");
publish(fd_a);
usleep(200 + rand() % 1000);
close(t); /* A' is unmounted, fd_a holds it */
usleep(200 + rand() % 1000);
if (unlinkat(a, "f1", 0)) /* through A, a plain file there */
die("unlink f1");
atomic_fetch_add(&n_unlink, 1);
usleep(rand() % 300);
publish(-1);
}
close(a);
umount2(ADIR, MNT_DETACH);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t d, *w;
int c, i;
setvbuf(stdout, NULL, _IOLBF, 0);
while ((c = getopt(argc, argv, "t:w:")) != -1) {
switch (c) {
case 't':
duration = atoi(optarg);
break;
case 'w':
nwalkers = atoi(optarg);
break;
default:
fprintf(stderr, "usage: unlink_covered [-t seconds] [-w walkers]\n");
return 2;
}
}
if (unshare(CLONE_NEWNS) ||
mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL))
die("unshare");
if (mkdir(WORK, 0755) && errno != EEXIST)
die("mkdir");
w = calloc(nwalkers, sizeof(*w));
for (i = 0; i < nwalkers; i++)
if (pthread_create(&w[i], NULL, walker, (void *)(long)i))
die("pthread_create");
if (pthread_create(&d, NULL, driver, NULL))
die("pthread_create");
sleep(duration);
atomic_store(&stop, 1);
pthread_join(d, NULL);
for (i = 0; i < nwalkers; i++)
pthread_join(w[i], NULL);
printf("unlink_covered: %d s, %d walkers: unlinks %ld walks %ld mark %ld enoent %ld other %ld SECRET %ld (lockless %ld)\n",
duration, nwalkers, atomic_load(&n_unlink), atomic_load(&n_walk),
atomic_load(&n_mark), atomic_load(&n_enoent),
atomic_load(&n_other), atomic_load(&n_secret),
atomic_load(&n_secret_cached));
return atomic_load(&n_secret) ? 1 : 0;
}
# diff --git a/fs/namei.c b/fs/namei.c
# --- a/fs/namei.c
# +++ b/fs/namei.c
# @@ -35,6 +35,7 @@
# #include <linux/fcntl.h>
# #include <linux/device_cgroup.h>
# #include <linux/fs_struct.h>
# +#include <linux/delay.h>
# #include <linux/posix_acl.h>
# #include <linux/hash.h>
# #include <linux/bitops.h>
# @@ -1205,9 +1206,26 @@ static int sysctl_protected_symlinks __read_mostly;
# static int sysctl_protected_hardlinks __read_mostly;
# static int sysctl_protected_fifos __read_mostly;
# static int sysctl_protected_regular __read_mostly;
# +/* debug: widen the two windows of the detach_mounts() race */
# +static int sysctl_detach_race_walk_us __read_mostly;
# +static int sysctl_detach_race_unlink_us __read_mostly;
#
# #ifdef CONFIG_SYSCTL
# static const struct ctl_table namei_sysctls[] = {
# + {
# + .procname = "detach_race_walk_us",
# + .data = &sysctl_detach_race_walk_us,
# + .maxlen = sizeof(int),
# + .mode = 0644,
# + .proc_handler = proc_dointvec,
# + },
# + {
# + .procname = "detach_race_unlink_us",
# + .data = &sysctl_detach_race_unlink_us,
# + .maxlen = sizeof(int),
# + .mode = 0644,
# + .proc_handler = proc_dointvec,
# + },
# {
# .procname = "protected_symlinks",
# .data = &sysctl_protected_symlinks,
# @@ -1878,6 +1896,10 @@ static struct dentry *lookup_fast(struct nameidata *nd)
# dentry = __d_lookup(parent, &nd->last);
# if (unlikely(!dentry))
# return NULL;
# + /* debug: between finding a mountpoint and crossing its mounts */
# + if (unlikely(sysctl_detach_race_walk_us) && d_mountpoint(dentry))
# + usleep_range(sysctl_detach_race_walk_us,
# + sysctl_detach_race_walk_us + 10);
# status = d_revalidate(nd->inode, &nd->last, dentry, nd->flags);
# }
# if (unlikely(status <= 0)) {
# @@ -5693,6 +5715,10 @@ int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir,
# if (!error) {
# dont_mount(dentry);
# detach_mounts(dentry);
# + /* debug: the mounts are gone, d_delete() is still to come */
# + if (unlikely(sysctl_detach_race_unlink_us))
# + usleep_range(sysctl_detach_race_unlink_us,
# + sysctl_detach_race_unlink_us + 10);
# }
# }
# }
Fixes: 8ed936b5671b ("vfs: Lazily remove mounts on unlinked files and directories.")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-2-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namei.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2087,6 +2087,33 @@ all_done: // pure jump
}
/*
+ * Be careful in case the dentry is unlinked or renamed. Any mounts
+ * stacked on top of it are going away. We need to make sure that we
+ * don't reveal the underyling dentry during refwalk. In rcuwalk we
+ * catch this via d_seq and another lookup for the name. Give the same
+ * guarantee in refwalk.
+ */
+static bool unlink_may_reveal(struct nameidata *nd, int flags,
+ struct path *path, struct dentry *dentry)
+{
+ /* ".." and LOOKUP_DOWN may land on an unhashed directory */
+ if (flags & WALK_NOFOLLOW)
+ return false;
+ if (nd->flags & LOOKUP_REVAL)
+ return false;
+ /* We crossed onto a mount and the name led us here while it still existed */
+ if (path->mnt != nd->path.mnt)
+ return false;
+ /* only a name on its way out is flagged */
+ if (likely(!cant_mount(dentry)))
+ return false;
+ if (!d_unlinked(dentry))
+ return false;
+ dput(no_free_ptr(path->dentry));
+ return true;
+}
+
+/*
* Do we need to follow links? We _really_ want to be able
* to do this check without having to look at inode->i_op,
* so we keep a cache of "no, this doesn't need follow_link"
@@ -2115,6 +2142,8 @@ static noinline const char *step_into_sl
if (unlikely(!inode))
return ERR_PTR(-ENOENT);
} else {
+ if (unlikely(unlink_may_reveal(nd, flags, &path, dentry)))
+ return ERR_PTR(-ESTALE);
dput(nd->path.dentry);
if (nd->path.mnt != path.mnt)
mntput(nd->path.mnt);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 168/281] fcntl: refuse F_SET_RW_HINT on an immutable inode
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (166 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 167/281] namei: dont reveal overmounted entries in refwalk Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 169/281] namespace: refuse an automount below a mount that is in no namespace Greg Kroah-Hartman
` (119 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit b0d1022b9bdb1e98aa7fb3244fdd50a58c61766c upstream.
An immutable inode is never written to so write hints are pointless.
Refuse the hint on an immutable inode the way setattr(), fallocate() and
etxattr() refuse their changes.
Fixes: c75b1d9421f8 ("fs: add fcntl() interface for setting/getting write life time hints")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-3-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/fcntl.c | 3 +++
1 file changed, 3 insertions(+)
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -372,6 +372,9 @@ static long fcntl_set_rw_hint(struct fil
u64 __user *argp = (u64 __user *)arg;
u64 hint;
+ /* nothing is ever written to it */
+ if (IS_IMMUTABLE(inode))
+ return -EPERM;
if (!inode_owner_or_capable(file_mnt_idmap(file), inode))
return -EPERM;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 169/281] namespace: refuse an automount below a mount that is in no namespace
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (167 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 168/281] fcntl: refuse F_SET_RW_HINT on an immutable inode Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 170/281] nullfs: dont update the access time Greg Kroah-Hartman
` (118 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit ba985ce08471c555af2a2fbe217c1bc2e72a6d8c upstream.
It's possible to add autmounts even when the parent mount isn't in the
mount namespace of the caller. The only requirement we have is that the
parent mount namespace must not be NULL, i.e., unmounted.
Problem is that clone_private_mount() has MNT_NS_INTERNAL which makes
that trivially true. So that passes the test and attach_recursive_mnt()
accepts that as a mount point and funny enough, count_mounts()
dereferences MNT_NS_INTERNAL. The problem is it is an error pointer...
So we can reach this in userspace via fanotify. A filesystem mark on the
lower filesystem of an overlay reports paths on the layer clone and
reading the event hands out a descriptor on it. For example with debugfs
as the lower layer it goes kaboom:
openat(evfd, "tracing", O_DIRECTORY)
Oops: general protection fault
KASAN: null-ptr-deref in range [0x1d0-0x1d7]
RIP: 0010:count_mounts+0x35/0x200
attach_recursive_mnt
finish_automount
And since that sleeping beauty happens under namespace_sem held for
writing every mount operation on the system blocks from then on.
Congrats.
Use is_mounted() instead which rejects unmounted and internal mounts
alike. The open fails with EINVAL just as it did before
clone_private_mount() used MNT_NS_INTERNAL.
Fixes: df820f8de4e4 ("ovl: make private mounts longterm")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-5-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3784,7 +3784,7 @@ static int do_add_mount(struct mount *ne
if (!(mnt_flags & MNT_SHRINKABLE))
return -EINVAL;
/* ... and for those we'd better have mountpoint still alive */
- if (!parent->mnt_ns)
+ if (!is_mounted(&parent->mnt))
return -EINVAL;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 170/281] nullfs: dont update the access time
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (168 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 169/281] namespace: refuse an automount below a mount that is in no namespace Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 171/281] namespace: never expire a locked mount Greg Kroah-Hartman
` (117 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit caf16f9b4aa66e5092f95e98cda54f2bb7482ed2 upstream.
There's no point in updating access times of the nullfs instance. Raise
S_IMMUTABLE.
Fixes: 9d4e752a24f7 ("namespace: allow creating empty mount namespaces")
Cc: stable@vger.kernel.org # v7.1+
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-7-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/nullfs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/nullfs.c
+++ b/fs/nullfs.c
@@ -30,8 +30,8 @@ static int nullfs_fs_fill_super(struct s
make_empty_dir_inode(inode);
simple_inode_init_ts(inode);
inode->i_ino = 1;
- /* ... and immutable. */
- inode->i_flags |= S_IMMUTABLE;
+ /* ... and immutable, reading it leaves no trace either. */
+ inode->i_flags |= S_IMMUTABLE | S_NOATIME;
s->s_root = d_make_root(inode);
if (!s->s_root)
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 171/281] namespace: never expire a locked mount
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (169 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 170/281] nullfs: dont update the access time Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 172/281] namespace: handle mount locking for automounts correctly Greg Kroah-Hartman
` (116 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit f78ddcc872248c7aa1d7e904928441a0be4c6d5d upstream.
Locked mounts are special. They protect the underlying files and
directories from being revealed. do_umount() refuses to unmount locked
mounts but shrink_submounts() doesn't.
A shrinkable mount can become locked once the owner of a user namespace
puts it beneath a locked mount with MOVE_MOUNT_BENEATH. The locked
property now moves to the mount at the bottom making it possible to
unmount the top mount.
So umount() of an unlocked ancestor now expires the bottom mount first
and the covered directory is revealed:
move_mount(c -> x/hidden, MOVE_MOUNT_BENEATH) = 0
the cover after the lock moved: umount2(x/hidden) = 0
the holder of the lock: umount2(x/hidden) = EINVAL
the root of the copy, busy: umount2(x) = EBUSY
reads x/hidden/secret: "covered-by-root"
So leave a locked mount alone as it dies together with its parent. A
plain umount() of an unlocked mount with a locked one below it is EBUSY
from now on. It's the same for any other locked child. A lazy umount
still takes the whole tree.
mark_mounts_for_expiry() never sees a locked mount. lock_mnt_tree()
leaves a mount on an expiry list alone and nothing else puts a locked
one on such a list. Add an assert for this.
Fixes: 5ff9d8a65ce8 ("vfs: Lock in place mounts from more privileged users")
Fixes: c62a4766937e ("move_mount: transfer MNT_LOCKED")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-8-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3994,6 +3994,8 @@ void mark_mounts_for_expiry(struct list_
list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
if (!is_mounted(&mnt->mnt))
continue;
+ /* lock_mnt_tree() leaves expirable mounts alone */
+ VFS_WARN_ON_ONCE(IS_MNT_LOCKED(mnt));
if (!xchg(&mnt->mnt_expiry_mark, 1) ||
propagate_mount_busy(mnt, 1))
continue;
@@ -4020,7 +4022,8 @@ EXPORT_SYMBOL_GPL(mark_mounts_for_expiry
*/
static bool shrink_submount(struct mount *mnt)
{
- if (propagate_mount_busy(mnt, 1))
+ /* not the kernel's to remove either */
+ if (IS_MNT_LOCKED(mnt) || propagate_mount_busy(mnt, 1))
return false;
touch_mnt_namespace(mnt->mnt_ns);
umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 172/281] namespace: handle mount locking for automounts correctly
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (170 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 171/281] namespace: never expire a locked mount Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 173/281] namespace: keep the lock on a mount that a propagated copy is moved beneath Greg Kroah-Hartman
` (115 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit 33aadc7c72055fca93cb5a3691d836ebf8b31c9b upstream.
If mounts are propagated across user namespaces, attach_recursive_mnt()
locks every copy of the source mount to protect overmounts from
vanishing and revealing the underlying files or directories.
The user namespace is taken from the caller's mount namespaces since
this is where the mounts end up. Except, that's not always true.
Automounts may legitimately get popped in by tasks located in a
different mount and user namespace during path lookup.
Then check doesn't make sense at that point. The copy in the namespace
of the parent - which may be the host's - is now locked and the host
cannot change the flags of its own mounts anymore.
Here's the reproducer:
- host has debugfs mounted nosuid,nodev,noexec and shared
- tracefs automount below it is not yet active
- hand a child process a directory descriptor on that mount
- child process enters auser and mount namespace
- child process' namespace now holds a locked copy of the host's debugfs
mount that receives propagation from it
- child process stats "tracing/." through the descriptor
- lookup runs on the host's mount so the automount lands below the host's mount
- propagation puts a copy below the child's copy
- both try to clear the flags on the mount they got, with a bind remount:
host, on its own automount: MS_REMOUNT|MS_BIND = EPERM
child, on the copy in its namespace: MS_REMOUNT|MS_BIND = 0
So the lock landed on the host's mount instead of the child's copy.
Congrats. So we need to compare with the owner of the namespace the
mount actually gets mounted on. For all regular cases that is the
caller's mount namespace and so nothing changes.
Detached trees in anonymous mount namespaces by be handed over via
SCM_RIGHTS or inherited in other ways on purpose so the attaching task's
mount namespace is authoritative, not the creator of the detached tree.
Fixes: 132c94e31b8b ("vfs: Carefully propogate mounts across user namespaces")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-6-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2589,11 +2589,11 @@ enum mnt_tree_flags_t {
static int attach_recursive_mnt(struct mount *source_mnt,
const struct pinned_mountpoint *dest)
{
- struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
struct mount *dest_mnt = dest->parent;
struct mountpoint *dest_mp = dest->mp;
HLIST_HEAD(tree_list);
struct mnt_namespace *ns = dest_mnt->mnt_ns;
+ struct user_namespace *user_ns = ns->user_ns;
struct pinned_mountpoint root = {};
struct mountpoint *shorter = NULL;
struct mount *child, *p;
@@ -2603,6 +2603,22 @@ static int attach_recursive_mnt(struct m
bool moving = mnt_has_parent(source_mnt);
/*
+ * A caller in an unprivileged mount namespaces may trigger an
+ * automount and propagate locked mounts into privileged mount
+ * namespaces. Take ownership from the target mount namespace.
+ * It's equivalent for everything but the automount case.
+ *
+ * Detached trees in anonymous mount namespaces by be handed
+ * over via SCM_RIGHTS or inherited in other ways on purpose
+ * the attaching task's mount namespace is authoritative, not
+ * the creator of the detached tree.
+ */
+ if (is_anon_ns(ns))
+ user_ns = current->nsproxy->mnt_ns->user_ns;
+ else
+ user_ns = ns->user_ns;
+
+ /*
* Preallocate a mountpoint in case the new mounts need to be
* mounted beneath mounts on the same mountpoint.
*/
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 173/281] namespace: keep the lock on a mount that a propagated copy is moved beneath
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (171 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 172/281] namespace: handle mount locking for automounts correctly Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 174/281] xfs: stop exchanging reflink flags when exchanging mappings Greg Kroah-Hartman
` (114 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
commit d74d66aa708ccf2bc0b1e265a83fed0f2308d5c4 upstream.
attach_recursive_mnt() transfers MNT_LOCKED from the top mount to the
mount that is moved beneath it with MOVE_MOUNT_BENEATH. This allows the
owner of a user namespace to replace its locked /proc or its root. The
mount beneath takes on the job of covering the underlying mountpoint
allowing the top mount to be unmounted.
Consider two mount namespaces:
(H) The host H has a shared mount P with a secret in P/d
(Z) Z is a user namespace made from M. Its copy of P receives
propagation from the host's P and its copy of M's cover on P/d is
locked Z's owner must not get to see P/d.
Now (H) mounts X on P/d. This propagates into (Z). The copy of X lands
beneath (Z)'s locked cover. The locked property is transfered from (Z)'s
cover to the copy of X propagated beneath it. The cover is now unlocked.
Now (H) unmounts X again. The copy of X in (Z) gets unmounted and the
covering mount is left unlocked on top of P/d. (Z) can now unmount it:
Z: umount2(P/d) = EINVAL /* the cover is locked */
H: mount X on P/d, umount X /* both propagate into Z /*
Z: umount2(P/d) = 0 /* the cover is now unlocked */
Z: read P/d/secret = "covered-by-root" /* secret revealed */
So only transfer the locked property to the mount beneath for mounts the
caller has placed. A propagated copy that lands beneath a locked mount
is locked as well so that the mount at the bottom of the stack carries a
lock the way every check expects. The mount on top of it remains locked
to ensure that it keeps covering even if the propagated mount is
unmounted again.
Fixes: c62a4766937e ("move_mount: transfer MNT_LOCKED")
Cc: stable@vger.kernel.org # v7.1+
Link: https://patch.msgid.link/20261002-work-mount-fixes-4-v1-9-dd44b89d44ce@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/namespace.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2697,15 +2697,17 @@ static int attach_recursive_mnt(struct m
/*
* If @q was locked it was meant to hide
* whatever was under it. Let @child take over
- * that job and lock it, then we can unlock @q.
- * That'll allow another namespace to shed @q
- * and reveal @child. Clearly, that mounter
- * consented to this by not severing the mount
- * relationship. Otherwise, what's the point.
+ * that job and lock it. If @child is the mount
+ * the caller placed we can then unlock @q:
+ * nothing another namespace does removes it
+ * again. A propagated copy goes away when the
+ * mounter of the original unmounts it, so @q
+ * keeps its lock.
*/
if (IS_MNT_LOCKED(q)) {
child->mnt.mnt_flags |= MNT_LOCKED;
- q->mnt.mnt_flags &= ~MNT_LOCKED;
+ if (child == source_mnt)
+ q->mnt.mnt_flags &= ~MNT_LOCKED;
}
mnt_change_mountpoint(r, mp, q);
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 174/281] xfs: stop exchanging reflink flags when exchanging mappings
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (172 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 173/281] namespace: keep the lock on a mount that a propagated copy is moved beneath Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 175/281] xfs: fix exchange-range-to-eof file size exchange Greg Kroah-Hartman
` (113 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Dave Chinner,
Darrick J. Wong, Carlos Maiolino, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Norbert Szetei <norbert@doyensec.com>
[ Upstream commit d84d6c1a7f1e2de9e601703a326a4c1b7b421943 ]
When an exchange covers both files from offset 0 to i_disk_size,
xmi_can_exchange_reflink_flags() assumes every mapping moved and hands
the reflink flag over to the other file.
That assumption is wrong. A file can still own shared blocks past
i_disk_size, e.g. after EXCHANGE_RANGE_TO_EOF sets a smaller size
without unmapping anything. The flag is cleared anyway, and the next
write to such a block happens in place instead of CoW, corrupting the
other file that shares it.
Commit a23eca88448e ("xfs: fix exchange-range reflink flag clearing
issue with INO1_WRITTEN") fixed one instance of this. Rather than add
another special case, stop moving the flags.
xfs_exchmaps_ensure_reflink() already sets the flag on both inodes
before the exchange, so both just keep it.
Nothing sets CLEAR_INO{1,2}_REFLINK anymore. Intents logged by older
kernels may still carry them; recovery already masks them off, so they
stay in the log format mask and are ignored.
XFS_IOC_SWAPEXT has the same problem: it moves the reflink flag from
one inode to the other along with the extents. Just removing that is
not enough here: the exchange path flags both inodes up front in
xfs_exchmaps_ensure_reflink(), but swapext has no such step, so the
inode receiving the shared extents would be left without the flag.
Set it on both inodes instead, and make sure both have a CoW fork,
since an inode with the reflink flag is expected to have one.
The flag now stays until FALLOC_FL_UNSHARE_RANGE, xfs_scrub, or a
truncate to zero removes it.
Fixes: 966ceafc7a43 ("xfs: create deferred log items for file mapping exchanges")
Fixes: f0bc4d134b46 ("xfs: swap inode reflink flags when swapping inode extents")
Cc: stable@vger.kernel.org # v6.10
Assisted-by: LLM
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
[ sashal: Removed an extra duplicate INO1_WRITTEN guard when deleting xmi_can_exchange_reflink_flags(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_exchmaps.c | 90 +----------------------------------------
fs/xfs/libxfs/xfs_log_format.h | 4 -
fs/xfs/xfs_bmap_util.c | 15 ++----
3 files changed, 10 insertions(+), 99 deletions(-)
--- a/fs/xfs/libxfs/xfs_exchmaps.c
+++ b/fs/xfs/libxfs/xfs_exchmaps.c
@@ -49,7 +49,7 @@ struct xfs_exchmaps_adjacent {
.right2 = { .br_startblock = HOLESTARTBLOCK }, \
}
-/* Information to reset reflink flag / CoW fork state after an exchange. */
+/* Information to reset CoW fork state after an exchange. */
/*
* If the reflink flag is set on either inode, make sure it has an incore CoW
@@ -127,9 +127,7 @@ xmi_has_more_exchange_work(const struct
static inline bool
xmi_has_postop_work(const struct xfs_exchmaps_intent *xmi)
{
- return xmi->xmi_flags & (XFS_EXCHMAPS_CLEAR_INO1_REFLINK |
- XFS_EXCHMAPS_CLEAR_INO2_REFLINK |
- __XFS_EXCHMAPS_INO2_SHORTFORM);
+ return xmi->xmi_flags & __XFS_EXCHMAPS_INO2_SHORTFORM;
}
/* Check all mappings to make sure we can actually exchange them. */
@@ -525,18 +523,6 @@ free:
return error;
}
-/* Clear the reflink flag after an exchange. */
-static inline void
-xfs_exchmaps_clear_reflink(
- struct xfs_trans *tp,
- struct xfs_inode *ip)
-{
- trace_xfs_reflink_unset_inode_flag(ip);
-
- ip->i_diflags2 &= ~XFS_DIFLAG2_REFLINK;
- xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-}
-
/* Finish whatever work might come after an exchange operation. */
static int
xfs_exchmaps_do_postop_work(
@@ -557,16 +543,6 @@ xfs_exchmaps_do_postop_work(
return error;
}
- if (xmi->xmi_flags & XFS_EXCHMAPS_CLEAR_INO1_REFLINK) {
- xfs_exchmaps_clear_reflink(tp, xmi->xmi_ip1);
- xmi->xmi_flags &= ~XFS_EXCHMAPS_CLEAR_INO1_REFLINK;
- }
-
- if (xmi->xmi_flags & XFS_EXCHMAPS_CLEAR_INO2_REFLINK) {
- xfs_exchmaps_clear_reflink(tp, xmi->xmi_ip2);
- xmi->xmi_flags &= ~XFS_EXCHMAPS_CLEAR_INO2_REFLINK;
- }
-
return 0;
}
@@ -948,56 +924,13 @@ xfs_exchmaps_intent_destroy_cache(void)
}
/*
- * Decide if we will exchange the reflink flags between the two files after the
- * exchange. The only time we want to do this is if we're exchanging all
- * mappings under EOF and the inode reflink flags have different states.
+ * Allocate and initialize a new incore intent item from a request.
*/
-static inline bool
-xmi_can_exchange_reflink_flags(
- const struct xfs_exchmaps_req *req,
- unsigned int reflink_state)
-{
- struct xfs_mount *mp = req->ip1->i_mount;
-
- /*
- * The INO1_WRITTEN optimization can skip exchanging hole and
- * unwritten mappings, which means we cannot guarantee that all
- * shared extents actually moved to the other file. Clearing the
- * reflink flag of an inode that still holds shared extents breaks
- * the CoW write path, so refuse to exchange the flags in that case.
- */
- if (req->flags & XFS_EXCHMAPS_INO1_WRITTEN)
- return false;
-
- /*
- * The INO1_WRITTEN optimization can skip exchanging hole and
- * unwritten mappings, which means we cannot guarantee that all
- * shared extents actually moved to the other file. Clearing the
- * reflink flag of an inode that still holds shared extents breaks
- * the CoW write path, so refuse to exchange the flags in that case.
- */
- if (req->flags & XFS_EXCHMAPS_INO1_WRITTEN)
- return false;
-
- if (hweight32(reflink_state) != 1)
- return false;
- if (req->startoff1 != 0 || req->startoff2 != 0)
- return false;
- if (req->blockcount != XFS_B_TO_FSB(mp, req->ip1->i_disk_size))
- return false;
- if (req->blockcount != XFS_B_TO_FSB(mp, req->ip2->i_disk_size))
- return false;
- return true;
-}
-
-
-/* Allocate and initialize a new incore intent item from a request. */
struct xfs_exchmaps_intent *
xfs_exchmaps_init_intent(
const struct xfs_exchmaps_req *req)
{
struct xfs_exchmaps_intent *xmi;
- unsigned int rs = 0;
xmi = kmem_cache_zalloc(xfs_exchmaps_intent_cache,
GFP_NOFS | __GFP_NOFAIL);
@@ -1021,23 +954,6 @@ xfs_exchmaps_init_intent(
xmi->xmi_isize2 = req->ip1->i_disk_size;
}
- /* Record the state of each inode's reflink flag before the op. */
- if (xfs_is_reflink_inode(req->ip1))
- rs |= 1;
- if (xfs_is_reflink_inode(req->ip2))
- rs |= 2;
-
- /*
- * Figure out if we're clearing the reflink flags (which effectively
- * exchanges them) after the operation.
- */
- if (xmi_can_exchange_reflink_flags(req, rs)) {
- if (rs & 1)
- xmi->xmi_flags |= XFS_EXCHMAPS_CLEAR_INO1_REFLINK;
- if (rs & 2)
- xmi->xmi_flags |= XFS_EXCHMAPS_CLEAR_INO2_REFLINK;
- }
-
if (S_ISDIR(VFS_I(xmi->xmi_ip2)->i_mode) ||
S_ISLNK(VFS_I(xmi->xmi_ip2)->i_mode))
xmi->xmi_flags |= __XFS_EXCHMAPS_INO2_SHORTFORM;
--- a/fs/xfs/libxfs/xfs_log_format.h
+++ b/fs/xfs/libxfs/xfs_log_format.h
@@ -927,10 +927,8 @@ struct xfs_xmi_log_format {
*/
#define XFS_EXCHMAPS_INO1_WRITTEN (1ULL << 2)
-/* Clear the reflink flag from inode1 after the operation. */
+/* No longer set, but older intents may carry them; keep them valid. */
#define XFS_EXCHMAPS_CLEAR_INO1_REFLINK (1ULL << 3)
-
-/* Clear the reflink flag from inode2 after the operation. */
#define XFS_EXCHMAPS_CLEAR_INO2_REFLINK (1ULL << 4)
#define XFS_EXCHMAPS_LOGGED_FLAGS (XFS_EXCHMAPS_ATTR_FORK | \
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1514,7 +1514,6 @@ xfs_swap_extents(
struct xfs_bstat *sbp = &sxp->sx_stat;
int src_log_flags, target_log_flags;
int error = 0;
- uint64_t f;
int resblks = 0;
unsigned int flags = 0;
struct timespec64 ctime, mtime;
@@ -1670,14 +1669,12 @@ xfs_swap_extents(
if (error)
goto out_trans_cancel;
- /* Do we have to swap reflink flags? */
- if ((ip->i_diflags2 & XFS_DIFLAG2_REFLINK) ^
- (tip->i_diflags2 & XFS_DIFLAG2_REFLINK)) {
- f = ip->i_diflags2 & XFS_DIFLAG2_REFLINK;
- ip->i_diflags2 &= ~XFS_DIFLAG2_REFLINK;
- ip->i_diflags2 |= tip->i_diflags2 & XFS_DIFLAG2_REFLINK;
- tip->i_diflags2 &= ~XFS_DIFLAG2_REFLINK;
- tip->i_diflags2 |= f & XFS_DIFLAG2_REFLINK;
+ /* Either inode may now own shared blocks; flag both, with CoW forks. */
+ if ((ip->i_diflags2 | tip->i_diflags2) & XFS_DIFLAG2_REFLINK) {
+ ip->i_diflags2 |= XFS_DIFLAG2_REFLINK;
+ tip->i_diflags2 |= XFS_DIFLAG2_REFLINK;
+ xfs_ifork_init_cow(ip);
+ xfs_ifork_init_cow(tip);
}
/* Swap the cow forks. */
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 175/281] xfs: fix exchange-range-to-eof file size exchange
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (173 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 174/281] xfs: stop exchanging reflink flags when exchanging mappings Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 176/281] clk: qcom: gcc-eliza: Fix always-enabling PCIE_RSCC clocks Greg Kroah-Hartman
` (112 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Darrick J. Wong,
Dave Chinner, Carlos Maiolino, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Darrick J. Wong" <djwong@kernel.org>
[ Upstream commit 7dfb218c829c1acb626e0fe92c5fddb9a26a03e9 ]
Norbert Szetei posted a patch containing an incomplete description of a
bug in XFS_IOC_EXCHANGE_RANGE's TO_EOF flag. The bug tricks
exchange-range into modifying a file so that it has shared blocks
starting beyond EOF, which is never allowed because files never have
written data beyond EOF, and you can only share written data blocks.
This is key to all the incorrect behavior that follows.
Eventually I got from Norbert a description of what's going wrong:
> Fair. Here it is with physical block numbers, 4k blocks. peer is the file
> that gets rewritten and file1 is the one that ends up with the flag
> cleared.
>
> Start, nothing shared:
>
> peer size 4096 -> [100]
> file1 size 12288 -> [200] [201] [202]
> donor1 size 4096 -> [300]
> donor2 size 4096 -> [400]
>
> 1. FICLONERANGE peer's block into file1's middle slot:
>
> peer size 4096 -> [100]
> file1 size 12288 -> [200] [100] [202] reflink flag set
> ^^^^^ both files own block 100
>
> 2. XFS_IOC_EXCHANGE_RANGE file1 against donor1, file1_offset 0,
> file2_offset 8192, length 0, TO_EOF. One block is exchanged, and the sizes
> are exchanged with it:
>
> file1 size 4096 -> [200] [100] [300] reflink flag set
> ^^^^^^^^^^^ still owned, now past the size
> donor1 size 12288 -> [202]
>
> file1 says it is one block long while it still owns three. Nothing was
> unmapped. file2_offset is block 2, so this exchange cannot clear a flag.
>
> 3. XFS_IOC_EXCHANGE_RANGE file1 against donor2, both offsets 0, length 4096.
> By i_disk_size this is two one-block files exchanging everything, so
> xmi_can_exchange_reflink_flags() agrees and the flag is cleared:
>
> file1 size 4096 -> [400] [100] [300] reflink flag CLEARED
> donor2 size 4096 -> [200]
>
> Block 100 is still shared with peer.
>
> 4. pwrite(file1, 4096, 4096), which is file1's second slot, block 100.
> xfs_is_cow_inode(file1) is false, so no CoW:
>
> peer size 4096 -> [100] same block, new contents
>
> Block 100 is the only one that matters here. PoC below, it reads a file
> called peer in the current directory. The filesystem needs reflink and
> exchange-range, which mkfs.xfs 7.x turns on by default.
So yes, TO_EOF is screwing up the file size even if it's actually
exchanging the data block correctly. The following is the intended
behavior of XFS_EXCHANGE_RANGE_TO_EOF, as described by its manpage:
"Ignore the length parameter. All bytes in file1_fd from file1_offset
to EOF are moved to file2_fd, and file2's size is set to
(file2_offset+(file1_length-file1_offset)). Meanwhile, all bytes in
file2 from file2_offset to EOF are moved to file1 and file1's size is
set to (file1_offset+(file2_length-file2_offset))."
In other words, if we only exchange a portion of the file data, then we
should only exchange the portion of the file size that relates to the
exchanged data. Unfortunately, the code swaps the ondisk file size and
the incore file sizes, which is incorrect if the caller passes in a
nonzero offset.
Having confused the file sizes, the PoC uses a second exchange-range
call on what looks like a non-reflinked single-block file. Because the
file size is set incorrectly, exchange-range thinks it's exchanging the
full contents of two files and clears the reflink flag on the broken
file. That enables an extending write of the broken file to rewrite the
shared block that's just past EOF. This has become known colloquially
as refluxfs.
Once the file sizes are set correctly, the second exchange-range no
longer thinks that it's doing a full-contents swap, so it won't clear
the reflink flag on either of its file arguments.
Norbert followed up to an earlier version of this patch with a second
complaint about us not handling the i_disk_size state correctly:
> The offsets are bounded against the incore i_size but subtracted from
> the ondisk i_disk_size, so a file that has not been written back gives
> xmi_isize1 = 0 + (0 - 12288).
>
> For instance, you can do:
>
> $ xfs_io -f -c "pwrite -q 0 4096" -c fsync file1
> $ xfs_io -f -c "pwrite -q 0 12288" \
> -c "exchangerange -s 0 -d 12288 file1" dirty
> $ stat -c %s file1
> 0
> $ stat -c %i file1
> 131
> $ sudo xfs_io -r -c "bulkstat_single 131" . | grep bs_size
> bs_size = 18446744073709539328
That's wrong, and the new file size update logic depends on the ondisk
i_disk_size matching the incore i_size, so flush the pagecache as needed
to push it upwards.
Link: https://lore.kernel.org/linux-xfs/1E196589-DEBE-40AC-AFEA-D420DAAB067F@doyensec.com/
Reported-by: Norbert Szetei <norbert@doyensec.com>
Cc: stable@vger.kernel.org # v6.10
Fixes: 966ceafc7a4371 ("xfs: create deferred log items for file mapping exchanges")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_exchmaps.c | 13 +++++++++-
fs/xfs/xfs_exchrange.c | 51 +++++++++++++++++++++++++++++++------------
2 files changed, 48 insertions(+), 16 deletions(-)
--- a/fs/xfs/libxfs/xfs_exchmaps.c
+++ b/fs/xfs/libxfs/xfs_exchmaps.c
@@ -931,6 +931,7 @@ xfs_exchmaps_init_intent(
const struct xfs_exchmaps_req *req)
{
struct xfs_exchmaps_intent *xmi;
+ struct xfs_mount *mp = req->ip1->i_mount;
xmi = kmem_cache_zalloc(xfs_exchmaps_intent_cache,
GFP_NOFS | __GFP_NOFAIL);
@@ -948,10 +949,18 @@ xfs_exchmaps_init_intent(
return xmi;
}
+ /*
+ * If the caller wanted, set each file's size to that file's exchange
+ * offset + length exchanged from the other file because the ranges in
+ * each file might be different lengths.
+ */
if (req->flags & XFS_EXCHMAPS_SET_SIZES) {
+ loff_t off1 = XFS_FSB_TO_B(mp, xmi->xmi_startoff1);
+ loff_t off2 = XFS_FSB_TO_B(mp, xmi->xmi_startoff2);
+
xmi->xmi_flags |= XFS_EXCHMAPS_SET_SIZES;
- xmi->xmi_isize1 = req->ip2->i_disk_size;
- xmi->xmi_isize2 = req->ip1->i_disk_size;
+ xmi->xmi_isize1 = off1 + (req->ip2->i_disk_size - off2);
+ xmi->xmi_isize2 = off2 + (req->ip1->i_disk_size - off1);
}
if (S_ISDIR(VFS_I(xmi->xmi_ip2)->i_mode) ||
--- a/fs/xfs/xfs_exchrange.c
+++ b/fs/xfs/xfs_exchrange.c
@@ -290,17 +290,20 @@ retry:
goto out_unlock;
/*
- * If the caller wanted us to exchange the contents of two complete
- * files of unequal length, exchange the incore sizes now. This should
- * be safe because we flushed both files' page caches, exchanged all
- * the mappings, and updated the ondisk sizes.
+ * If the caller wanted, set each file's size to that file's exchange
+ * offset + length exchanged from the other file because the ranges in
+ * each file might be different lengths. This should be safe because
+ * we flushed both files' page caches, exchanged all the mappings, and
+ * updated the ondisk sizes.
*/
if (fxr->flags & XFS_EXCHANGE_RANGE_TO_EOF) {
- loff_t temp;
+ loff_t old_ip1_size = i_size_read(VFS_I(ip1));
+ loff_t old_ip2_size = i_size_read(VFS_I(ip2));
- temp = i_size_read(VFS_I(ip2));
- i_size_write(VFS_I(ip2), i_size_read(VFS_I(ip1)));
- i_size_write(VFS_I(ip1), temp);
+ i_size_write(VFS_I(ip2), fxr->file2_offset +
+ (old_ip1_size - fxr->file1_offset));
+ i_size_write(VFS_I(ip1), fxr->file1_offset +
+ (old_ip2_size - fxr->file2_offset));
}
out_unlock:
@@ -445,6 +448,30 @@ xfs_exchange_range_checks(
return blen == fxr->length ? 0 : -EINVAL;
}
+/* Flush all relevant dirty pagecache near the range to be exchanged. */
+static inline int
+xfs_exchange_range_flush(
+ struct xfs_inode *ip,
+ const struct xfs_exchrange *fxr,
+ loff_t offset)
+{
+ /*
+ * If TO_EOF is set, the ondisk file size update logic depends on the
+ * ondisk file size matching the incore file size. Flush everything.
+ */
+ if (fxr->flags & XFS_EXCHANGE_RANGE_TO_EOF)
+ return filemap_write_and_wait(VFS_I(ip)->i_mapping);
+
+ /*
+ * Because we're updating the ondisk mappings, flush all dirty data
+ * between the ondisk size and the exchange offset to reduce the chance
+ * of zeroed file contents in that gap after a crash.
+ */
+ return filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
+ min(offset, ip->i_disk_size),
+ offset + fxr->length - 1);
+}
+
/*
* Check that the two inodes are eligible for range exchanges, the ranges make
* sense, and then flush all dirty data. Caller must ensure that the inodes
@@ -470,15 +497,11 @@ xfs_exchange_range_prep(
if (!same_inode)
inode_dio_wait(inode2);
- error = filemap_write_and_wait_range(inode1->i_mapping,
- fxr->file1_offset,
- fxr->file1_offset + fxr->length - 1);
+ error = xfs_exchange_range_flush(XFS_I(inode1), fxr, fxr->file1_offset);
if (error)
return error;
- error = filemap_write_and_wait_range(inode2->i_mapping,
- fxr->file2_offset,
- fxr->file2_offset + fxr->length - 1);
+ error = xfs_exchange_range_flush(XFS_I(inode2), fxr, fxr->file2_offset);
if (error)
return error;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 176/281] clk: qcom: gcc-eliza: Fix always-enabling PCIE_RSCC clocks
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (174 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 175/281] xfs: fix exchange-range-to-eof file size exchange Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 177/281] clk: qcom: gcc-kaanapali: " Greg Kroah-Hartman
` (111 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luca Weiss, Abel Vesa,
Bjorn Andersson, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luca Weiss <luca.weiss@fairphone.com>
[ Upstream commit 5ffd02d16f4e2f0566b8f31d5610538987e1944c ]
The critical_cbrcrs array will get qcom_branch_set_clk_en() called on
each entry which will set BIT(0) to enable the clock. This is however
wrong for these two PCIE_RSCC clocks which need BIT(20) and BIT(21) set
respectively to enable them.
Fixes: 3d356ab4a1ec ("clk: qcom: Add support for Global clock controller on Eliza")
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Tested-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260807-various-pcie-clk-fix-v1-1-5caf78a599d7@fairphone.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/clk/qcom/gcc-eliza.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/qcom/gcc-eliza.c b/drivers/clk/qcom/gcc-eliza.c
index 3e26c7a1e5b54..fe18942a59ac4 100644
--- a/drivers/clk/qcom/gcc-eliza.c
+++ b/drivers/clk/qcom/gcc-eliza.c
@@ -3010,8 +3010,6 @@ static const u32 gcc_eliza_critical_cbcrs[] = {
0x26034, /* GCC_CAMERA_XO_CLK */
0x27004, /* GCC_DISP_AHB_CLK */
0x71004, /* GCC_GPU_CFG_AHB_CLK */
- 0x52010, /* GCC_PCIE_RSCC_CFG_AHB_CLK */
- 0x52010, /* GCC_PCIE_RSCC_XO_CLK */
0x32004, /* GCC_VIDEO_AHB_CLK */
0x32038, /* GCC_VIDEO_XO_CLK */
};
@@ -3045,6 +3043,10 @@ static const struct regmap_config gcc_eliza_regmap_config = {
static void clk_eliza_regs_configure(struct device *dev, struct regmap *regmap)
{
+ /* Keep clocks always enabled */
+ regmap_update_bits(regmap, 0x52010, BIT(20), BIT(20)); /* GCC_PCIE_RSCC_CFG_AHB_CLK */
+ regmap_update_bits(regmap, 0x52010, BIT(21), BIT(21)); /* GCC_PCIE_RSCC_XO_CLK */
+
/* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 177/281] clk: qcom: gcc-kaanapali: Fix always-enabling PCIE_RSCC clocks
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (175 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 176/281] clk: qcom: gcc-eliza: Fix always-enabling PCIE_RSCC clocks Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 178/281] clk: qcom: gpucc-glymur: Mark the GPU CX GDSC as votable Greg Kroah-Hartman
` (110 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luca Weiss, Bjorn Andersson,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luca Weiss <luca.weiss@fairphone.com>
[ Upstream commit 0bfb542fc3368371cefb4cf45ef21c3ba2d37c3f ]
The critical_cbrcrs array will get qcom_branch_set_clk_en() called on
each entry which will set BIT(0) to enable the clock. This is however
wrong for these two PCIE_RSCC clocks which need BIT(20) and BIT(21) set
respectively to enable them.
Fixes: d1919c375f21 ("clk: qcom: Add support for Global clock controller on Kaanapali")
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
Link: https://lore.kernel.org/r/20260807-various-pcie-clk-fix-v1-3-5caf78a599d7@fairphone.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/clk/qcom/gcc-kaanapali.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/qcom/gcc-kaanapali.c b/drivers/clk/qcom/gcc-kaanapali.c
index 842c1a70c6916..5bcbcd1786577 100644
--- a/drivers/clk/qcom/gcc-kaanapali.c
+++ b/drivers/clk/qcom/gcc-kaanapali.c
@@ -3464,8 +3464,6 @@ static const u32 gcc_kaanapali_critical_cbcrs[] = {
0x9f004, /* GCC_EVA_AHB_CLK */
0x9f024, /* GCC_EVA_XO_CLK */
0x71004, /* GCC_GPU_CFG_AHB_CLK */
- 0x52010, /* GCC_PCIE_RSCC_CFG_AHB_CLK */
- 0x52010, /* GCC_PCIE_RSCC_XO_CLK */
0x32004, /* GCC_VIDEO_AHB_CLK */
0x32040, /* GCC_VIDEO_XO_CLK */
};
@@ -3480,6 +3478,10 @@ static const struct regmap_config gcc_kaanapali_regmap_config = {
static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap)
{
+ /* Keep clocks always enabled */
+ regmap_update_bits(regmap, 0x52010, BIT(20), BIT(20)); /* GCC_PCIE_RSCC_CFG_AHB_CLK */
+ regmap_update_bits(regmap, 0x52010, BIT(21), BIT(21)); /* GCC_PCIE_RSCC_XO_CLK */
+
/* FORCE_MEM_CORE_ON for ufs phy ice core clocks */
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 178/281] clk: qcom: gpucc-glymur: Mark the GPU CX GDSC as votable
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (176 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 177/281] clk: qcom: gcc-kaanapali: " Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 179/281] clk: qcom: gpucc-kaanapali: " Greg Kroah-Hartman
` (109 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Taniya Das, Jagadeesh Kona,
Bjorn Andersson, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taniya Das <taniya.das@oss.qualcomm.com>
[ Upstream commit 8f3f88309fa4e975ac27368ee945c2c202251a7c ]
The GPU CX GDSC on Glymur is a votable power domain and hence should
not be polled for power-off status during GDSC disable. Also, its
power-on status should be read from the GDS hardware control register.
Accommodate this by removing POLL_CFG_GDSCR and adding the VOTABLE
flag for the GPU CX GDSC, similar to other platforms (e.g. SM8750 and
Milos).
Fixes: 67e645285dd0 ("clk: qcom: Add support for GPUCC and GXCLK for Glymur")
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
Reviewed-by: Jagadeesh Kona <jagadeesh.kona@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260801-kaanapali-gpu-voteable-v1-1-fe804d24d2e9@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/clk/qcom/gpucc-glymur.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/gpucc-glymur.c b/drivers/clk/qcom/gpucc-glymur.c
index 001b2454786a0..cac51de20b295 100644
--- a/drivers/clk/qcom/gpucc-glymur.c
+++ b/drivers/clk/qcom/gpucc-glymur.c
@@ -510,7 +510,7 @@ static struct gdsc gpu_cc_cx_gdsc = {
.name = "gpu_cc_cx_gdsc",
},
.pwrsts = PWRSTS_OFF_ON,
- .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+ .flags = RETAIN_FF_ENABLE | VOTABLE,
};
static struct clk_regmap *gpu_cc_glymur_clocks[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 179/281] clk: qcom: gpucc-kaanapali: Mark the GPU CX GDSC as votable
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (177 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 178/281] clk: qcom: gpucc-glymur: Mark the GPU CX GDSC as votable Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 180/281] arm64: dts: lx2160a: fix incorrect pinmux Greg Kroah-Hartman
` (108 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Taniya Das, Jagadeesh Kona,
Bjorn Andersson, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taniya Das <taniya.das@oss.qualcomm.com>
[ Upstream commit 55981579b27b6541aeeab81c768f248dba0491ac ]
The GPU CX GDSC on Kaanapali is a votable power domain and hence
should not be polled for power-off status during GDSC disable. Also,
its power-on status should be read from the GDS hardware control
register.
Accommodate this by removing POLL_CFG_GDSCR and adding the VOTABLE
flag for the GPU CX GDSC, similar to other platforms (e.g. SM8750 and
Milos).
Fixes: 685ec348339b ("clk: qcom: Add support for GPUCC and GXCLK for Kaanapali")
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
Reviewed-by: Jagadeesh Kona <jagadeesh.kona@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260801-kaanapali-gpu-voteable-v1-2-fe804d24d2e9@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/clk/qcom/gpucc-kaanapali.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/gpucc-kaanapali.c b/drivers/clk/qcom/gpucc-kaanapali.c
index ae5563e516f67..f75f2caa2205c 100644
--- a/drivers/clk/qcom/gpucc-kaanapali.c
+++ b/drivers/clk/qcom/gpucc-kaanapali.c
@@ -380,7 +380,7 @@ static struct gdsc gpu_cc_cx_gdsc = {
.name = "gpu_cc_cx_gdsc",
},
.pwrsts = PWRSTS_OFF_ON,
- .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+ .flags = RETAIN_FF_ENABLE | VOTABLE,
};
static struct clk_regmap *gpu_cc_kaanapali_clocks[] = {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 180/281] arm64: dts: lx2160a: fix incorrect pinmux
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (178 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 179/281] clk: qcom: gpucc-kaanapali: " Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 181/281] arm64: dts: lx2160a: fix IIC1 pinmux submask rejected by pinctrl-single Greg Kroah-Hartman
` (107 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thibaut Collet, Josua Mayer,
Vincent Jardin, Frank Li, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Jardin <vjardin@free.fr>
[ Upstream commit 8188a59dd6782786556b18f515090b79cb701c45 ]
For gpio1 value set for pinctrl is outside the mask and so will do
nothing.
Add the missing offset for value field to be the same as the mask as
expected.
Fixes: 284ad7064aaa ("arm64: dts: lx2160a: complete pinmux for rcwsr12 configuration word")
Suggested-by: Thibaut Collet <thbt.cllt@gmail.com>
Reviewed-by: Josua Mayer <josua@solid-run.com>
Signed-off-by: Vincent Jardin <vjardin@free.fr>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index 1d73abffa6b72..b9f079c49e193 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -1803,7 +1803,7 @@ fspi_data74_pins: xspi1-data74-pins {
};
gpio1_31_28_pins: xspi1-data74-gpio-pins {
- pinctrl-single,bits = <0x0 0x1 (0x7 << 15)>;
+ pinctrl-single,bits = <0x0 (0x1 << 15) (0x7 << 15)>;
};
fspi_data30_pins: xspi1-data30-pins {
@@ -1811,7 +1811,7 @@ fspi_data30_pins: xspi1-data30-pins {
};
gpio1_27_24_pins: xspi1-data30-gpio-pins {
- pinctrl-single,bits = <0x0 0x1 (0x7 << 18)>;
+ pinctrl-single,bits = <0x0 (0x1 << 18) (0x7 << 18)>;
};
fspi_dqs_sck_cs10_pins: xspi1-base-pins {
@@ -1819,7 +1819,7 @@ fspi_dqs_sck_cs10_pins: xspi1-base-pins {
};
gpio1_23_20_pins: xspi1-base-gpio-pins {
- pinctrl-single,bits = <0x0 0x1 (0x7 << 21)>;
+ pinctrl-single,bits = <0x0 (0x1 << 21) (0x7 << 21)>;
};
esdhc0_cmd_data30_clk_vsel_pins: sdhc1-base-sdhc-vsel-pins {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 181/281] arm64: dts: lx2160a: fix IIC1 pinmux submask rejected by pinctrl-single
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (179 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 180/281] arm64: dts: lx2160a: fix incorrect pinmux Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 182/281] arm64: dts: lx2160a: fix the iic5 spi3 pinmux offset and value Greg Kroah-Hartman
` (106 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Jardin, Josua Mayer,
Frank Li, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Jardin <vjardin@free.fr>
[ Upstream commit 6affdda171ca8f2e082e8c4fba56233a2f8c9910 ]
IIC1_PMUX is a single bit field at RCWSR14 bit 10, so the mask for the
two iic1 pinmux nodes was narrowed from 0x7 to 0x1 to avoid writing the
two reserved bits next to it.
With pinctrl-single,bit-per-mux the driver does not take the supplied
mask as the bits to modify. It derives the field from the node's
pinctrl-single,function-mask, which is 0x7 here, and then requires the
supplied mask to match it exactly:
bit_pos = __ffs(mask); /* 10 */
mask_pos = ((pcs->fmask) << bit_pos); /* 0x7 << 10 = 0x1c00 */
submask = mask & mask_pos; /* 0x400 */
...
if (submask != mask_pos) {
dev_warn(pcs->dev,
"Invalid submask 0x%x for %pOFn at 0x%x\n",
submask, np, offset);
continue;
}
A one bit mask gives submask 0x400 against mask_pos 0x1c00, so both
nodes are rejected and the pins are never muxed with this message:
pinctrl-single 70010012c.pinmux: Invalid submask 0x400 for iic1-i2c-pins
pinctrl-single 70010012c.pinmux: Invalid submask 0x400 for iic1-gpio-pins
The values are not changed:
- 0x0 selects IIC1
- 0x1 << 10 selects GPIO_1[3:2].
Fixes: 7a3cc49ad1fc ("arm64: dts: lx2160a: change i2c0 (iic1) pinmux mask to one bit")
Signed-off-by: Vincent Jardin <vjardin@free.fr>
Reviewed-by: Josua Mayer <josua@solid-run.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index b9f079c49e193..8f33dd26577fa 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -1868,12 +1868,19 @@ i2c6_i2c7_pins: iic8-iic7-i2c-pins {
};
/* RCWSR14 */
+ /*
+ * IIC1_PMUX is a single bit at RCWSR14[10], but bit-per-mux
+ * uses the mask for the field to clear before applying the
+ * value.
+ * So bits 11 and 12, which are reserved, are written as 0
+ * on every mux switch, it is harmless.
+ */
i2c0_pins: iic1-i2c-pins {
- pinctrl-single,bits = <0x8 0x0 (0x1 << 10)>;
+ pinctrl-single,bits = <0x8 0x0 (0x7 << 10)>;
};
gpio0_3_2_pins: iic1-gpio-pins {
- pinctrl-single,bits = <0x8 (0x1 << 10) (0x1 << 10)>;
+ pinctrl-single,bits = <0x8 (0x1 << 10) (0x7 << 10)>;
};
};
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 182/281] arm64: dts: lx2160a: fix the iic5 spi3 pinmux offset and value
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (180 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 181/281] arm64: dts: lx2160a: fix IIC1 pinmux submask rejected by pinctrl-single Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 183/281] iommu/dma: skip swiotlb bounce for DMA_ATTR_MMIO in iommu_dma_map_phys Greg Kroah-Hartman
` (105 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josua Mayer, Vincent Jardin,
Frank Li, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Jardin <vjardin@free.fr>
[ Upstream commit f14f4dc8ea3810f8ed4f0f3ea13f8bba3e2b0f04 ]
The iic5-spi3-pins node has both of its first two cells wrong.
The offset selects the register within the node's reg range, where:
0x0 is RCWSR12,
0x4 is RCWSR13,
0x8 is RCWSR14.
An offset of 0x3 is not one of them and is not even aligned for the
declared 32 bit register width. It is the only node in this pinmux that
does not use 0x0, 0x4 neither 0x8.
The value is wrong too:
IIC5_PMUX is RCWSR12[11:9] and it encodes 0b000 for IIC5,
0b001 for GPIO_1[25:24],
0b010 for SDHC1_CLK_SYNC_OUT/IN,
0b011 for {IIC5_SCL,IIC5_SDA} = {SPI3_SOUT,SPI3_SIN}.
This node selects the last of those, so it needs 0x3, not the 0x2, which
is the value of the neighbouring sdhc1 clock sync node it was copied
from.
Fixes: 284ad7064aaa ("arm64: dts: lx2160a: complete pinmux for rcwsr12 configuration word")
Reviewed-by: Josua Mayer <josua@solid-run.com>
Signed-off-by: Vincent Jardin <vjardin@free.fr>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index 8f33dd26577fa..6ead557a8cf19 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -1783,7 +1783,7 @@ esdhc0_clksync_pins: iic5-sdhc-clk-pins {
};
dspi2_miso_mosi_pins: iic5-spi3-pins {
- pinctrl-single,bits = <0x3 (0x2 << 9) (0x7 << 9)>;
+ pinctrl-single,bits = <0x0 (0x3 << 9) (0x7 << 9)>;
};
i2c5_pins: iic6-i2c-pins {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 183/281] iommu/dma: skip swiotlb bounce for DMA_ATTR_MMIO in iommu_dma_map_phys
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (181 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 182/281] arm64: dts: lx2160a: fix the iic5 spi3 pinmux offset and value Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 184/281] mount: refuse MOVE_MOUNT_SET_GROUP on an unbindable mount Greg Kroah-Hartman
` (104 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Peng Fan, Robin Murphy,
Marek Szyprowski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <peng.fan@nxp.com>
[ Upstream commit 057e5e07420c753f248f9ce148040ab6dcf8359f ]
MMIO resources mapped via dma_map_resource() carry DMA_ATTR_MMIO. These
never need swiotlb bounce buffering, but the current code enters the
swiotlb path when the physical address is not page-aligned, then rejects
the mapping because MMIO cannot be bounced.
Move the DMA_ATTR_MMIO check before the swiotlb block so the entire bounce
path is skipped for MMIO, falling through directly to __iommu_dma_map()
which creates the IOVA mapping.
Fixes: f9374de14c0e8 ("iommu/dma: implement DMA_ATTR_MMIO for iommu_dma_(un)map_phys()")
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Acked-by: Robin Murphy <robin.murphy@arm.comn>
Link: https://lore.kernel.org/r/20260916-iommu-dma-fix-v1-1-a59a0c45ec5b@nxp.com
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/dma-iommu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index ae814d8c99c04..5f901b4baf216 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -1228,9 +1228,9 @@ dma_addr_t iommu_dma_map_phys(struct device *dev, phys_addr_t phys, size_t size,
* If both the physical buffer start address and size are page aligned,
* we don't need to use a bounce page.
*/
- if (dev_use_swiotlb(dev, size, dir) &&
+ if (!(attrs & DMA_ATTR_MMIO) && dev_use_swiotlb(dev, size, dir) &&
iova_unaligned(iovad, phys, size)) {
- if (attrs & (DMA_ATTR_MMIO | DMA_ATTR_REQUIRE_COHERENT))
+ if (attrs & DMA_ATTR_REQUIRE_COHERENT)
return DMA_MAPPING_ERROR;
phys = iommu_dma_map_swiotlb(dev, phys, size, dir, attrs);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 184/281] mount: refuse MOVE_MOUNT_SET_GROUP on an unbindable mount
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (182 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 183/281] iommu/dma: skip swiotlb bounce for DMA_ATTR_MMIO in iommu_dma_map_phys Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 185/281] fs: dont let a migrating task hide its reference from do_umount() Greg Kroah-Hartman
` (103 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable),
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit a2b42babc912e4fb428cbb42adb4f6e1e067113d ]
do_set_group() only accepts mounts as targets that are neither shared
nor a slave. That encompasses undindable mounts.
If the source mount is a slave mount the target mount will end up with
source's master as its master. It keeps T_UNBINDABLE. That means we get
a mount that is both unbindable and a slave:
mount --bind /tmp/src /tmp/src
mount --make-shared /tmp/src
mount --bind /tmp/src /tmp/b
mount --make-slave /tmp/b
mount --bind /tmp/src /tmp/c
mount --make-unbindable /tmp/c
move_mount(b, "", c, "", MOVE_MOUNT_SET_GROUP)
grep /tmp/c /proc/self/mountinfo
... /tmp/c ... master:646 unbindable ...
This property cannot be produced any other way. change_mnt_propagation()
drops the master when it makes a mount unbindable (iow, it becomes
private) and doesn't touch an unbindable mount when it is supposed to
turned into a slave mount.
End-result is that the unbindable-slave mount receives everything
propagated from its master's peer group while it can't be bind mounted
itself. Not sure what that's supposed to do.
On the other side: if the source mount is shared, the target mount drops
T_UNBINDABLE because because set_mnt_shared() clears T_SHARED_MASK.
So teach do_set_group() to refuse an unbindable target mount the same
way a shared or slave target mount is refused.
The main user of MOVE_MOUNT_SET_GROUP is CRIU which restores sharing
first and applies MS_UNBINDABLE afterwards. It never hits this.
Link: https://patch.msgid.link/20260923-work-mount-fixes-v1-3-f424cf8d3242@kernel.org
Fixes: 9ffb14ef61ba ("move_mount: allow to add a mount into an existing group")
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/namespace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 472cca0b730d9..010bc659188d4 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3530,7 +3530,7 @@ static int do_set_group(const struct path *from_path, const struct path *to_path
return -EINVAL;
/* Setting sharing groups is only allowed on private mounts */
- if (IS_MNT_SHARED(to) || IS_MNT_SLAVE(to))
+ if (IS_MNT_SHARED(to) || IS_MNT_SLAVE(to) || IS_MNT_UNBINDABLE(to))
return -EINVAL;
/* From should not be private */
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 185/281] fs: dont let a migrating task hide its reference from do_umount()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (183 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 184/281] mount: refuse MOVE_MOUNT_SET_GROUP on an unbindable mount Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 186/281] scsi: ufs: core: Hold a clock reference across the probe Greg Kroah-Hartman
` (102 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable),
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit 7eb84d54fac5002bd975d1de8fd61d57e89172ab ]
propagate_mount_busy() uses mnt_get_count() via do_refcount_check() to
figure out whether a synchronous umount may proceed or not by summing
the per-CPU mnt_count counter under mount_lock.
The fastpath for mntget() and mntput() doesn't require that lock. A task
that already holds a reference and takes another one on a cpu the loop
has summed can get migrated and drops that reference again on another
cpu. The loop might not have reached that cpu yet. That ends up
undercounting. The original reference of the task is missed and umount()
ends up succeeding with the file still open. The mount is destroyed
later when the task mntput()s so it degrades to a lazy umount.
That's basically the umount(2) variant of commit 9ea0a46ca2c3 ("fix
mntput/mntput race") closed for the final mntput(). The same
cpu-migration caused a UAF.
Luckily this isn't a UAF. It's just a hidden reference pinning the
mount but it's wrong nonetheless.
Like the other race it's a narrow window but I can reproduce it reliably
with some patching. The debug patch below prints the sum the loop
computed next to an immediate re-sum of the same counters. It reports
who drops the last reference to that mount later:
# --- a/fs/namespace.c
# +++ b/fs/namespace.c
# @@ -34,6 +34,8 @@
# #include <linux/mnt_idmapping.h>
# #include <linux/pidfs.h>
# #include <linux/nstree.h>
# +#include <linux/debugfs.h>
# +#include <linux/delay.h>
#
# #include "pnode.h"
# #include "internal.h"
# @@ -263,17 +265,48 @@
# #endif
# }
#
# +static u32 mnt_get_count_delay_ms;
# +static int mnt_get_count_debug_id;
# +
# +static int __init mnt_get_count_debug_init(void)
# +{
# + debugfs_create_u32("mnt_get_count_delay_ms", 0600, NULL,
# + &mnt_get_count_delay_ms);
# + return 0;
# +}
# +late_initcall(mnt_get_count_debug_init);
# +
# /*
# * vfsmount lock must be held for write
# */
# int mnt_get_count(struct mount *mnt)
# {
# #ifdef CONFIG_SMP
# - int count = 0;
# + static int seen[NR_CPUS];
# + bool slow = mnt_get_count_delay_ms &&
# + !(mnt->mnt.mnt_flags & MNT_UMOUNT);
# + int count = 0, again = 0;
# int cpu;
#
# for_each_possible_cpu(cpu) {
# - count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
# + seen[cpu] = per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
# + count += seen[cpu];
# + if (slow)
# + mdelay(mnt_get_count_delay_ms);
# + }
# + if (slow) {
# + for_each_possible_cpu(cpu) {
# + int now;
# +
# + now = per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
# + again += now;
# + pr_err("mount %d: cpu%d read %d, now %d\n",
# + mnt->mnt_id, cpu, seen[cpu], now);
# + }
# + mnt_get_count_debug_id = mnt->mnt_id;
# + pr_err("mount %d: sum %d, re-sum %d, %ps\n",
# + mnt->mnt_id, count, again,
# + __builtin_return_address(0));
# }
#
# return count;
# @@ -1350,6 +1383,9 @@
# smp_mb();
# mnt_add_count(mnt, -1);
# count = mnt_get_count(mnt);
# + if (count == 0 && mnt->mnt_id == mnt_get_count_debug_id)
# + pr_err("mount %d: last put by %s (%d)\n", mnt->mnt_id,
# + current->comm, task_pid_nr(current));
# if (count != 0) {
# WARN_ON(count < 0);
# rcu_read_unlock();
A task holds open a directory fd on a tmpfs. A synchronous rumount() of
the tmpfs sums up. Concurrently a task calls fchdir() on that fd on
CPU 0 and fchdir()s back to / on CPU 3. This will cause a path_get() and
a path_put() with a migration in between without mount_lock held.
Adding a delay per CPU makes the count loop miss the get in a cpu it
already visited but count the put in one it hasn't.
The reproducer, run as root with debugfs mounted:
/*
* gcc -static -o umount-torn umount-torn.c
*/
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
#define KNOB "/sys/kernel/debug/mnt_get_count_delay_ms"
#define MNT "/mnt/x"
static int kmsg;
static void pin(int cpu)
{
cpu_set_t s;
CPU_ZERO(&s);
CPU_SET(cpu, &s);
sched_setaffinity(0, sizeof(s), &s);
}
static void knob(const char *v)
{
int fd = open(KNOB, O_WRONLY);
write(fd, v, strlen(v));
close(fd);
}
int main(void)
{
int last = sysconf(_SC_NPROCESSORS_ONLN) - 1;
int p[2], fd, ret;
pid_t pid;
char c;
kmsg = open("/dev/kmsg", O_WRONLY);
mkdir(MNT, 0755);
mount("none", MNT, "tmpfs", 0, NULL);
fd = open(MNT "/f", O_WRONLY | O_CREAT, 0644);
write(fd, "still here\n", 11);
close(fd);
pipe(p);
pid = fork();
if (pid == 0) {
int dirfd = open(MNT, O_RDONLY | O_DIRECTORY);
int rootfd = open("/", O_RDONLY | O_DIRECTORY);
struct stat st;
char buf[16];
/* one get/put pair while the umount is summing */
usleep(150000);
pin(0);
fchdir(dirfd); /* mntget() */
dprintf(kmsg, "holder %d: get on cpu %d\n", getpid(),
sched_getcpu());
pin(last);
fchdir(rootfd); /* mntput() */
dprintf(kmsg, "holder %d: put on cpu %d\n", getpid(),
sched_getcpu());
/* the umount has returned, is the fd still good? */
read(p[0], &c, 1);
fd = openat(dirfd, "f", O_RDONLY);
ret = read(fd, buf, sizeof(buf));
dprintf(kmsg, "holder %d: fstat %d openat %d read %d\n",
getpid(), fstat(dirfd, &st), fd, ret);
_exit(0);
}
pin(1);
knob("100");
ret = umount2(MNT, 0);
knob("0");
if (ret)
dprintf(kmsg, "umount: %s\n", strerror(errno));
else
dprintf(kmsg, "umount: 0\n");
write(p[1], "x", 1);
waitpid(pid, NULL, 0);
return 0;
}
The log shows the busy check summing 2 and when read right after it
reads 3. The loop read CPU 0 before the get landed there and CPU 3
after the put did. The umount succeeds while there's still someone
with an fd. The mount is then dropped when the fd goes:
[ 2.511944] holder 90: get on cpu 0
[ 2.512023] holder 90: put on cpu 3
[ 2.671388] mount 28: cpu0 read 1, now 2
[ 2.671398] mount 28: cpu1 read 2, now 2
[ 2.671401] mount 28: cpu2 read 0, now 0
[ 2.671404] mount 28: cpu3 read -1, now -1
[ 2.671407] mount 28: sum 2, re-sum 3, propagate_mount_busy
[ 2.671773] umount: 0
[ 2.672963] holder 90: fstat 0 openat 8 read 11
[ 2.673663] mount 28: last put by umount-torn (90)
Easy fix would be to order mntget() against the loop that sums up. But
that's a full barrier and a flag test in mntget() afaict. No bueno...
That would cost every path_get().
So learn from SRCU. Keep gets and puts in separate per-cpu counters and
make mnt_get_count() sum all puts first and all gets second with a full
barrier in between.
A put is always after its own get (hopefully...) independent of the cpu
the task is on. So a put the first pass counted must have its get
visible to the second pass. Ergo, we can't undercount.
This is the two pass sum srcu_readers_active_idx_check() does for
srcu_locks and srcu_unlocks. mntget() keeps a single
this_cpu_inc(). mntput() gains an smp_wmb() before its increment, a
compiler barrier on x86 and a store fence on the weakly ordered
architectures, since the two counters are two words and a put stored
after a get could otherwise become visible before it. The counters
are unsigned so the difference stays right after they wrap.
The count can still come out high when a get is counted whose put
the first pass did not see. We don't care. A task can only take a new
reference if:
(1) it holds one already
(2) through __legitimize_mnt() which the seqcount orders
against the write side
So a get in this window means someone has a reference and -EBUSY is
correct. The final mntput() is unchanged. Once ->mnt_ns is NULL every
put takes the slow path under mount_lock and so no put is in flight
while it counts. Here's an attempted proof for that crap:
(i) A put never becomes visible before its get. Within one task the
smp_wmb() in mntput_no_expire() orders every earlier store before the
increment of the puts.
Any task that migrated in between had its stores flushed by the
scheduler. When that reference is handed to another task that's
trivially true.
(ii) The double count in mnt_get_count() is ordered via smp_mb(). That
keeps every read of the puts counter before every read of the gets
counter.
(iii) We never undercount by (ii).
(iv) There are no spurious counts/differences. A get is counted only if
it happened and a put is left out only if it hasn't happened when
the counter was read. With (iii) this means it's equivalent to the
old count whenever nothing is taken or dropped during the loop.
(v) do_umount() holds a reference and mount_lock hence. New references
come from: (v.a) __legitimize_mnt() managed by the seqcount. Either
it's smp_mb() made the get visible to the loop or it takes the lock
and waits for the loop. By (iii) a mount with a additional
references is refused. By (iv) refusing the umount just means that
any additional reference existed, same as the old counter.
(vi) mntput_no_expire_slowpath() runs with ->mnt_ns already NULL. Hence,
every other put must take the slowpath as well and hangs on mount_lock.
The grace period in namespace_unlock() will make every fast path do
a put that still saw ->mnt_ns.
No put is in flight during the loop.
A get that is in flight comes from a task holding another reference.
That must be included by the count or from __legitimize_mnt() as in
(v).
Ergo, zero means the last reference and non-zero means a reference
is live.
(vii) may_umount() uses propagate_mount_busy() as well and
may_umount_tree() sums mnt_get_count() itself.
With this patch the race is dead:
[ 3.066786] mount 28: sum 3, re-sum 3, propagate_mount_busy
[ 3.105867] umount: Device or resource busy
[ 3.106047] holder 90: fstat 0 openat 8 read 11
Link: https://patch.msgid.link/20260923-work-mount-fixes-v1-7-f424cf8d3242@kernel.org
Fixes: b3e19d924b6e ("fs: scale mntget/mntput")
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/mount.h | 3 ++-
fs/namespace.c | 48 ++++++++++++++++++++++++++++++------------------
2 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/fs/mount.h b/fs/mount.h
index 03b41e68776fb..2223fb141499f 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -33,7 +33,8 @@ struct mnt_namespace {
} __randomize_layout;
struct mnt_pcp {
- int mnt_count;
+ unsigned int mnt_gets;
+ unsigned int mnt_puts;
int mnt_writers;
};
diff --git a/fs/namespace.c b/fs/namespace.c
index 010bc659188d4..ec93bdac9e789 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -248,16 +248,24 @@ void mnt_release_group_id(struct mount *mnt)
mnt->mnt_group_id = 0;
}
-/*
- * vfsmount lock must be held for read
- */
-static inline void mnt_add_count(struct mount *mnt, int n)
+static inline void mnt_inc_count(struct mount *mnt)
+{
+#ifdef CONFIG_SMP
+ this_cpu_inc(mnt->mnt_pcp->mnt_gets);
+#else
+ preempt_disable();
+ mnt->mnt_count++;
+ preempt_enable();
+#endif
+}
+
+static inline void mnt_dec_count(struct mount *mnt)
{
#ifdef CONFIG_SMP
- this_cpu_add(mnt->mnt_pcp->mnt_count, n);
+ this_cpu_inc(mnt->mnt_pcp->mnt_puts);
#else
preempt_disable();
- mnt->mnt_count += n;
+ mnt->mnt_count--;
preempt_enable();
#endif
}
@@ -268,14 +276,17 @@ static inline void mnt_add_count(struct mount *mnt, int n)
int mnt_get_count(struct mount *mnt)
{
#ifdef CONFIG_SMP
- int count = 0;
+ unsigned int gets = 0, puts = 0;
int cpu;
- for_each_possible_cpu(cpu) {
- count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
- }
+ /* puts first, so a put counted here has its get counted below */
+ for_each_possible_cpu(cpu)
+ puts += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_puts;
+ smp_mb(); /* pairs with the smp_wmb() in mntput_no_expire() */
+ for_each_possible_cpu(cpu)
+ gets += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_gets;
- return count;
+ return gets - puts;
#else
return mnt->mnt_count;
#endif
@@ -304,7 +315,7 @@ static struct mount *alloc_vfsmnt(const char *name)
if (!mnt->mnt_pcp)
goto out_free_devname;
- this_cpu_add(mnt->mnt_pcp->mnt_count, 1);
+ this_cpu_inc(mnt->mnt_pcp->mnt_gets);
#else
mnt->mnt_count = 1;
mnt->mnt_writers = 0;
@@ -748,13 +759,13 @@ int __legitimize_mnt(struct vfsmount *bastard, unsigned seq)
if (bastard == NULL)
return 0;
mnt = real_mount(bastard);
- mnt_add_count(mnt, 1);
- smp_mb(); // see mntput_no_expire() and do_umount()
+ mnt_inc_count(mnt);
+ smp_mb(); /* see mntput_no_expire_slowpath() and do_umount() */
if (likely(!read_seqretry(&mount_lock, seq)))
return 0;
lock_mount_hash();
if (unlikely(bastard->mnt_flags & (MNT_SYNC_UMOUNT | MNT_DOOMED))) {
- mnt_add_count(mnt, -1);
+ mnt_dec_count(mnt);
unlock_mount_hash();
return 1;
}
@@ -1353,7 +1364,7 @@ static void noinline mntput_no_expire_slowpath(struct mount *mnt)
* mount_lock, we'll see their refcount increment here.
*/
smp_mb();
- mnt_add_count(mnt, -1);
+ mnt_dec_count(mnt);
count = mnt_get_count(mnt);
if (count != 0) {
WARN_ON(count < 0);
@@ -1410,7 +1421,8 @@ static void mntput_no_expire(struct mount *mnt)
* non-NULL under rcu_read_lock(), the reference
* we are dropping is not the final one.
*/
- mnt_add_count(mnt, -1);
+ smp_wmb(); /* pairs with the smp_mb() in mnt_get_count() */
+ mnt_dec_count(mnt);
rcu_read_unlock();
return;
}
@@ -1432,7 +1444,7 @@ EXPORT_SYMBOL(mntput);
struct vfsmount *mntget(struct vfsmount *mnt)
{
if (mnt)
- mnt_add_count(real_mount(mnt), 1);
+ mnt_inc_count(real_mount(mnt));
return mnt;
}
EXPORT_SYMBOL(mntget);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 186/281] scsi: ufs: core: Hold a clock reference across the probe
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (184 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 185/281] fs: dont let a migrating task hide its reference from do_umount() Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 187/281] Bluetooth: btintel_pcie: fix TX descriptor bounds check Greg Kroah-Hartman
` (101 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Naomi Chu, Peter Wang,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naomi Chu <naomi.chu@mediatek.com>
[ Upstream commit 02a3178319639f650428164d4d003de4dc03e326 ]
Clock gating becomes possible as soon as ufshcd_init_clk_gating() has run,
and from that point on the probe keeps accessing host registers without
ever taking a clock reference. This has been safe only because of the state
check in __ufshcd_release(): gate_work is not queued unless
hba->ufshcd_state is UFSHCD_STATE_OPERATIONAL, and the promotion to that
state used to happen after the last register access of the probe, at the
end of ufshcd_probe_hba().
That is fragile: it only works while the promotion happens after the
register accesses. Commit a390e6677f41 ("scsi: ufs: core: Expand the
ufshcd_device_init(hba, true) call") changed that ordering by moving the
promotion into ufshcd_init(), which schedules ufshcd_async_scan()
afterwards. ufshcd_probe_hba() therefore now runs with the state already
promoted, and it accesses host registers without holding a clock reference:
- On hosts with UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH it calls
ufshcd_hba_stop() and ufshcd_hba_enable() before ufshcd_device_init()
sets the state back to UFSHCD_STATE_RESET, and both read
REG_CONTROLLER_ENABLE, so gated clocks stall there instead of just
losing a write.
- It ends with an ufshcd_configure_auto_hibern8() write, which its other
callers do take a clock reference for.
Take a clock reference as soon as clock gating has been initialised and
keep it until the probe is over. It then does not matter who drops a clock
reference while the probe is running, and the register accesses of the
probe no longer depend on hba->ufshcd_state. The reference is dropped by
ufshcd_async_scan() once the scan has finished, or by the new out_release
label if the probe fails after it was taken.
Fixes: a390e6677f41 ("scsi: ufs: core: Expand the ufshcd_device_init(hba, true) call")
Signed-off-by: Naomi Chu <naomi.chu@mediatek.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Link: https://patch.msgid.link/20260909091045.1134956-1-naomi.chu@mediatek.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ufs/core/ufshcd.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index fb5f119b19772..0a9366f21483f 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -9484,6 +9484,7 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie)
ret = ufshcd_add_lus(hba);
out:
+ ufshcd_release(hba);
pm_runtime_put_sync(hba->dev);
if (ret)
@@ -11206,6 +11207,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
ufshcd_init_clk_gating(hba);
+ /* Released by ufshcd_async_scan(), or by out_release on failure. */
+ ufshcd_hold(hba);
+
ufshcd_init_clk_scaling(hba);
/*
@@ -11226,7 +11230,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
err = devm_request_irq(dev, irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba);
if (err) {
dev_err(hba->dev, "request irq failed\n");
- goto out_disable;
+ goto out_release;
} else {
hba->is_irq_enabled = true;
}
@@ -11242,7 +11246,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
dev_err(hba->dev, "Host controller enable failed\n");
ufshcd_print_evt_hist(hba);
ufshcd_print_host_state(hba);
- goto out_disable;
+ goto out_release;
}
INIT_DELAYED_WORK(&hba->rpm_dev_flush_recheck_work, ufshcd_rpm_dev_flush_recheck_work);
@@ -11256,7 +11260,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
err = ufshcd_add_scsi_host(hba);
if (err)
- goto out_disable;
+ goto out_release;
/* Hold auto suspend until async scan completes */
pm_runtime_get_sync(dev);
@@ -11276,7 +11280,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
err = ufshcd_link_startup(hba);
if (err)
- goto out_disable;
+ goto out_release;
if (hba->mcq_enabled)
ufshcd_config_mcq(hba);
@@ -11293,23 +11297,23 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
/* Verify device initialization by sending NOP OUT UPIU */
err = ufshcd_verify_dev_init(hba);
if (err)
- goto out_disable;
+ goto out_release;
/* Initiate UFS initialization, and waiting until completion */
err = ufshcd_complete_dev_init(hba);
if (err)
- goto out_disable;
+ goto out_release;
err = ufshcd_device_params_init(hba);
if (err)
- goto out_disable;
+ goto out_release;
err = ufshcd_post_device_init(hba);
initialized:
ufshcd_process_probe_result(hba, probe_start, err);
if (err)
- goto out_disable;
+ goto out_release;
ufs_sysfs_add_nodes(hba->dev);
hba->dme_qos_sysfs_handle = sysfs_get_dirent(hba->dev->kobj.sd,
@@ -11320,6 +11324,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
ufshcd_pm_qos_init(hba);
return 0;
+out_release:
+ ufshcd_release(hba);
out_disable:
hba->is_irq_enabled = false;
ufshcd_hba_exit(hba);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 187/281] Bluetooth: btintel_pcie: fix TX descriptor bounds check
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (185 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 186/281] scsi: ufs: core: Hold a clock reference across the probe Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 188/281] Bluetooth: btintel_pcie: Add shared HW reset for clean start Greg Kroah-Hartman
` (100 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ravindra, Luiz Augusto von Dentz,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ravindra <ravindra@intel.com>
[ Upstream commit baa53af641c9e3644e717b8dfd1b95a55a0c111b ]
btintel_pcie_prepare_tx() uses tfd_index to access the TFD and data
buffer arrays before the index is advanced modulo txq->count. An index
equal to txq->count is one past the end of both arrays, so reject it in
the bounds check.
Fixes: 6e65a09f9275 ("Bluetooth: btintel_pcie: Add *setup* function to download firmware")
Signed-off-by: Ravindra <ravindra@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btintel_pcie.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index ed2a6286892c5..34899a5507339 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -401,7 +401,7 @@ static int btintel_pcie_send_sync(struct btintel_pcie_data *data,
tfd_index = data->ia.tr_hia[BTINTEL_PCIE_TXQ_NUM];
- if (tfd_index > txq->count)
+ if (tfd_index >= txq->count)
return -ERANGE;
if (skb->len > BTINTEL_PCIE_BUFFER_SIZE - BTINTEL_PCIE_HCI_TYPE_LEN) {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 188/281] Bluetooth: btintel_pcie: Add shared HW reset for clean start
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (186 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 187/281] Bluetooth: btintel_pcie: fix TX descriptor bounds check Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 189/281] drm/bridge: Fix unlocked list_del in drm_bridge_add() Greg Kroah-Hartman
` (99 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sai Teja Aluvala,
Luiz Augusto von Dentz, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sai Teja Aluvala <aluvala.sai.teja@intel.com>
[ Upstream commit 1465494e8d07426fa41c0021530cccb2a1ac38fa ]
Reset shared Bluetooth hardware after mapping the BAR and before setting
up MSI-X interrupts, so stale device state is cleared before IRQ handlers
and interrupt masks are configured.
Propagate reset errors so probe aborts rather than continuing when the
reset fails.
Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Signed-off-by: Sai Teja Aluvala <aluvala.sai.teja@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btintel_pcie.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 34899a5507339..ed4ba2e469ac7 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -1819,6 +1819,13 @@ static int btintel_pcie_config_pcie(struct pci_dev *pdev,
if (IS_ERR(data->base_addr))
return PTR_ERR(data->base_addr);
+ /* Do shared hardware reset to ensure a clean start before
+ * configuring interrupts.
+ */
+ err = btintel_pcie_reset_bt(data);
+ if (err)
+ return err;
+
err = btintel_pcie_setup_irq(data);
if (err)
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 189/281] drm/bridge: Fix unlocked list_del in drm_bridge_add()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (187 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 188/281] Bluetooth: btintel_pcie: Add shared HW reset for clean start Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 190/281] drm/bridge: Fix unlocked list access in drm_bridge_attach() Greg Kroah-Hartman
` (98 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Cristian Ciocaltea,
Luca Ceresoli, Robin Räber, Sasha Levin, Igor Paunovic
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
[ Upstream commit b62e3db8cdc1680e1c3390591e872f485148541a ]
When re-adding a bridge that was previously removed, drm_bridge_add()
drops it from bridge_lingering_list without holding bridge_lock.
Both bridge_list and bridge_lingering_list are protected by bridge_lock,
as they are concurrently modified by drm_bridge_remove() and
__drm_bridge_free(), and walked by the debugfs 'bridges' file. Running
the list_empty() test and the list_del_init() outside of the lock may
therefore corrupt either list.
Perform both under bridge_lock.
Fixes: 17805a15d175 ("drm/bridge: add list of removed refcounted bridges")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260723015004.1F5711F000E9@smtp.kernel.org/
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Igor Paunovic <royalnet026@gmail.com> # RK3588 Orange Pi 5 Plus, dual HDMI
Tested-by: Robin Räber <robin.raebi@gmail.com>
Link: https://patch.msgid.link/20260901-dw-hdmi-qp-scramb-v11-12-bc12954a0688@collabora.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/drm_bridge.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 687b36eea0c70..3618cb12483e2 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -414,8 +414,10 @@ void drm_bridge_add(struct drm_bridge *bridge)
* in bridge_lingering_list. Remove it or bridge_lingering_list will be
* corrupted when adding this bridge to bridge_list below.
*/
+ mutex_lock(&bridge_lock);
if (!list_empty(&bridge->list))
list_del_init(&bridge->list);
+ mutex_unlock(&bridge_lock);
mutex_init(&bridge->hpd_mutex);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 190/281] drm/bridge: Fix unlocked list access in drm_bridge_attach()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (188 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 189/281] drm/bridge: Fix unlocked list_del in drm_bridge_add() Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 191/281] cgroup/cpuset: Dont access cpuset_cgrp_subsys.root in is_in_v2_mode() Greg Kroah-Hartman
` (97 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cristian Ciocaltea, Luca Ceresoli,
Robin Räber, Sasha Levin, Igor Paunovic
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
[ Upstream commit 57889076afd1be890150c32ffde3b691fe5707c8 ]
drm_bridge_attach() inspects bridge->list to warn about bridges being
attached without a previous drm_bridge_add() call, but it does so
without holding bridge_lock.
The list head can be concurrently written by drm_bridge_add(),
drm_bridge_remove() and __drm_bridge_free() while they operate on
neighbouring entries of bridge_list or bridge_lingering_list, all of
them under bridge_lock. Hence the unlocked read is a data race, even
though it is unlikely to change the outcome of list_empty() in practice.
Perform the check with bridge_lock held.
Fixes: 76f1a9711b83 ("drm/bridge: add warning for bridges attached without being added")
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Igor Paunovic <royalnet026@gmail.com> # RK3588 Orange Pi 5 Plus, dual HDMI
Tested-by: Robin Räber <robin.raebi@gmail.com>
Link: https://patch.msgid.link/20260901-dw-hdmi-qp-scramb-v11-14-bc12954a0688@collabora.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/drm_bridge.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 3618cb12483e2..9124cbe1ff889 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -558,8 +558,10 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
if (!bridge->container)
DRM_WARN("DRM bridge corrupted or not allocated by devm_drm_bridge_alloc()\n");
- if (list_empty(&bridge->list))
- DRM_WARN("Missing drm_bridge_add() before attach\n");
+ scoped_guard(mutex, &bridge_lock) {
+ if (list_empty(&bridge->list))
+ DRM_WARN("Missing drm_bridge_add() before attach\n");
+ }
drm_bridge_get(bridge);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 191/281] cgroup/cpuset: Dont access cpuset_cgrp_subsys.root in is_in_v2_mode()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (189 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 190/281] drm/bridge: Fix unlocked list access in drm_bridge_attach() Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 192/281] drm/dp: dont mark the AUX backlight enabled when enabling failed Greg Kroah-Hartman
` (96 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Waiman Long, Ridong Chen,
Andrea Righi, Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <longman@redhat.com>
[ Upstream commit e06b678e3b4e12fdaa0b51a7a5a54abc5dbd6469 ]
After seeing the patch [1] to guard is_in_v2_mode() with RCU, it makes
me realize that is_in_v2_mode() may be called in a context where a new
cgroup filesystem is being rebound with stale cpuset_cgrp_subsys.root
pointer. Avoid this potential UaF situation by adding a new cpuset_v2_mode
flag which is set when the cpuset_v2_mode mount option is used. This
flag is written into only when cpuset_bind() is being called with a
stable cpuset_cgrp_subsys.root value. The is_in_v2_mode() helper is
modified to read the new cpuset_v2_mode flag instead of accessing
cpuset_cgrp_subsys.root directly.
[1] https://lore.kernel.org/lkml/20260929084124.626693-2-arighi@nvidia.com
Fixes: b8d1b8ee93df ("cpuset: Allow v2 behavior in v1 cgroup")
Signed-off-by: Waiman Long <longman@redhat.com>
Reviewed-by: Ridong Chen <ridong.chen@linux.dev>
Reviewed-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/cgroup/cpuset.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 2b86b76dba56b..16c554df4a50e 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -151,6 +151,12 @@ static cpumask_var_t isolated_cpus; /* CSCB */
*/
static bool update_housekeeping; /* RWCS */
+/*
+ * Set if "cpuset_v2_mode" mount option is used
+ * Cached at bind time and not lock protected; accessed via {READ,WRITE}_ONCE
+ */
+static bool cpuset_v2_mode;
+
/*
* Copy of isolated_cpus to be passed to housekeeping_update()
*/
@@ -403,8 +409,7 @@ static inline bool cpuset_v2(void)
*/
static inline bool is_in_v2_mode(void)
{
- return cpuset_v2() ||
- (cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE);
+ return cpuset_v2() || READ_ONCE(cpuset_v2_mode);
}
/**
@@ -3602,6 +3607,8 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css)
mutex_lock(&cpuset_mutex);
spin_lock_irq(&callback_lock);
+ WRITE_ONCE(cpuset_v2_mode,
+ !!(cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE));
if (is_in_v2_mode()) {
cpumask_copy(top_cpuset.cpus_allowed, cpu_possible_mask);
cpumask_copy(top_cpuset.effective_xcpus, cpu_possible_mask);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 192/281] drm/dp: dont mark the AUX backlight enabled when enabling failed
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (190 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 191/281] cgroup/cpuset: Dont access cpuset_cgrp_subsys.root in is_in_v2_mode() Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 193/281] gpio: exar: initialize the ID before registering its cleanup Greg Kroah-Hartman
` (95 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oleg Keri, Douglas Anderson,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleg Keri <okerixx@gmail.com>
[ Upstream commit 707ce102521496c67860d81221b20c56d8255f2f ]
If drm_edp_backlight_enable() fails, dp_aux_backlight_update_status()
still marks the backlight as enabled. From then on every brightness
change only updates the level and the enable is never retried, so the
panel stays dark until something blanks and unblanks the backlight.
Return the error instead, so the next update tries to enable again.
Fixes: 10f7b40e4f30 ("drm/panel: add basic DP AUX backlight support")
Signed-off-by: Oleg Keri <okerixx@gmail.com>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Link: https://patch.msgid.link/20260925132558.27518-1-okerixx@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/display/drm_dp_helper.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index e623ccb4c1d8a..488fd123a01ad 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -4634,7 +4634,9 @@ static int dp_aux_backlight_update_status(struct backlight_device *bd)
if (!backlight_is_blank(bd)) {
if (!bl->enabled) {
- drm_edp_backlight_enable(bl->aux, &bl->info, brightness);
+ ret = drm_edp_backlight_enable(bl->aux, &bl->info, brightness);
+ if (ret)
+ return ret;
bl->enabled = true;
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 193/281] gpio: exar: initialize the ID before registering its cleanup
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (191 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 192/281] drm/dp: dont mark the AUX backlight enabled when enabling failed Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 194/281] drm/aspeed: Balance the display clock enable on teardown Greg Kroah-Hartman
` (94 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Changyul Lee, Sang-Hoon Choi,
Linus Walleij, Bartosz Golaszewski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Hoon Choi <csh0052@gmail.com>
[ Upstream commit 4d69e74034b208588636ecc177e0dd43a7696af3 ]
devm_add_action_or_reset() invokes the cleanup action immediately when
registering the action fails. gpio_exar_probe() currently stores the
allocated ID in exar_gpio only after registering the action, so that
failure makes exar_devm_ida_free() release ID 0. If the allocated ID is
nonzero, this leaks that ID and can free ID 0 belonging to another device.
Store the ID before registering the cleanup action so both the immediate
failure path and normal device teardown release the correct allocation.
Fixes: 5300ebb695fa ("gpio: exar: use devm action for freeing the IDA and drop remove()")
Reported-by: Changyul Lee <lcy8047@gmail.com>
Assisted-by: LLM
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/179070265834.12871.48183786512201899.idr-bug-79@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpio/gpio-exar.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-exar.c b/drivers/gpio/gpio-exar.c
index 9053662f18177..f629cc526f3ee 100644
--- a/drivers/gpio/gpio-exar.c
+++ b/drivers/gpio/gpio-exar.c
@@ -199,6 +199,7 @@ static int gpio_exar_probe(struct platform_device *pdev)
index = ida_alloc(&ida_index, GFP_KERNEL);
if (index < 0)
return index;
+ exar_gpio->index = index;
ret = devm_add_action_or_reset(dev, exar_devm_ida_free, exar_gpio);
if (ret)
@@ -214,7 +215,6 @@ static int gpio_exar_probe(struct platform_device *pdev)
exar_gpio->gpio_chip.set = exar_set_value;
exar_gpio->gpio_chip.base = -1;
exar_gpio->gpio_chip.ngpio = ngpios;
- exar_gpio->index = index;
exar_gpio->first_pin = first_pin;
ret = devm_gpiochip_add_data(dev, &exar_gpio->gpio_chip, exar_gpio);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 194/281] drm/aspeed: Balance the display clock enable on teardown
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (192 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 193/281] gpio: exar: initialize the ID before registering its cleanup Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 195/281] drm/vc4: Free the BO cache size list " Greg Kroah-Hartman
` (93 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak,
Thomas Zimmermann, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
[ Upstream commit ecce445c6489895463b7ddec2af66338287fee4c ]
aspeed_gfx_load() enables the display clock without checking the return
value and never disables it on probe failure or removal. devm_clk_get()
only releases the clock reference, leaving the enable unbalanced.
Use devm_clk_get_enabled() to handle enable failures and automatically
disable and unprepare the clock on probe failure or removal.
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Fixes: 4f2a8f5898ec ("drm: Add ASPEED GFX driver")
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Assisted-by: OpenAI:GPT-5.6
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260913223019.89651-1-mhun512@gmail.com
Link: https://patch.msgid.link/20260905080426.34224-1-kmehltretter@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
index d4577663a1f0e..aa36b79d0f6c4 100644
--- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
+++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
@@ -189,13 +189,12 @@ static int aspeed_gfx_load(struct drm_device *drm)
}
reset_control_deassert(priv->rst);
- priv->clk = devm_clk_get(drm->dev, NULL);
+ priv->clk = devm_clk_get_enabled(drm->dev, NULL);
if (IS_ERR(priv->clk)) {
dev_err(&pdev->dev,
- "missing or invalid clk device tree entry");
+ "failed to get and enable clock\n");
return PTR_ERR(priv->clk);
}
- clk_prepare_enable(priv->clk);
/* Sanitize control registers */
writel(0, priv->base + CRT_CTRL1);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 195/281] drm/vc4: Free the BO cache size list on teardown
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (193 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 194/281] drm/aspeed: Balance the display clock enable on teardown Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 196/281] drm/vc4: Use kvmalloc_objs() for the BO cache size list Greg Kroah-Hartman
` (92 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thadeu Lima de Souza Cascardo,
Maíra Canal, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <mcanal@igalia.com>
[ Upstream commit b41ff8b529278216cba22a5dcdc93fea2a3a9619 ]
vc4_bo_cache_destroy() purges the cached BOs but never frees the size
list, leaking it on every unbind.
Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.")
Assisted-by: LLM
Reviewed-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Link: https://patch.msgid.link/20260930190721.1897264-1-mcanal@igalia.com
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_bo.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 49ea2ed0996b4..ea1be891ac781 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -1052,6 +1052,7 @@ static void vc4_bo_cache_destroy(struct drm_device *dev, void *unused)
cancel_work_sync(&vc4->bo_cache.time_work);
vc4_bo_cache_purge(dev);
+ kfree(vc4->bo_cache.size_list);
for (i = 0; i < vc4->num_labels; i++) {
if (vc4->bo_labels[i].num_allocated) {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 196/281] drm/vc4: Use kvmalloc_objs() for the BO cache size list
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (194 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 195/281] drm/vc4: Free the BO cache size list " Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 197/281] net/sched: em_text: reject unterminated algo before autoload Greg Kroah-Hartman
` (91 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thadeu Lima de Souza Cascardo,
Maíra Canal, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <mcanal@igalia.com>
[ Upstream commit bca45af5998a05f34b13a2ef11e639bac9c62643 ]
The BO cache size list has one entry per BO page count, so its size
scales with the largest BO ever freed. A 64 MiB BO already needs at
least an order-6 allocation, which fails under fragmentation and
triggers a warn_alloc() splat on BO close:
page allocation failure: order:7, mode:0x40cc0(GFP_KERNEL|__GFP_COMP)
Call trace:
...
warn_alloc+0x118/0x190
__alloc_pages_slowpath+0x4a8/0x520
...
__kmalloc_noprof+0x3ac/0x5d8
vc4_free_object+0x128/0x370 [vc4]
drm_gem_object_handle_put_unlocked+0xb8/0x158 [drm]
drm_gem_object_release_handle+0x74/0xe8 [drm]
drm_gem_handle_delete+0x6c/0xa8 [drm]
drm_gem_close_ioctl+0x34/0x50 [drm]
The list doesn't need physically contiguous memory. Use kvmalloc_objs()
so large lists can fall back to vmalloc(), avoiding the allocation
failure.
Fixes: c826a6e10644 ("drm/vc4: Add a BO cache.")
Reviewed-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Link: https://patch.msgid.link/20260930190721.1897264-2-mcanal@igalia.com
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_bo.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index ea1be891ac781..7b8b3364000fc 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -204,7 +204,7 @@ static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev,
struct list_head *new_list;
uint32_t i;
- new_list = kmalloc_objs(struct list_head, new_size);
+ new_list = kvmalloc_objs(struct list_head, new_size);
if (!new_list)
return NULL;
@@ -224,7 +224,7 @@ static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev,
for (i = vc4->bo_cache.size_list_size; i < new_size; i++)
INIT_LIST_HEAD(&new_list[i]);
- kfree(vc4->bo_cache.size_list);
+ kvfree(vc4->bo_cache.size_list);
vc4->bo_cache.size_list = new_list;
vc4->bo_cache.size_list_size = new_size;
}
@@ -1052,7 +1052,7 @@ static void vc4_bo_cache_destroy(struct drm_device *dev, void *unused)
cancel_work_sync(&vc4->bo_cache.time_work);
vc4_bo_cache_purge(dev);
- kfree(vc4->bo_cache.size_list);
+ kvfree(vc4->bo_cache.size_list);
for (i = 0; i < vc4->num_labels; i++) {
if (vc4->bo_labels[i].num_allocated) {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 197/281] net/sched: em_text: reject unterminated algo before autoload
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (195 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 196/281] drm/vc4: Use kvmalloc_objs() for the BO cache size list Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 198/281] amt: send the relays General Query directly from the receive path Greg Kroah-Hartman
` (90 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko (gemini), Jamal Hadi Salim,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit c9728fcf2e7fb4a7a8d08ebd9524c3b02ae1a021 ]
This is a follow-up to commit 9c572a83037a ("net/sched: fix potential
stack infoleak in em_text_dump()"), which zero-initialised the dump-side
struct. Sashiko pointed at a pre-existing bug that exposed the change-side
input-validation gap open.
em_text_change() casts the raw netlink attribute payload to struct
tcf_em_text and passes conf->algo, a 16-byte array with no enforced NUL
terminator, to textsearch_prepare(). On the TS_AUTOLOAD retry
textsearch_prepare() calls request_module("ts_%s", algo); vsnprintf()
walks %s until it finds a NUL, so an algo[] with no NUL reads past the
array into the adjacent struct fields and payload and feeds those bytes
to the usermode helper command line. This is an out-of-bounds read and
a kernel memory disclosure.
Reject the attribute when no NUL exists within TC_EM_TEXT_ALGOSIZ bytes,
matching the check xt_string has had since 3ab720881b6e.
Conditions to recreate the bug:
- CAP_NET_ADMIN on the target netns (namespace-local via unshare -Urn
is enough)
- install clsact on an interface, then add a basic filter with one text
ematch whose algo[] is 16 bytes with no NUL (e.g. "A"*16) and
pattern_len at least 1
- the add fails with -ENOENT and the kernel invokes modprobe with a
module name made of "ts_" plus the 16 bytes and the adjacent payload
Fixes: d675c989ed2d4 ("[PKT_SCHED]: Packet classification based on textsearch (ematch)")
Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260918133953.12494-1-bernard.ladenthin%40gmail.com
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-2DIU.v1.20260929183844@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/em_text.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/sched/em_text.c b/net/sched/em_text.c
index 4132f8c3c5fc9..bc45edb8c03bf 100644
--- a/net/sched/em_text.c
+++ b/net/sched/em_text.c
@@ -58,6 +58,9 @@ static int em_text_change(struct net *net, void *data, int len,
if (len < sizeof(*conf) || len < (sizeof(*conf) + conf->pattern_len))
return -EINVAL;
+ if (!memchr(conf->algo, '\0', sizeof(conf->algo)))
+ return -EINVAL;
+
if (conf->from_layer > conf->to_layer)
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 198/281] amt: send the relays General Query directly from the receive path
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (196 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 197/281] net/sched: em_text: reject unterminated algo before autoload Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 199/281] lib/dim: fix 32-bit overflow in dim_calc_stats() rates Greg Kroah-Hartman
` (89 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, AutonomousCodeSecurity,
Xiang Mei (Microsoft), Cen Zhang (Microsoft Security FORGE Labs),
Omar Ramadan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Omar Ramadan <omar@blockcast.net>
[ Upstream commit afae89de73dd693cfa329580ba0fba63bd3f0a11 ]
An skb queued in a qdisc can outlive the tunnel it references
through a raw pointer in skb->cb. For example, with igmp_qrv set
to 1 on the relay a tunnel lives for 135s, so a netem delay of
180s on the amt device outlives it; when the tunnel expires and is
freed, the subsequent dequeue triggers a use-after-free in
amt_dev_xmit().
BUG: KASAN: slab-use-after-free in amt_dev_xmit+0x2763/0x2e20
Call Trace:
amt_dev_xmit+0x2763/0x2e20 [drivers/net/amt.c:1262]
dev_hard_start_xmit+0x22f/0x620
sch_direct_xmit+0x12e/0xac0
netem_dequeue+0x333/0xc50
net_tx_action+0x35c/0xa60
amt_send_igmp_gq() and amt_send_mld_gq() are only called from
amt_request_handler(), inside the rcu_read_lock_bh() section of
amt_rcv(). amt_request_handler() already has the tunnel the query is
for: it found or created it inside that section. Queuing the query with
dev_queue_xmit() only leads back into amt_dev_xmit(), which strips the
Ethernet header and calls amt_send_membership_query() for that tunnel.
Make that call directly from the two senders instead, the same way
amt_send_advertisement() transmits from the receive path. The query
never waits in a qdisc, the tunnel is only dereferenced inside the
RCU section that found or created it, and nothing is stored in
skb->cb, so no lookup or refcount is needed. Remove the query branch
of amt_dev_xmit(), amt_skb_cb() and struct amt_skb_cb, which have no
users left.
Behaviour changes:
- The relay's own General Queries no longer pass through the amt
device's egress path: its qdisc, tc egress (clsact/tcx), the
netfilter egress hook and packet taps. They are still visible as
UDP on the underlay.
- A query that is sent successfully is no longer counted as
tx_dropped. The old query branch left through the unlock label,
which counted every sent query as dropped.
- A query that reaches amt_dev_xmit() on a relay from elsewhere,
such as a userspace querier, is now dropped at the IGMP/MLD type
switch. Before, it trusted whatever skb->cb held, and a NULL
tunnel hit the WARN_ON(1).
Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
Reported-by: AutonomousCodeSecurity@microsoft.com
Reported-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Reported-by: Cen Zhang (Microsoft Security FORGE Labs) <cenzhang@linux.microsoft.com>
Signed-off-by: Omar Ramadan <omar@blockcast.net>
Link: https://patch.msgid.link/20260928202312.74574-2-omar@blockcast.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/amt.c | 48 +++++++++++++++--------------------------------
include/net/amt.h | 4 ----
2 files changed, 15 insertions(+), 37 deletions(-)
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index 7645ce3a29ad9..189b3a43e4e2a 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -80,15 +80,6 @@ static struct in6_addr mld2_all_node = MLD2_ALL_NODE_INIT;
static struct mld2_grec mldv2_zero_grec;
#endif
-static struct amt_skb_cb *amt_skb_cb(struct sk_buff *skb)
-{
- BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct tc_skb_cb) >
- sizeof_field(struct sk_buff, cb));
-
- return (struct amt_skb_cb *)((void *)skb->cb +
- sizeof(struct tc_skb_cb));
-}
-
static void __amt_source_gc_work(void)
{
struct amt_source_node *snode;
@@ -789,6 +780,11 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
rcu_read_unlock();
}
+static bool amt_send_membership_query(struct amt_dev *amt,
+ struct sk_buff *skb,
+ struct amt_tunnel_list *tunnel,
+ bool v6);
+
static void amt_send_igmp_gq(struct amt_dev *amt,
struct amt_tunnel_list *tunnel)
{
@@ -798,8 +794,11 @@ static void amt_send_igmp_gq(struct amt_dev *amt,
if (!skb)
return;
- amt_skb_cb(skb)->tunnel = tunnel;
- dev_queue_xmit(skb);
+ skb_pull(skb, sizeof(struct ethhdr));
+ if (amt_send_membership_query(amt, skb, tunnel, false)) {
+ amt->dev->stats.tx_dropped++;
+ kfree_skb(skb);
+ }
}
#if IS_ENABLED(CONFIG_IPV6)
@@ -883,8 +882,11 @@ static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
if (!skb)
return;
- amt_skb_cb(skb)->tunnel = tunnel;
- dev_queue_xmit(skb);
+ skb_pull(skb, sizeof(struct ethhdr));
+ if (amt_send_membership_query(amt, skb, tunnel, true)) {
+ amt->dev->stats.tx_dropped++;
+ kfree_skb(skb);
+ }
}
#else
static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
@@ -1183,7 +1185,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
#endif
bool report = false;
struct igmphdr *ih;
- bool query = false;
struct iphdr *iph;
bool data = false;
bool v6 = false;
@@ -1201,9 +1202,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
case IGMP_HOST_MEMBERSHIP_REPORT:
report = true;
break;
- case IGMP_HOST_MEMBERSHIP_QUERY:
- query = true;
- break;
default:
goto free;
}
@@ -1225,9 +1223,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
case ICMPV6_MLD2_REPORT:
report = true;
break;
- case ICMPV6_MGM_QUERY:
- query = true;
- break;
default:
goto free;
}
@@ -1258,19 +1253,6 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
goto free;
goto unlock;
} else if (amt->mode == AMT_MODE_RELAY) {
- if (query) {
- tunnel = amt_skb_cb(skb)->tunnel;
- if (!tunnel) {
- WARN_ON(1);
- goto free;
- }
-
- /* Do not forward unexpected query */
- if (amt_send_membership_query(amt, skb, tunnel, v6))
- goto free;
- goto unlock;
- }
-
if (!data)
goto free;
list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) {
diff --git a/include/net/amt.h b/include/net/amt.h
index a0255491f5b05..2846dde0cadce 100644
--- a/include/net/amt.h
+++ b/include/net/amt.h
@@ -231,10 +231,6 @@ struct amt_relay_headers {
};
} __packed;
-struct amt_skb_cb {
- struct amt_tunnel_list *tunnel;
-};
-
struct amt_tunnel_list {
struct list_head list;
/* Protect All resources under an amt_tunne_list */
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 199/281] lib/dim: fix 32-bit overflow in dim_calc_stats() rates
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (197 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 198/281] amt: send the relays General Query directly from the receive path Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 200/281] cxgb4/ch_ktls: disable softirqs around tid_list erases Greg Kroah-Hartman
` (88 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shashank Mohan Jain, David S. Miller,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shashank Mohan Jain <jain.sm@gmail.com>
[ Upstream commit 0843b23890642a02ff85c36406224e8874e30664 ]
dim_calc_stats() computes the per-millisecond rates as
DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us)
where nbytes is a u32 and USEC_PER_MSEC is 1000L. On 64-bit the product
is done in 64-bit long arithmetic, but on 32-bit architectures long is
32 bits wide and the product wraps as soon as a measurement window
carries more than 4294967 bytes (about 4.3 MB). The same applies to the
packet and completion counts, although those need more than 4.29
million packets or completions per window.
A DIM window spans DIM_NEVENTS (64) events. Drivers count events per
interrupt or per NAPI poll, so under sustained load a window can easily
carry more than 4.3 MB: 64 full NAPI polls of 64 MTU-sized frames are
already 6.2 MB, and drivers such as mtk_eth_soc count one event per
interrupt while NAPI keeps polling with the interrupt masked. On 32-bit
users of the library (for example mtk_eth_soc on MT7621, bcmgenet and
bcmsysport on 32-bit ARM, or virtio_net in a 32-bit guest) bpms then
becomes the product modulo 2^32 divided by the window length, and
net_dim_stats_compare() makes its BETTER/WORSE decisions on a value
that has little to do with the real throughput.
For example, a 1 Gbit/s link at line rate that moves 5 MB in a 40 ms
window gives bpms = 125000 on 64-bit but 17626 on 32-bit, and 5 million
packets in 2 s gives ppms = 353 instead of 2500.
Widen the products to 64 bits and divide with DIV_ROUND_UP_ULL(). The
results are unchanged on 64-bit.
Fixes: cb3c7fd4f839 ("net/mlx5e: Support adaptive RX coalescing")
Fixes: 4c4dbb4a7363 ("net/mlx5e: Move dynamic interrupt coalescing code to include/linux")
Assisted-by: LLM
Signed-off-by: Shashank Mohan Jain <jain.sm@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
lib/dim/dim.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/lib/dim/dim.c b/lib/dim/dim.c
index 97c3d084ebf02..7f3eebae73cb9 100644
--- a/lib/dim/dim.c
+++ b/lib/dim/dim.c
@@ -69,11 +69,15 @@ bool dim_calc_stats(const struct dim_sample *start,
if (!delta_us)
return false;
- curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
- curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
+ /* u32 * USEC_PER_MSEC overflows a 32-bit long */
+ curr_stats->ppms = DIV_ROUND_UP_ULL((u64)npkts * USEC_PER_MSEC,
+ delta_us);
+ curr_stats->bpms = DIV_ROUND_UP_ULL((u64)nbytes * USEC_PER_MSEC,
+ delta_us);
curr_stats->epms = DIV_ROUND_UP(DIM_NEVENTS * USEC_PER_MSEC,
delta_us);
- curr_stats->cpms = DIV_ROUND_UP(ncomps * USEC_PER_MSEC, delta_us);
+ curr_stats->cpms = DIV_ROUND_UP_ULL((u64)ncomps * USEC_PER_MSEC,
+ delta_us);
if (curr_stats->epms != 0)
curr_stats->cpe_ratio = DIV_ROUND_DOWN_ULL(
curr_stats->cpms * 100, curr_stats->epms);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 200/281] cxgb4/ch_ktls: disable softirqs around tid_list erases
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (198 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 199/281] lib/dim: fix 32-bit overflow in dim_calc_stats() rates Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 201/281] wifi: mt76: mt7996: program a link again if the driver holds it Greg Kroah-Hartman
` (87 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Changyul Lee, Sang-Hoon Choi,
Ayush Sawal, David S. Miller, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Hoon Choi <csh0052@gmail.com>
[ Upstream commit 4c9dc0faca98084922caeb689579d338cf3e1c29 ]
chcr_ktls_cpl_act_open_rpl() inserts into tid_list from the receive path
using xa_insert_bh(). The array is shared by the adapter's connections
and initialized with XA_FLAGS_LOCK_BH. However, chcr_ktls_dev_del() and
the chcr_ktls_dev_add() error path use xa_erase(), which takes the XArray
lock without disabling softirqs.
When cleanup runs with softirqs enabled, a receive softirq for another
connection on the same CPU can interrupt the erase and spin on the lock
held by the interrupted task. Use xa_erase_bh() at both sites to match
the insertion path.
Fixes: 65e302a9bd57 ("cxgb4/ch_ktls: Clear resources when pf4 device is removed")
Reported-by: Changyul Lee <lcy8047@gmail.com>
Assisted-by: LLM
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Reviewed-by: Ayush Sawal <ayush.sawal@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c b/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c
index f5acd4be1e69d..dbec95b497773 100644
--- a/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c
+++ b/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c
@@ -389,7 +389,7 @@ static void chcr_ktls_dev_del(struct net_device *netdev,
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
tx_info->tid, tx_info->ip_family);
- xa_erase(&u_ctx->tid_list, tx_info->tid);
+ xa_erase_bh(&u_ctx->tid_list, tx_info->tid);
}
port_stats = &tx_info->adap->ch_ktls_stats.ktls_port[tx_info->port_id];
@@ -577,7 +577,7 @@ static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk,
cxgb4_remove_tid(&tx_info->adap->tids, tx_info->tx_chan,
tx_info->tid, tx_info->ip_family);
- xa_erase(&u_ctx->tid_list, tx_info->tid);
+ xa_erase_bh(&u_ctx->tid_list, tx_info->tid);
put_module:
/* release module refcount */
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 201/281] wifi: mt76: mt7996: program a link again if the driver holds it
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (199 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 200/281] cxgb4/ch_ktls: disable softirqs around tid_list erases Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 202/281] net: stmmac: propagate PTP addend and system time programming errors Greg Kroah-Hartman
` (86 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Felix Fietkau, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit f5e0b20f6c6d548d985acdd620c5110776c915c2 ]
The firmware needs the driver to remove active links from the BSSINFO table
when it destroys the interface. A link therefore stays registered from its
first chanctx assignment until the interface goes away. If the driver holds
the link already, a second add does nothing.
mac80211 gives a non-AP MLD a new address each time it sets a link up. A link
that comes back after a failed attempt thus carries an address that the
hardware does not know, on a BSS that the driver never programs again. The
station then authenticates from an address that nothing answers. The failure
repeats until the driver tears the interface down for good.
Program the address and the BSS again. This is the pair that the initial add
sets up. For a station it does what mt7996_mcu_mld_link_oper() does for an AP.
Fixes: 08813703ac41 ("wifi: mt76: mt7996: Destroy vif active links in mt7996_remove_interface()")
Link: https://patch.msgid.link/20260818125825.395538-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/main.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index c6140412ed322..484fe880232b4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -310,7 +310,14 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif,
if (vif->type == NL80211_IFTYPE_AP)
return mt7996_mcu_mld_link_oper(dev, link_conf, link,
true);
- return 0;
+
+ /* update the link address */
+ ret = mt7996_mcu_add_dev_info(phy, vif, link_conf, mlink, true);
+ if (ret)
+ return ret;
+
+ return mt7996_mcu_add_bss_info(phy, vif, link_conf, mlink,
+ msta_link, true);
}
mlink->idx = __ffs64(~dev->mt76.vif_mask);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 202/281] net: stmmac: propagate PTP addend and system time programming errors
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (200 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 201/281] wifi: mt76: mt7996: program a link again if the driver holds it Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 203/281] tee: optee: ffa: support shared memory offsets on large-page kernels Greg Kroah-Hartman
` (85 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Maxime Chevallier,
David S. Miller, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
[ Upstream commit 232d49dd4b40a666283de9e722899f088ed581b2 ]
stmmac_update_subsecond_increment() ignores the error returned by
stmmac_config_addend(), and stmmac_init_tstamp_counter() discards the
addend and system time programming errors, always returning success. A
failure to program the addend (PTP_TCR_TSADDREG) or to initialize the
system time counter (PTP_TCR_TSINIT) is therefore silently swallowed,
leaving the hardware timestamp counter in a non-running or partially
configured state while the driver keeps operating as if timestamping
were up. This matters for TAPRIO/EST offloading, which derives the gate
base time from the hardware timestamp counter.
The same hooks are also called from the PHC callbacks: settime64 and
adjfine drop the error and report success to clock_settime() and
clock_adjtime(), so a dead PTP reference clock goes unnoticed by
ptp4l/phc2sys.
Return error codes from stmmac_update_subsecond_increment(),
stmmac_init_tstamp_counter(), stmmac_dl_ts_coarse_set() and the
settime64/adjfine callbacks instead of silently returning success. On
failure, roll back the partially applied configuration so the hardware
and the driver bookkeeping stay consistent, and report the reason
through the devlink extack. Also guard against a zero sub-second
increment, which would otherwise divide by zero when computing the
addend.
Reset the persistent timestamping state (hwts_tx_en, hwts_rx_en,
tstamp_config, systime_flags and tsfupdt_coarse) when (re)initializing
timestamping, so a failed init does not leave TX/RX timestamping
enabled on a counter that never started.
Fixes: cc4c9001ce31 ("net: stmmac: Switch stmmac_hwtimestamp to generic HW Interface Helpers")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 106 +++++++++++++-----
.../net/ethernet/stmicro/stmmac/stmmac_ptp.c | 10 +-
2 files changed, 84 insertions(+), 32 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 010fef79ec01e..034d9f941d402 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -601,31 +601,64 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
}
}
-static void stmmac_update_subsecond_increment(struct stmmac_priv *priv)
+static void stmmac_restore_subsecond_increment(struct stmmac_priv *priv,
+ u32 default_addend)
{
bool xmac = dwmac_is_xmac(priv->plat->core_type);
u32 sec_inc = 0;
- u64 temp = 0;
+ stmmac_config_addend(priv, priv->ptpaddr, default_addend);
stmmac_config_hw_tstamping(priv, priv->ptpaddr, priv->systime_flags);
+ stmmac_config_sub_second_increment(priv, priv->ptpaddr,
+ priv->plat->clk_ptp_rate,
+ xmac, &sec_inc);
+ priv->default_addend = default_addend;
+ priv->sub_second_inc = sec_inc;
+}
+
+static int stmmac_update_subsecond_increment(struct stmmac_priv *priv,
+ u32 systime_flags)
+{
+ bool xmac = dwmac_is_xmac(priv->plat->core_type);
+ u32 sec_inc = 0, val;
+ u64 temp = 0;
+ int ret;
+
+ stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags);
/* program Sub Second Increment reg */
stmmac_config_sub_second_increment(priv, priv->ptpaddr,
priv->plat->clk_ptp_rate,
xmac, &sec_inc);
- temp = div_u64(1000000000ULL, sec_inc);
-
- /* Store sub second increment for later use */
- priv->sub_second_inc = sec_inc;
+ if (!sec_inc) {
+ ret = -EINVAL;
+ goto error;
+ }
/* calculate default added value:
* formula is :
* addend = (2^32)/freq_div_ratio;
* where, freq_div_ratio = 1e9ns/sec_inc
*/
+ temp = div_u64(1000000000ULL, sec_inc);
temp = (u64)(temp << 32);
- priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate);
- stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend);
+ val = div_u64(temp, priv->plat->clk_ptp_rate);
+
+ ret = stmmac_config_addend(priv, priv->ptpaddr, val);
+ if (ret)
+ goto error;
+
+ priv->sub_second_inc = sec_inc;
+ priv->default_addend = val;
+
+ return 0;
+error:
+ /* Restore previous configuration */
+ stmmac_config_hw_tstamping(priv, priv->ptpaddr, priv->systime_flags);
+ stmmac_config_sub_second_increment(priv, priv->ptpaddr,
+ priv->plat->clk_ptp_rate, xmac,
+ NULL);
+ return ret;
}
/**
@@ -854,35 +887,42 @@ static int stmmac_hwtstamp_get(struct net_device *dev,
/**
* stmmac_init_tstamp_counter - init hardware timestamping counter
* @priv: driver private structure
- * @systime_flags: timestamping flags
* Description:
* Initialize hardware counter for packet timestamping.
* This is valid as long as the interface is open and not suspended.
* Will be rerun after resuming from suspend, case in which the timestamping
* flags updated by stmmac_hwtstamp_set() also need to be restored.
*/
-static int stmmac_init_tstamp_counter(struct stmmac_priv *priv,
- u32 systime_flags)
+static int stmmac_init_tstamp_counter(struct stmmac_priv *priv)
{
+ u32 default_addend = priv->default_addend;
struct timespec64 now;
+ int ret;
if (!priv->plat->clk_ptp_rate) {
netdev_err(priv->dev, "Invalid PTP clock rate");
return -EINVAL;
}
- stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags);
- priv->systime_flags = systime_flags;
-
- stmmac_update_subsecond_increment(priv);
+ ret = stmmac_update_subsecond_increment(priv, priv->systime_flags);
+ if (ret)
+ return ret;
/* initialize system time */
ktime_get_real_ts64(&now);
/* lower 32 bits of tv_sec are safe until y2106 */
- stmmac_init_systime(priv, priv->ptpaddr, (u32)now.tv_sec, now.tv_nsec);
+ ret = stmmac_init_systime(priv, priv->ptpaddr, (u32)now.tv_sec,
+ now.tv_nsec);
+ if (ret)
+ goto error;
return 0;
+error:
+ /* Restore previous configuration */
+ stmmac_restore_subsecond_increment(priv, default_addend);
+
+ return ret;
}
/**
@@ -905,8 +945,14 @@ static int stmmac_init_timestamping(struct stmmac_priv *priv)
return -EOPNOTSUPP;
}
- ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE |
- PTP_TCR_TSCFUPDT);
+ /* Reset hw ts configuration */
+ memset(&priv->tstamp_config, 0, sizeof(priv->tstamp_config));
+ priv->systime_flags = STMMAC_HWTS_ACTIVE | PTP_TCR_TSCFUPDT;
+ priv->tsfupdt_coarse = false;
+ priv->hwts_tx_en = 0;
+ priv->hwts_rx_en = 0;
+
+ ret = stmmac_init_tstamp_counter(priv);
if (ret) {
netdev_warn(priv->dev, "PTP init failed\n");
return ret;
@@ -927,10 +973,6 @@ static int stmmac_init_timestamping(struct stmmac_priv *priv)
netdev_info(priv->dev,
"IEEE 1588-2008 Advanced Timestamp supported\n");
- memset(&priv->tstamp_config, 0, sizeof(priv->tstamp_config));
- priv->hwts_tx_en = 0;
- priv->hwts_rx_en = 0;
-
if (priv->plat->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY)
stmmac_hwtstamp_correct_latency(priv, priv);
@@ -7718,18 +7760,26 @@ static int stmmac_dl_ts_coarse_set(struct devlink *dl, u32 id,
{
struct stmmac_devlink_priv *dl_priv = devlink_priv(dl);
struct stmmac_priv *priv = dl_priv->stmmac_priv;
+ u32 systime_flags = priv->systime_flags;
+ int ret;
- priv->tsfupdt_coarse = ctx->val.vbool;
-
- if (priv->tsfupdt_coarse)
- priv->systime_flags &= ~PTP_TCR_TSCFUPDT;
+ if (ctx->val.vbool)
+ systime_flags &= ~PTP_TCR_TSCFUPDT;
else
- priv->systime_flags |= PTP_TCR_TSCFUPDT;
+ systime_flags |= PTP_TCR_TSCFUPDT;
/* In Coarse mode, we can use a smaller subsecond increment, let's
* reconfigure the systime, subsecond increment and addend.
*/
- stmmac_update_subsecond_increment(priv);
+ ret = stmmac_update_subsecond_increment(priv, systime_flags);
+ if (ret) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "failed to reconfigure PTP adjustment");
+ return ret;
+ }
+
+ priv->tsfupdt_coarse = ctx->val.vbool;
+ priv->systime_flags = systime_flags;
return 0;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 3bfcc9760dce7..493c5d81a36bf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -28,14 +28,15 @@ static int stmmac_adjust_freq(struct ptp_clock_info *ptp, long scaled_ppm)
container_of(ptp, struct stmmac_priv, ptp_clock_ops);
unsigned long flags;
u32 addend;
+ int ret;
addend = adjust_by_scaled_ppm(priv->default_addend, scaled_ppm);
write_lock_irqsave(&priv->ptp_lock, flags);
- stmmac_config_addend(priv, priv->ptpaddr, addend);
+ ret = stmmac_config_addend(priv, priv->ptpaddr, addend);
write_unlock_irqrestore(&priv->ptp_lock, flags);
- return 0;
+ return ret;
}
/**
@@ -153,12 +154,13 @@ static int stmmac_set_time(struct ptp_clock_info *ptp,
struct stmmac_priv *priv =
container_of(ptp, struct stmmac_priv, ptp_clock_ops);
unsigned long flags;
+ int ret;
write_lock_irqsave(&priv->ptp_lock, flags);
- stmmac_init_systime(priv, priv->ptpaddr, ts->tv_sec, ts->tv_nsec);
+ ret = stmmac_init_systime(priv, priv->ptpaddr, ts->tv_sec, ts->tv_nsec);
write_unlock_irqrestore(&priv->ptp_lock, flags);
- return 0;
+ return ret;
}
static int stmmac_enable(struct ptp_clock_info *ptp,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 203/281] tee: optee: ffa: support shared memory offsets on large-page kernels
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (201 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 202/281] net: stmmac: propagate PTP addend and system time programming errors Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 204/281] bonding: fix the program leak when XDP is replaced Greg Kroah-Hartman
` (84 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Liming Sun, James Hurley,
Dave Thompson, Mahantesh Salimath, Sumit Garg, Jens Wiklander,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mahantesh Salimath <mahantesh@nvidia.com>
[ Upstream commit 3c0d2f1f431c51a11253f28763be723ac782fd7a ]
OP-TEE FF-A memory objects use 4 KiB pages, while the kernel page
size may be larger. Consequently, tee_shm->offset can be greater than
or equal to FFA_PAGE_SIZE, but OP-TEE rejects such a value in
internal_offs.
Do not encode the excess page offset in offs_low/offs_high. Those
fields describe the logical memref offset and are copied back into
tee_param->shm_offs on return. Folding the page offset into them breaks
parameter round trips when a memref is reused. They are also ignored by
the OPTEE_RPC_CMD_SHM_ALLOC response path, which uses only global_id and
internal_offs to construct the shared-memory mobj.
Instead, start the FF-A descriptor at the 4 KiB page containing the
shared buffer, the same approach as optee_fill_pages_list() in the SMC
ABI. Store the remaining in-page offset in internal_offs and preserve
shm_offs in offs_low/offs_high. This keeps internal_offs within the
FF-A page size, maps RPC allocations at the correct address, and
preserves normal memref offsets across repeated invocations.
Tested on ARMv8-A with 64 KiB PAGE_SIZE. OP-TEE OS ran as a secure
partition under Hafnium (SPMC) over FF-A. Verified registered shared
memory with tee_shm->offset >= 4 KiB, memref reuse on the same
TEEC_Operation, and RPC OPTEE_RPC_CMD_SHM_ALLOC (xtest regression
6007-6009). optee_hello_world, optee_aes, and xtest regression 1005,
1007, 1008, 4001-4003 and 6001-6003 also passed.
Fixes: 4615e5a34b95 ("optee: add FF-A support")
Acked-by: Liming Sun <limings@nvidia.com>
Acked-by: James Hurley <jahurley@nvidia.com>
Acked-by: Dave Thompson <davthompson@nvidia.com>
Signed-off-by: Mahantesh Salimath <mahantesh@nvidia.com>
Reviewed-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
Signed-off-by: Jens Wiklander <jens.wiklander@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tee/optee/ffa_abi.c | 22 ++++++++++++++++++----
drivers/tee/optee/optee_msg.h | 4 ++--
2 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c
index d3cc7c5fc1e99..d027fe7ce86fd 100644
--- a/drivers/tee/optee/ffa_abi.c
+++ b/drivers/tee/optee/ffa_abi.c
@@ -198,7 +198,8 @@ static int to_msg_param_ffa_mem(struct optee_msg_param *mp,
if (shm) {
u64 shm_offs = p->u.memref.shm_offs;
- mp->u.fmem.internal_offs = shm->offset;
+ mp->u.fmem.internal_offs = tee_shm_get_page_offset(shm) &
+ (FFA_PAGE_SIZE - 1);
mp->u.fmem.offs_low = shm_offs;
mp->u.fmem.offs_high = shm_offs >> 32;
@@ -284,14 +285,26 @@ static int optee_ffa_shm_register(struct tee_context *ctx, struct tee_shm *shm,
.nattrs = 1,
};
struct sg_table sgt;
+ size_t ffa_offs;
int rc;
+ if (!num_pages)
+ return -EINVAL;
+
rc = optee_check_mem_type(start, num_pages);
if (rc)
return rc;
- rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0,
- num_pages * PAGE_SIZE, GFP_KERNEL);
+ /*
+ * Start the FF-A descriptor at the 4 KiB page containing the shared
+ * buffer, skipping unused leading 4 KiB pages when PAGE_SIZE is
+ * larger. Same approach as optee_fill_pages_list() in the SMC ABI.
+ * This leaves only the offset into that 4 KiB page for internal_offs.
+ */
+ ffa_offs = round_down(tee_shm_get_page_offset(shm), FFA_PAGE_SIZE);
+ rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, ffa_offs,
+ num_pages * PAGE_SIZE - ffa_offs,
+ GFP_KERNEL);
if (rc)
return rc;
args.sg = sgt.sgl;
@@ -458,7 +471,8 @@ static void handle_ffa_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
.attr = OPTEE_MSG_ATTR_TYPE_FMEM_OUTPUT,
.u.fmem.size = tee_shm_get_size(shm),
.u.fmem.global_id = shm->sec_world_id,
- .u.fmem.internal_offs = shm->offset,
+ .u.fmem.internal_offs = tee_shm_get_page_offset(shm) &
+ (FFA_PAGE_SIZE - 1),
};
arg->ret = TEEC_SUCCESS;
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
index 7d9b12e71c035..6c3043f8da33c 100644
--- a/drivers/tee/optee/optee_msg.h
+++ b/drivers/tee/optee/optee_msg.h
@@ -136,8 +136,8 @@ struct optee_msg_param_rmem {
* struct optee_msg_param_fmem - FF-A memory reference parameter
* @offs_low: lower bits of offset into shared memory reference
* @offs_high: higher bits of offset into shared memory reference
- * @internal_offs: internal offset into the first page of shared memory
- * reference
+ * @internal_offs: offset into the first 4 KiB page of the FF-A shared
+ * memory region
* @size: size of the buffer
* @global_id: global identifier of the shared memory
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 204/281] bonding: fix the program leak when XDP is replaced
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (202 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 203/281] tee: optee: ffa: support shared memory offsets on large-page kernels Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 205/281] ice: Restore Ordered MMIO Writes for Tx Doorbells Greg Kroah-Hartman
` (83 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daniel Borkmann, Jiayuan Chen,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit 184b5ddf82d45d6f75cc83719a2e453392512bd2 ]
We need to release the reference on the old BPF prog, whether
we are going to no-prog, or replacing the prog with another.
Spotted by AI while running tests for the propagation series
(leaked programs were accumulating). Selftest will come in
the net-next series to avoid conflicts.
Fixes: 9e2ee5c7e7c3 ("net, bonding: Add XDP support to the bonding driver")
Fixes: 6d5f1ef83868 ("bonding: Fix negative jump label count on nested bonding")
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://patch.msgid.link/20261001012639.298690-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/bonding/bond_main.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 34c5bbbed9aee..507d655eca21e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -5738,12 +5738,12 @@ static int bond_xdp_set(struct net_device *dev, struct bpf_prog *prog,
bpf_prog_inc(prog);
}
- if (prog) {
+ if (prog && !old_prog)
static_branch_inc(&bpf_master_redirect_enabled_key);
- } else if (old_prog) {
- bpf_prog_put(old_prog);
+ else if (!prog && old_prog)
static_branch_dec(&bpf_master_redirect_enabled_key);
- }
+ if (old_prog)
+ bpf_prog_put(old_prog);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 205/281] ice: Restore Ordered MMIO Writes for Tx Doorbells
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (203 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 204/281] bonding: fix the program leak when XDP is replaced Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 206/281] nvmet: return Invalid Field for invalid NSIDs feature 82h Greg Kroah-Hartman
` (82 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bryan Fraschetti, Alexander Nowlin,
Tony Nguyen, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryan Fraschetti <bryan.fraschetti@canonical.com>
[ Upstream commit 7a579dec8423bba7bec96fcfcb2e30838b0858ee ]
The DQL accounting state which tracks the number of bytes queued for the
NIC to transmit, namely dql->num_queued, is updated by the ICE driver
when it invokes __netdev_tx_sent_queue(). Subsequently the driver
updates the hardware queue tail allowing the NIC to begin processing the
work queue. The queue accounting update should be ordered before the NIC
begins transmitting descriptors.
The transmit path currently updates the hardware doorbell using
writel_relaxed(), which (on arm64) does not provide the same ordering
guarantees between writes to normal memory and writes to MMIO registers
that writel() does. This introduces a potential race where the NIC
begins transmitting descriptors before the dql->num_queued update is
globally visible. If the NIC finishes before the update is observed by
dql_completed(), it detects an invalid state where more bytes have been
completed than have been queued. When this happens the following BUG_ON
is triggered.
BUG_ON(count > num_queued - dql->num_completed);
This has been observed and manifests as the following crash (note that
the trace has been trimmed) in an environment with sustained network
load that uses an Intel Corporation Ethernet Controller E810-XXV for SFP
(rev 02) on an arm64 machine. Replacing writel_relaxed() with writel()
in a test kernel eliminated the crash in the user's workload, which
previously reproduced the issue reliably.
kernel BUG at lib/dynamic_queue_limits.c:99
Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
pc : dql_completed+0x268/0x2a0
lr : ice_clean_tx_irq+0x1d4/0x620 [ice]
Call trace:
dql_completed+0x268/0x2a0 (P)
ice_napi_poll+0x94/0x520 [ice]
__napi_poll+0x48/0x3f0
net_rx_action+0x194/0x420
This restores the behaviour prior to commit ccde82e90946 ("ice: add E830
Earliest TxTime First Offload support"), which changed the notification
mechanism from writel() to writel_relaxed().
Link: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2161572
Fixes: ccde82e90946 ("ice: add E830 Earliest TxTime First Offload support")
Signed-off-by: Bryan Fraschetti <bryan.fraschetti@canonical.com>
Tested-by: Alexander Nowlin <alexander.nowlin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Link: https://patch.msgid.link/20260928230429.495442-4-anthony.l.nguyen@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/ice/ice_txrx.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
index c04c5856dad6e..4e26ace793ec6 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
@@ -1561,10 +1561,10 @@ ice_tx_map(struct ice_tx_ring *tx_ring, struct ice_tx_buf *first,
}
}
tstamp_ring->next_to_use = j;
- writel_relaxed(j, tstamp_ring->tail);
+ writel(j, tstamp_ring->tail);
} else {
ring_kick:
- writel_relaxed(i, tx_ring->tail);
+ writel(i, tx_ring->tail);
}
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 206/281] nvmet: return Invalid Field for invalid NSIDs feature 82h
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (204 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 205/281] ice: Restore Ordered MMIO Writes for Tx Doorbells Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 207/281] nvmet: use the local P2P device on metadata allocation failure Greg Kroah-Hartman
` (81 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Nilay Shroff,
Guixin Liu, Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guixin Liu <kanie@linux.alibaba.com>
[ Upstream commit d99bc5b456fd63be46c8bda20dbf6ede93d2fc11 ]
The Reservation Notification Mask feature (FID 82h) defines its own
status code for namespaces that do not support reservations:
"If a Set Features command or a Get Features command attempts to
access the Reservation Notification Mask on a namespace that does
not support reservations or is invalid, then that command is
aborted with status code of Invalid Field in Command."
-- NVMe Base Specification, section 5.2.26.1.33
The Set Features handler routes the namespace lookup through
nvmet_req_find_ns(), which returns Invalid Namespace or Format for an
unknown NSID. That is the correct status for the generic
namespace-scoped admin commands, but not for this feature: a Set
Features 82h naming a nonexistent NSID is aborted with Invalid
Namespace or Format instead of Invalid Field in Command.
Translate the lookup failure to Invalid Field in Command. The
broadcast NSID, the namespace-without-reservations case and everything
else keep their current behavior.
Fixes: 5a47c2080a73 ("nvmet: support reservation feature")
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/pr.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/nvme/target/pr.c b/drivers/nvme/target/pr.c
index ad07f55e7f173..acb44df15fc7e 100644
--- a/drivers/nvme/target/pr.c
+++ b/drivers/nvme/target/pr.c
@@ -51,6 +51,8 @@ u16 nvmet_set_feat_resv_notif_mask(struct nvmet_req *req, u32 mask)
if (nsid != U32_MAX) {
status = nvmet_req_find_ns(req);
+ if (status == (NVME_SC_INVALID_NS | NVME_STATUS_DNR))
+ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
if (status)
return status;
if (!req->ns->pr.enable)
@@ -75,6 +77,8 @@ u16 nvmet_get_feat_resv_notif_mask(struct nvmet_req *req)
u16 status;
status = nvmet_req_find_ns(req);
+ if (status == (NVME_SC_INVALID_NS | NVME_STATUS_DNR))
+ return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
if (status)
return status;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 207/281] nvmet: use the local P2P device on metadata allocation failure
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (205 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 206/281] nvmet: return Invalid Field for invalid NSIDs feature 82h Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 208/281] arm64/boot: Dont set PMUv3p9 FGT2 bits without PMUv3 Greg Kroah-Hartman
` (80 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Changyul Lee, Maurizio Lombardi,
Sang-Hoon Choi, Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Hoon Choi <csh0052@gmail.com>
[ Upstream commit 4aa9c0f377a4de5e8fddce76b34ee4529639a1ff ]
nvmet_req_alloc_p2pmem_sgls() assigns req->p2p_dev only after the data
and metadata SGL allocations succeed. If the data allocation succeeds
but the metadata allocation fails, out_free_sg passes req->p2p_dev to
pci_p2pmem_free_sgl() before that assignment has taken place.
Pass the local p2p_dev argument instead, so cleanup uses the same PCI
device as the successful data allocation.
Fixes: bcd9a0797d73 ("nvmet: fix freeing unallocated p2pmem")
Reported-by: Changyul Lee <lcy8047@gmail.com>
Reviewed-by: Maurizio Lombardi <mlombard@redhat.com>
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 2aa9ded7d5514..0b1f800c6cc8f 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -1310,7 +1310,7 @@ static int nvmet_req_alloc_p2pmem_sgls(struct pci_dev *p2p_dev,
return 0;
out_free_sg:
- pci_p2pmem_free_sgl(req->p2p_dev, req->sg);
+ pci_p2pmem_free_sgl(p2p_dev, req->sg);
out_err:
return -ENOMEM;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 208/281] arm64/boot: Dont set PMUv3p9 FGT2 bits without PMUv3
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (206 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 207/281] nvmet: use the local P2P device on metadata allocation failure Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 209/281] spi: spi-nxp-fspi: exit stop mode before waiting for DLL lock Greg Kroah-Hartman
` (79 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fuad Tabba, Bradley Morgan,
Anshuman Khandual, Will Deacon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <fuad.tabba@linux.dev>
[ Upstream commit b52ef450139f5632d7e53e6fd5f5ec46c7029dac ]
On a CPU with FGT2 and an IMPLEMENTATION DEFINED PMU (PMUVer 0b1111),
__init_el2_fgt2 sets the PMUv3p9 bits in HDFGRTR2_EL2 and HDFGWTR2_EL2,
which are RES0 there. The macro only checks that PMUVer is at least
PMUv3p9, and 0b1111 passes.
Exclude 0b1111 before the compare, as __init_el2_debug does.
Fixes: 858c7bfcb35e1 ("arm64/boot: Enable EL2 requirements for FEAT_PMUv3p9")
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/include/asm/el2_setup.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 87560d8b254e6..1da277baacf78 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -421,8 +421,9 @@
mov x2, xzr
mrs x1, id_aa64dfr0_el1
ubfx x1, x1, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
- cmp x1, #ID_AA64DFR0_EL1_PMUVer_V3P9
- b.lt .Lskip_pmuv3p9_\@
+ cmp x1, #ID_AA64DFR0_EL1_PMUVer_IMP_DEF
+ ccmp x1, #ID_AA64DFR0_EL1_PMUVer_V3P9, #8, ne
+ b.lt .Lskip_pmuv3p9_\@ // Skip if < PMUv3p9 or IMP_DEF
orr x0, x0, #HDFGRTR2_EL2_nPMICNTR_EL0
orr x0, x0, #HDFGRTR2_EL2_nPMICFILTR_EL0
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 209/281] spi: spi-nxp-fspi: exit stop mode before waiting for DLL lock
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (207 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 208/281] arm64/boot: Dont set PMUv3p9 FGT2 bits without PMUv3 Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 210/281] zloop: zero out only the unread tail of short reads Greg Kroah-Hartman
` (78 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Haibo Chen, Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haibo Chen <haibo.chen@nxp.com>
[ Upstream commit 94b6df050433875f493fb8298b58d7b0dc32eb9c ]
For 8D-8D-8D (octal DTR) mode the FlexSPI samples read data using
MCR0[RXCLKSRC] = 3 (flash-memory-provided read strobe on the DQS pad),
which requires the DLL to be locked. Per the i.MX95 Reference Manual
(FlexSPI chapter, "DLL configuration for sampling"), when the serial
root clock is above 100 MHz the DLL is enabled (DLLxCR[DLLEN] = 1,
OVRDEN = 0) and software must then wait for STS2[xREFLOCK] and
STS2[xSLVLOCK] to be asserted before starting a read or write. This DLL
lock is relative to the serial root clock.
While the module is in stop mode (MCR0[MDIS] = 1) the AHB and serial
clocks are gated off internally, so the serial root clock the DLL locks
against is not running. nxp_fspi_dll_calibration() both programs DLLxCR
and then polls STS2 for lock. When it runs entirely in stop mode the
STS2 REF/SLV lock bits never assert (observed as "DLL lock failed" with
STS2 = 0).
The MCR0 bit fields (RXCLKSRC) and the serial root clock rate still have
to be reconfigured in stop mode, so keep entering stop mode around that.
Only move the exit from stop mode (clearing MCR0[MDIS]) ahead of the DLL
calibration/override step, so that the serial root clock is running when
the DLL is calibrated and STS2 can report lock.
Fixes: b4bde5cfff8e ("spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL")
Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
Link: https://patch.msgid.link/20260928-fspi-fix-v1-1-a0f9288cd5c8@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-nxp-fspi.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
index 4425132432ec8..e0c88e9f81833 100644
--- a/drivers/spi/spi-nxp-fspi.c
+++ b/drivers/spi/spi-nxp-fspi.c
@@ -898,10 +898,10 @@ static int nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
dev_dbg(f->dev, "Target device [CS:%x] selected\n", spi_get_chipselect(spi, 0));
/*
- * Per the FlexSPI reference manual (initialization sequence), MCR0 and
- * the DLL control registers should be configured while the module is in
- * stop mode (MCR0[MDIS] = 1). Enter stop mode before reconfiguring the
- * RX sample clock source and the DLL, then exit stop mode afterwards.
+ * Per the FlexSPI reference manual (initialization sequence), MCR0
+ * should be configured while the module is in stop mode (MCR0[MDIS] = 1).
+ * Enter stop mode before reconfiguring the RX sample clock source, then
+ * exit stop mode afterwards.
*/
reg = fspi_readl(f, f->iobase + FSPI_MCR0);
fspi_writel(f, reg | FSPI_MCR0_MDIS, f->iobase + FSPI_MCR0);
@@ -936,6 +936,16 @@ static int nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
if (ret)
return ret;
+ /*
+ * Exit stop mode before running the DLL calibration. The DLL
+ * reference clock is derived from the module clock domain, which is
+ * gated while MCR0[MDIS] = 1. Calibrating the DLL in stop mode leaves
+ * the STS2 lock bits stuck at 0 (the DLL never runs), so clear MDIS
+ * first and let the module and reference clock run.
+ */
+ reg = fspi_readl(f, f->iobase + FSPI_MCR0);
+ fspi_writel(f, reg & ~FSPI_MCR0_MDIS, f->iobase + FSPI_MCR0);
+
/*
* If clock rate > 100MHz, then switch from DLL override mode to
* DLL calibration mode.
@@ -945,10 +955,6 @@ static int nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
else
nxp_fspi_dll_override(f);
- /* Exit stop mode now that MCR0 and the DLL have been reconfigured. */
- reg = fspi_readl(f, f->iobase + FSPI_MCR0);
- fspi_writel(f, reg & ~FSPI_MCR0_MDIS, f->iobase + FSPI_MCR0);
-
f->pre_op_rate = op->max_freq;
f->selected = spi_get_chipselect(spi, 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 210/281] zloop: zero out only the unread tail of short reads
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (208 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 209/281] spi: spi-nxp-fspi: exit stop mode before waiting for DLL lock Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 211/281] btrfs: always return -EIOCBQUEUED after btrfs_uring_read_extent_endio Greg Kroah-Hartman
` (77 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Damien Le Moal, Christoph Hellwig,
Shinichiro Kawasaki, Jens Axboe, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
[ Upstream commit 58304e139cb3fa640da74bc02101f0926d0607e2 ]
zloop_complete_rq() handles a short read from a zone's backing file by
zero-filling every bio in the request. This is correct when the entire
request is beyond the written part of the zone. When a read request
straddles the boundary between written and unwritten data, read_iter()
returns a partial byte count and zloop then zeroes the whole request
even for the partially read area with valid data.
Such an unexpected zero data read was observed with fio test script
t/zbd/test-zbd-support and its test case 69, failing with "bad magic
header 0".
Avoid the unexpected zero data read by zeroing out only the unread tail
part. When read data size cmd->ret is smaller than the request size,
call the new helper function zloop_fill_zero_rq() that walks through
each bio_vec and fills zeros from the specified start offset.
Fixes: eb0570c7df23 ("block: new zoned loop block device driver")
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Link: https://patch.msgid.link/20260916065657.62724-1-shinichiro.kawasaki@opensource.wdc.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/zloop.c | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/block/zloop.c b/drivers/block/zloop.c
index 1333fae05ac5d..a011f3e518a55 100644
--- a/drivers/block/zloop.c
+++ b/drivers/block/zloop.c
@@ -799,6 +799,27 @@ static void zloop_cmd_workfn(struct work_struct *work)
current->flags = orig_flags;
}
+static void zloop_fill_zero_rq(struct request *rq, unsigned int zero_from)
+{
+ struct req_iterator iter;
+ struct bio_vec bv;
+ unsigned int pos = 0;
+ unsigned int end, off;
+
+ rq_for_each_segment(bv, rq, iter) {
+ end = pos + bv.bv_len;
+ if (end > zero_from) {
+ if (pos < zero_from)
+ off = zero_from - pos;
+ else
+ off = 0;
+ memzero_page(bv.bv_page, bv.bv_offset + off,
+ bv.bv_len - off);
+ }
+ pos = end;
+ }
+}
+
static void zloop_complete_rq(struct request *rq)
{
struct zloop_cmd *cmd = blk_mq_rq_to_pdu(rq);
@@ -813,13 +834,9 @@ static void zloop_complete_rq(struct request *rq)
pr_err("Zone %u: failed read sector %llu, %llu sectors\n",
zone_no, cmd->sector, cmd->nr_sectors);
- if (cmd->ret >= 0 && cmd->ret != blk_rq_bytes(rq)) {
- /* short read */
- struct bio *bio;
-
- __rq_for_each_bio(bio, rq)
- zero_fill_bio(bio);
- }
+ /* Short read. Zero out the unread tail beyond cmd->ret. */
+ if (cmd->ret >= 0 && cmd->ret != blk_rq_bytes(rq))
+ zloop_fill_zero_rq(rq, cmd->ret);
break;
case REQ_OP_WRITE:
case REQ_OP_ZONE_APPEND:
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 211/281] btrfs: always return -EIOCBQUEUED after btrfs_uring_read_extent_endio
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (209 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 210/281] zloop: zero out only the unread tail of short reads Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 212/281] btrfs: free iov when btrfs_uring_read_extent() fails Greg Kroah-Hartman
` (76 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yue Sun, Jens Axboe, Yang Xiuwei,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Xiuwei <yangxiuwei@kylinos.cn>
[ Upstream commit 80a8dbb30d2b00b9c671b02bd73f700f6d20100f ]
If all bios finish before btrfs_encoded_read_regular_fill_pages()
returns, it calls btrfs_uring_read_extent_endio() and previously
returned the I/O status. A negative errno then made
btrfs_uring_read_extent() unlock and free while
btrfs_uring_read_finished() did the same again.
Return -EIOCBQUEUED so only the deferred path cleans up.
Reported-by: Yue Sun <samsun1006219@gmail.com>
Closes: https://lore.kernel.org/linux-btrfs/20260630091609.3414-1-samsun1006219@gmail.com/
Suggested-by: Jens Axboe <axboe@kernel.dk>
Fixes: 34310c442e17 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)")
Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/inode.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 7fe0a63d690a3..579b82e27b5ac 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -9622,7 +9622,6 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode,
struct completion sync_reads;
unsigned long i = 0;
struct btrfs_bio *bbio;
- int ret;
/*
* Fast path for synchronous reads which completes in this call, io_uring
@@ -9669,10 +9668,10 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode,
if (uring_ctx) {
if (refcount_dec_and_test(&priv->pending_refs)) {
- ret = blk_status_to_errno(READ_ONCE(priv->status));
- btrfs_uring_read_extent_endio(uring_ctx, ret);
+ int error = blk_status_to_errno(READ_ONCE(priv->status));
+
+ btrfs_uring_read_extent_endio(uring_ctx, error);
kfree(priv);
- return ret;
}
return -EIOCBQUEUED;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 212/281] btrfs: free iov when btrfs_uring_read_extent() fails
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (210 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 211/281] btrfs: always return -EIOCBQUEUED after btrfs_uring_read_extent_endio Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 213/281] btrfs: unlock inode and extent in caller when io_uring read extent fails Greg Kroah-Hartman
` (75 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yang Xiuwei, David Sterba,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Xiuwei <yangxiuwei@kylinos.cn>
[ Upstream commit a8ea92830b3e0e163d4e829bdcb17ca83c0f951c ]
After btrfs_uring_read_extent(), the caller always jumped to out_acct.
That skips kfree(data->iov), which is only correct for -EIOCBQUEUED
where the deferred path owns the iov. On failure, fall through to
out_free instead.
Fixes: 34310c442e17 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)")
Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ioctl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index a537036303a47..0ac2f449134a0 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4823,8 +4823,8 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue
cached_state, disk_bytenr, disk_io_size,
count, data->args.compression,
data->iov, cmd);
-
- goto out_acct;
+ if (ret == -EIOCBQUEUED)
+ goto out_acct;
}
out_free:
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 213/281] btrfs: unlock inode and extent in caller when io_uring read extent fails
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (211 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 212/281] btrfs: free iov when btrfs_uring_read_extent() fails Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 214/281] btrfs: dont stash io_uring encoded data across -EAGAIN Greg Kroah-Hartman
` (74 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Qu Wenruo, Yang Xiuwei,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Xiuwei <yangxiuwei@kylinos.cn>
[ Upstream commit b6e8add5d79d1f6f819a054c833bab452bd7365d ]
btrfs_uring_read_extent() runs only after btrfs_encoded_read() has taken
the inode shared lock and the extent lock. On failure it used to unlock
in out_fail, and a pages-array allocation failure returned -ENOMEM
without unlocking at all.
Unlock in the caller instead on all failure returns, matching the
copy_to_user() error path. The deferred -EIOCBQUEUED path still unlocks
in btrfs_uring_read_finished().
Fixes: 34310c442e17 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)")
Suggested-by: Qu Wenruo <quwenruo.btrfs@gmx.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ioctl.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 0ac2f449134a0..1c2e17bade5e5 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4559,7 +4559,7 @@ static void btrfs_uring_read_finished(struct io_tw_req tw_req, io_tw_token_t tw)
size_t page_offset;
ssize_t ret;
- /* The inode lock has already been acquired in btrfs_uring_read_extent. */
+ /* The inode lock has already been acquired in btrfs_encoded_read(). */
btrfs_lockdep_inode_acquire(inode, i_rwsem);
if (priv->err) {
@@ -4625,7 +4625,6 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter,
struct iovec *iov, struct io_uring_cmd *cmd)
{
struct btrfs_inode *inode = BTRFS_I(file_inode(iocb->ki_filp));
- struct extent_io_tree *io_tree = &inode->io_tree;
struct page **pages = NULL;
struct btrfs_uring_priv *priv = NULL;
unsigned long nr_pages;
@@ -4681,8 +4680,6 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter,
return -EIOCBQUEUED;
out_fail:
- btrfs_unlock_extent(io_tree, start, lockend, &cached_state);
- btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED);
kfree(priv);
for (int i = 0; i < nr_pages; i++) {
if (pages[i])
@@ -4825,6 +4822,8 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue
data->iov, cmd);
if (ret == -EIOCBQUEUED)
goto out_acct;
+ btrfs_unlock_extent(io_tree, start, lockend, &cached_state);
+ btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED);
}
out_free:
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 214/281] btrfs: dont stash io_uring encoded data across -EAGAIN
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (212 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 213/281] btrfs: unlock inode and extent in caller when io_uring read extent fails Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 215/281] btrfs: fix xattr replace when multiple xattrs are packed in the same item Greg Kroah-Hartman
` (73 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yang Xiuwei, David Sterba,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Xiuwei <yangxiuwei@kylinos.cn>
[ Upstream commit 51562a8cb11628d3a5e105b4c347ec5473e5745f ]
Returning -EAGAIN while leaving btrfs_uring_encoded_data in the cmd PDU
leaks if the request is cancelled or the ring exits before reissue.
io_uring does not free driver PDU allocations on cleanup.
Write: io_queue_sqe() always issues with IO_URING_F_NONBLOCK first, so
return -EAGAIN before allocating and free data on every exit.
Read: free on nowait -EAGAIN too; only -EIOCBQUEUED keeps the allocation
for btrfs_uring_read_finished().
Fixes: 34310c442e17 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)")
Fixes: e32dcdb0af9f ("btrfs: add io_uring interface for encoded writes")
Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ioctl.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 1c2e17bade5e5..833052306964b 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4792,7 +4792,7 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue
ret = btrfs_encoded_read(&kiocb, &data->iter, &data->args, &cached_state,
&disk_bytenr, &disk_io_size);
if (ret == -EAGAIN)
- goto out_acct;
+ goto out_free;
if (ret < 0 && ret != -EIOCBQUEUED)
goto out_free;
@@ -4834,8 +4834,10 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue
add_rchar(current, ret);
inc_syscr(current);
- if (ret != -EIOCBQUEUED && ret != -EAGAIN)
+ if (ret != -EIOCBQUEUED) {
kfree(data);
+ bc->data = NULL;
+ }
return ret;
}
@@ -4864,6 +4866,11 @@ static int btrfs_uring_encoded_write(struct io_uring_cmd *cmd, unsigned int issu
goto out_acct;
}
+ if (issue_flags & IO_URING_F_NONBLOCK) {
+ ret = -EAGAIN;
+ goto out_acct;
+ }
+
if (!data) {
data = kzalloc_obj(*data, GFP_NOFS);
if (!data) {
@@ -4932,11 +4939,6 @@ static int btrfs_uring_encoded_write(struct io_uring_cmd *cmd, unsigned int issu
}
}
- if (issue_flags & IO_URING_F_NONBLOCK) {
- ret = -EAGAIN;
- goto out_acct;
- }
-
pos = data->args.offset;
ret = rw_verify_area(WRITE, file, &pos, data->args.len);
if (ret < 0)
@@ -4962,8 +4964,8 @@ static int btrfs_uring_encoded_write(struct io_uring_cmd *cmd, unsigned int issu
add_wchar(current, ret);
inc_syscw(current);
- if (ret != -EAGAIN)
- kfree(data);
+ kfree(data);
+ bc->data = NULL;
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 215/281] btrfs: fix xattr replace when multiple xattrs are packed in the same item
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (213 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 214/281] btrfs: dont stash io_uring encoded data across -EAGAIN Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 216/281] btrfs: fix lost error return value in btrfs_listxattr() Greg Kroah-Hartman
` (72 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Filipe Manana,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit 858bee1c77857aabcc2327cd32dd8266332de332 ]
If we have a btrfs_dir_item item that packs multiple xattrs and then we
replace the value of one of them (with the setxattr(2) family of syscalls)
with another value of a different size, we end up not having a fully
initialized btrfs_dir_item, resulting in a corruption that the tree
checker will detect at extent buffer writeback time.
This is because in btrfs_setxattr() when we find a btrfs_dir_item with
multiple xattrs (due to the crc32c hash of their name being the same)
we delete one of the xattr items (btrfs_dir_item) and then insert a new
one, but the deletion and insertion results in shifting existing data in
the leaf and therefore when the new value of a xattr has a different size,
the new btrfs_dir_item is placed in a leaf section that was not
initialized and we only copy the value's data and set the value's length
in the new btrfs_dir_item, without setting the name, the name's length,
the key (which must be all zeroes for xattrs), flags (BTRFS_FT_XATTR) and
transaction ID.
The following script reproduces the issue:
$ cat test.sh
#!/bin/bash
DEV=/dev/sdi
MNT=/mnt/sdi
mkfs.btrfs -f $DEV
mount $DEV $MNT
touch $MNT/testfile
# Add two xattrs that, on btrfs, have the same hash (crc32c) for their
# name and therefore are packed into the same btrfs_dir_item.
setfattr -n user.foobar -v 123 $MNT/testfile
setfattr -n user.WvG1c1Td -v qwerty $MNT/testfile
# Verify the xattrs are present.
echo "xattrs before:"
getfattr --absolute-names --dump $MNT/testfile
# Now replace the value of the foobar xattr with a significantly larger
# value.
setfattr -n user.foobar -v abcdefghijklmnopqrstuvwxyz $MNT/testfile
# Check the xattrs have the expected values.
echo "xattrs after:"
getfattr --absolute-names --dump $MNT/testfile
umount $MNT
Running it:
$ ./test.sh
(...)
xattrs before:
# file: /mnt/sdi/testfile
user.WvG1c1Td="qwerty"
user.foobar="123"
xattrs after:
# file: /mnt/sdi/testfile
user.WvG1c1Td="qwerty"
So the "user.foobar" xattr is missing and there was a transaction abort
when unmounting the fs with the following traces in dmesg:
$ dmesg
[869800.159271] BTRFS warning (device sdi): access to eb bytenr 30474240 len 16384 out of range start 16015 len 25964
[869800.159293] ------------[ cut here ]------------
[869800.159296] WARNING: fs/btrfs/extent_io.c:4408 at report_eb_range+0x44/0x60 [btrfs], CPU#8: getfattr/2605179
[869800.168961] Modules linked in: btrfs dm_thin_pool (...)
[869800.190527] CPU: 8 UID: 0 PID: 2605179 Comm: getfattr Tainted: G W 7.3.0-rc3-btrfs-next-244+ #1 PREEMPT(full)
[869800.193726] Tainted: [W]=WARN
[869800.194502] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
[869800.197576] RIP: 0010:report_eb_range+0x44/0x60 [btrfs]
[869800.198985] Code: 48 8b 7b 18 (...)
[869800.203531] RSP: 0018:ffffce4541937d58 EFLAGS: 00010246
[869800.204609] RAX: 0000000000000000 RBX: ffff8dde054b8738 RCX: 0000000000000000
[869800.206137] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffffc04c92a0
[869800.207645] RBP: 0000000000003e8f R08: 0000000000000000 R09: 3fffffffffefffff
[869800.226175] R10: ffffce4541937a88 R11: 0000000000000003 R12: 000000000000656c
[869800.227594] R13: ffff8dde14be800f R14: 000000000000656c R15: 0000000000000069
[869800.229097] FS: 00007f59023bb780(0000) GS:ffff8de5788ed000(0000) knlGS:0000000000000000
[869800.231137] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[869800.232321] CR2: 0000558dc45e6a78 CR3: 0000000765b16004 CR4: 0000000000370ef0
[869800.233783] Call Trace:
[869800.234330] <TASK>
[869800.234791] read_extent_buffer+0x4d/0x100 [btrfs]
[869800.235898] btrfs_listxattr+0x199/0x240 [btrfs]
[869800.236912] vfs_listxattr+0x51/0xa0
[869800.237683] listxattr+0x7e/0x100
[869800.238398] path_listxattrat+0x9e/0x190
[869800.239117] do_syscall_64+0x89/0x470
[869800.239877] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[869800.240914] RIP: 0033:0x7f59024cdcb7
[869800.241686] Code: f0 ff ff 73 (...)
[869800.245353] RSP: 002b:00007ffd056dcdb8 EFLAGS: 00000246 ORIG_RAX: 00000000000000c2
[869800.246892] RAX: ffffffffffffffda RBX: 00007ffd056df2e2 RCX: 00007f59024cdcb7
[869800.248853] RDX: 0000000000006600 RSI: 0000558dc45e0470 RDI: 00007ffd056df2e2
[869800.250514] RBP: 00007ffd056df2e2 R08: 0000000000006600 R09: 0000000000006600
[869800.252295] R10: 0000000000000004 R11: 0000000000000246 R12: 00000000ffffff9c
[869800.254105] R13: 0000558dc45e0470 R14: 0000000000006600 R15: 0000000000000000
[869800.255931] </TASK>
[869800.256529] ---[ end trace 0000000000000000 ]---
[869800.260071] page: refcount:2 mapcount:0 mapping:000000007ccfc77f index:0x1d10 pfn:0x608c69
[869800.260075] memcg:ffff8dde00344d40
[869800.260076] aops:btree_aops [btrfs] ino:1
[869800.260151] flags: 0x17fffc00000402a(uptodate|lru|private|writeback|node=0|zone=2|lastcpupid=0x1ffff)
[869800.260154] raw: 017fffc00000402a fffff4adc773d4c8 fffff4adc48f3d88 ffff8de36504ba30
[869800.260155] raw: 0000000000001d10 ffff8dde054b8738 00000002ffffffff ffff8dde00344d40
[869800.260156] page dumped because: eb page dump
[869800.260157] BTRFS critical (device sdi): corrupt leaf: root=5 block=30474240 slot=5 ino=257, invalid location key type, have 46, expect 132 or 1
[869800.260161] BTRFS info (device sdi): leaf 30474240 gen 9 total ptrs 6 free space 15629 owner 5
[869800.260163] BTRFS info (device sdi): refs 3 lock_owner 0 current 2550294
[869800.260164] item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160
[869800.260165] inode generation 3 transid 0 size 0 nbytes 16384
[869800.260166] block group 0 mode 40755 links 1 uid 0 gid 0
[869800.260167] rdev 0 sequence 0 flags 0x0
[869800.260168] atime 1790340637.0
[869800.260169] ctime 1790340637.0
[869800.260169] mtime 1790340637.0
[869800.260170] otime 1790340637.0
[869800.260170] item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12
[869800.260172] index 0 name_len 2
[869800.260172] item 2 key (256 DIR_ITEM 982728850) itemoff 16073 itemsize 38
[869800.260173] location key (257 1 0) type 1
[869800.260174] transid 9 data_len 0 name_len 8
[869800.260175] item 3 key (257 INODE_ITEM 0) itemoff 15913 itemsize 160
[869800.260176] inode generation 9 transid 9 size 0 nbytes 0
[869800.260177] block group 0 mode 100664 links 1 uid 0 gid 0
[869800.260177] rdev 0 sequence 0 flags 0x0
[869800.260178] atime 1790340638.38778502
[869800.260179] ctime 1790340638.38778502
[869800.260179] mtime 1790340638.38778502
[869800.260180] otime 1790340638.38778502
[869800.260180] item 4 key (257 INODE_REF 256) itemoff 15895 itemsize 18
[869800.260181] index 2 name_len 8
[869800.260182] item 5 key (257 XATTR_ITEM 751495445) itemoff 15779 itemsize 116
[869800.260183] location key (0 0 0) type 8
[869800.266052] transid 9 data_len 6 name_len 13
[869800.266053] location key (8243121639454149888 46 7229457603934778967) type 0
[869800.266055] transid 113 data_len 26 name_len 0
[869800.266056] location key (8608196880778817904 120 162425) type 9
[869800.266057] transid 8391162079612502016 data_len 26982 name_len 25964
[869800.266058] BTRFS error (device sdi): block=30474240 write time tree block corruption detected
[869800.266091] ------------[ cut here ]------------
[869800.266092] WARNING: fs/btrfs/disk-io.c:336 at btree_csum_one_bio+0x20b/0x220 [btrfs], CPU#7: kworker/u50:7/2550294
[869800.268392] Modules linked in: btrfs dm_thin_pool (...)
[869800.365851] CPU: 7 UID: 0 PID: 2550294 Comm: kworker/u50:7 Tainted: G W 7.3.0-rc3-btrfs-next-244+ #1 PREEMPT(full)
[869800.368937] Tainted: [W]=WARN
[869800.369834] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
[869800.372778] Workqueue: writeback wb_workfn (flush-btrfs-3821)
[869800.374314] RIP: 0010:btree_csum_one_bio+0x20b/0x220 [btrfs]
[869800.375915] Code: 89 44 24 04 (...)
[869800.380639] RSP: 0018:ffffce4548e3f7d0 EFLAGS: 00010246
[869800.382008] RAX: 0000000000000000 RBX: ffff8dde054b8738 RCX: 0000000000000000
[869800.383850] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8de091c2ddc0
[869800.385710] RBP: ffff8dde196a2000 R08: 0000000000000000 R09: 3fffffffffefffff
[869800.387388] R10: ffffce4548e3f500 R11: 0000000000000003 R12: ffffce4548e3f7d8
[869800.388973] R13: ffff8dde196a2000 R14: ffff8de36504b750 R15: ffff8dde4c497b00
[869800.390414] FS: 0000000000000000(0000) GS:ffff8de5788ad000(0000) knlGS:0000000000000000
[869800.392002] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[869800.393160] CR2: 000055cd6e92ad5c CR3: 00000007cb264001 CR4: 0000000000370ef0
[869800.394595] Call Trace:
[869800.395113] <TASK>
[869800.395570] btrfs_submit_bbio+0x872/0x890 [btrfs]
[869800.397284] write_meta_extent_buffer+0x70/0x80 [btrfs]
[869800.398940] btree_writepages+0x141/0x4f0 [btrfs]
[869800.400426] ? get_random_u32+0x8a/0xf0
[869800.401417] ? build_slab_freelist+0x47/0x130
[869800.402574] ? preempt_count_add+0x6b/0xa0
[869800.403633] ? _raw_spin_lock_irqsave+0x23/0x50
[869800.404807] ? _raw_spin_unlock_irqrestore+0x22/0x40
[869800.406085] ? alloc_from_new_slab+0x18f/0x330
[869800.407223] do_writepages+0xc6/0x160
[869800.408191] ? refill_objects+0xd8/0x300
[869800.409211] __writeback_single_inode+0x42/0x350
[869800.410408] writeback_sb_inodes+0x231/0x560
[869800.411511] wb_writeback+0x8a/0x300
[869800.412440] wb_workfn+0xbf/0x460
[869800.413291] ? _raw_spin_unlock+0x14/0x30
[869800.414328] ? finish_task_switch.isra.0+0xb9/0x380
[869800.415105] process_one_work+0x1d1/0x3d0
[869800.416633] worker_thread+0x1c4/0x330
[869800.417467] ? __pfx_worker_thread+0x10/0x10
[869800.418452] kthread+0xfc/0x130
[869800.419257] ? __pfx_kthread+0x10/0x10
[869800.420089] ret_from_fork+0x1f7/0x2c0
[869800.420863] ? __pfx_kthread+0x10/0x10
[869800.421654] ret_from_fork_asm+0x1a/0x30
[869800.422484] </TASK>
[869800.422953] ---[ end trace 0000000000000000 ]---
[869800.424005] BTRFS error (device sdi state A): Transaction 9 aborted (-EIO)
[869800.424010] BTRFS: error (device sdi state A) in __btrfs_run_delayed_items:1162: errno=-5 IO failure
[869800.424011] BTRFS info (device sdi state EA): forced readonly
[869800.424013] BTRFS warning (device sdi state EA): Skipping commit of aborted transaction.
[869800.424014] BTRFS: error (device sdi state EA) in cleanup_transaction:2076: errno=-5 IO failure
Fix this by always setting all fields in the new btrfs_dir_item when we
replace an existing xattr.
Fixes: 5f5bc6b1e2d5 ("Btrfs: make xattr replace operations atomic")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/xattr.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index ab55d10bd71fd..e8762e12f3e1e 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -161,6 +161,7 @@ int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode,
const u16 old_data_len = btrfs_dir_data_len(leaf, di);
const u32 item_size = btrfs_item_size(leaf, slot);
const u32 data_size = sizeof(*di) + name_len + size;
+ unsigned long name_ptr;
unsigned long data_ptr;
char *ptr;
@@ -189,8 +190,16 @@ int btrfs_setxattr(struct btrfs_trans_handle *trans, struct inode *inode,
ptr = btrfs_item_ptr(leaf, slot, char);
ptr += btrfs_item_size(leaf, slot) - data_size;
di = (struct btrfs_dir_item *)ptr;
+ memzero_extent_buffer(leaf, (unsigned long)ptr +
+ offsetof(struct btrfs_dir_item, location),
+ sizeof(struct btrfs_disk_key));
+ btrfs_set_dir_flags(leaf, di, BTRFS_FT_XATTR);
+ btrfs_set_dir_transid(leaf, di, trans->transid);
+ btrfs_set_dir_name_len(leaf, di, name_len);
btrfs_set_dir_data_len(leaf, di, size);
+ name_ptr = (unsigned long)(di + 1);
data_ptr = ((unsigned long)(di + 1)) + name_len;
+ write_extent_buffer(leaf, name, name_ptr, name_len);
write_extent_buffer(leaf, value, data_ptr, size);
} else {
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 216/281] btrfs: fix lost error return value in btrfs_listxattr()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (214 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 215/281] btrfs: fix xattr replace when multiple xattrs are packed in the same item Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 217/281] drm/xe/mmio: Fix xe_mmio_wait32() to honor delay/sleep maximums Greg Kroah-Hartman
` (71 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Filipe Manana,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit 41c8899d59898f6fa51ceebd2b6e55257191a8ee ]
If the input buffer does not have enough space to store the current xattr,
we set 'iter_ret' to -ERANGE and then do "break", but that only exits the
while loop over the xattrs in the current btrfs_dir_item, and then we
continue the btrfs_for_each_slot() iteration, which overwrites the value
of 'iter_ret' causing us to lose the error return value and proceed as if
the buffer has enough space.
Fix this by returning -ERANGE directly (the path is automatically freed)
instead of breaking from the while loop.
Fixes: 184b3d190087 ("btrfs: use btrfs_for_each_slot in btrfs_listxattr")
Assisted-by: LLM (found the bug)
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/xattr.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index e8762e12f3e1e..cb001a211f557 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -329,10 +329,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
if (!size)
goto next;
- if (!buffer || (name_len + 1) > size_left) {
- iter_ret = -ERANGE;
- break;
- }
+ if (!buffer || (name_len + 1) > size_left)
+ return -ERANGE;
read_extent_buffer(leaf, buffer, name_ptr, name_len);
buffer[name_len] = '\0';
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 217/281] drm/xe/mmio: Fix xe_mmio_wait32() to honor delay/sleep maximums
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (215 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 216/281] btrfs: fix lost error return value in btrfs_listxattr() Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 218/281] drm/xe: Do not emit Wa_16010904313 twice Greg Kroah-Hartman
` (70 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alan Previn, Rodrigo Vivi,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alan Previn <alan.previn.teres.alexis@intel.com>
[ Upstream commit e7ed652b1312ffcb9ea2153946615856b5097c78 ]
Check for overflow in udelay use in __xe_mmio_wait32 and
avoid growing delays becoming intollerably large by capping the
in-loop wait time.
v7: - Change assisted-by to "LLM" (Rodrigo).
- Move the max-wait macro to outside the function (Rodrigo).
v6: - Fix commit message to remove items dropped in v5. Fix the
use of MAX_UDELAY_MS for microsecond unit. (Shasiko review).
v5: - Simplify: don't introduce additional redesign and
use min_t with a backoff to cap wait. (Rodrigo).
v4: - Simplify using poll_timeout_us and poll_timeout_us_atomic and
update all callers to never use a param for atomic (Jani)
v3: - Use div64_s64 kernel API for 32-bit vs 64-bit division.
v2: - Fixed checkpatch failure.
- Added helper for 64-bit DIV_ROUND_UP on 32-bit CPU (Shasiko
review). Fixed bug max range in usleep_range(Shasiko review)
Fixes: 5c09bd6ccd41 ("drm/xe/mmio: Move xe_mmio_wait32() to xe_mmio.c")
Signed-off-by: Alan Previn <alan.previn.teres.alexis@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Assisted-by: LLM
Link: https://patch.msgid.link/20260929192037.2233429-2-alan.previn.teres.alexis@intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
(cherry picked from commit 70dab9ee7d620e6018a64798aed065d14e9baed1)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/xe/xe_mmio.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
index 78adb303b6630..6907c1127d326 100644
--- a/drivers/gpu/drm/xe/xe_mmio.c
+++ b/drivers/gpu/drm/xe/xe_mmio.c
@@ -288,6 +288,7 @@ u64 xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg)
return (u64)udw << 32 | ldw;
}
+#define __XE_MMIO_WAIT_MAX_BACKOFF_100MS (100 * USEC_PER_MSEC)
static int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val,
u32 timeout_us, u32 *out_val, bool atomic, bool expect_match)
{
@@ -318,10 +319,10 @@ static int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u
wait = ktime_us_delta(end, cur);
if (atomic)
- udelay(wait);
+ udelay(min_t(s64, wait, (MAX_UDELAY_MS * 1000)));
else
usleep_range(wait, wait << 1);
- wait <<= 1;
+ wait = min_t(s64, wait << 1, __XE_MMIO_WAIT_MAX_BACKOFF_100MS);
}
if (ret != 0) {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 218/281] drm/xe: Do not emit Wa_16010904313 twice
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (216 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 217/281] drm/xe/mmio: Fix xe_mmio_wait32() to honor delay/sleep maximums Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 219/281] net: make dev_xdp_sb_prog_count() see programs attached through a link Greg Kroah-Hartman
` (69 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tvrtko Ursulin, Matt Roper,
Rodrigo Vivi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
[ Upstream commit f7fc61e66041b1f8300cad87005ba84604bfefd9 ]
During development of commit e8372edec948 ("drm/xe/xelp: Implement
Wa_16010904313")
one of the interim patch versions contained an incorrect rebase on top of
some upstream changes, which caused Wa_16010904313 to be emitted both from
the indirect context and from the workaround batch buffer.
As this workaround needs to be emitted from the indirect context for rcs
and ccs, but from the workaround batch buffer for bcs, vcs and vecs, we
need to pass the location as an input parameter to setup_timestamp_wa() so
it can decide whether to emit itself or not.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Fixes: e8372edec948 ("drm/xe/xelp: Implement Wa_16010904313")
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patch.msgid.link/20260925080016.64802-1-tvrtko.ursulin@igalia.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
[Rodrigo: small adjustments on commit message for check-patch]
(cherry picked from commit 38631a7bce195b88814b93bf2b6d3e48c827fef2)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/xe/xe_lrc.c | 38 ++++++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c
index 9f8217ff1904c..224e64bccaebc 100644
--- a/drivers/gpu/drm/xe/xe_lrc.c
+++ b/drivers/gpu/drm/xe/xe_lrc.c
@@ -1099,8 +1099,7 @@ static void xe_lrc_finish(struct xe_lrc *lrc)
#define CONTEXT_ACTIVE XE_LRC_CTX_TIMESTAMP_ACTIVE
static ssize_t setup_utilization_wa(struct xe_lrc *lrc,
struct xe_hw_engine *hwe,
- u32 *batch,
- size_t max_len)
+ u32 *batch, size_t max_len, bool indirect)
{
u32 *cmd = batch;
@@ -1131,19 +1130,25 @@ static ssize_t setup_utilization_wa(struct xe_lrc *lrc,
}
static ssize_t setup_timestamp_wa(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
- u32 *batch, size_t max_len)
+ u32 *batch, size_t max_len, bool indirect)
{
const u32 ts_addr = __xe_lrc_ctx_timestamp_ggtt_addr(lrc);
u32 *cmd = batch;
- if (!XE_GT_WA(lrc->gt, 16010904313) ||
- !(hwe->class == XE_ENGINE_CLASS_RENDER ||
- hwe->class == XE_ENGINE_CLASS_COMPUTE ||
- hwe->class == XE_ENGINE_CLASS_COPY ||
+ if (!XE_GT_WA(lrc->gt, 16010904313))
+ return 0;
+
+ if (!indirect &&
+ !(hwe->class == XE_ENGINE_CLASS_COPY ||
hwe->class == XE_ENGINE_CLASS_VIDEO_DECODE ||
hwe->class == XE_ENGINE_CLASS_VIDEO_ENHANCE))
return 0;
+ if (indirect &&
+ !(hwe->class == XE_ENGINE_CLASS_RENDER ||
+ hwe->class == XE_ENGINE_CLASS_COMPUTE))
+ return 0;
+
if (xe_gt_WARN_ON(lrc->gt, max_len < 12))
return -ENOSPC;
@@ -1169,7 +1174,8 @@ static ssize_t setup_timestamp_wa(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
static ssize_t setup_configfs_post_ctx_restore_bb(struct xe_lrc *lrc,
struct xe_hw_engine *hwe,
- u32 *batch, size_t max_len)
+ u32 *batch, size_t max_len,
+ bool indirect)
{
struct xe_device *xe = gt_to_xe(lrc->gt);
const u32 *user_batch;
@@ -1198,7 +1204,8 @@ static ssize_t setup_configfs_post_ctx_restore_bb(struct xe_lrc *lrc,
static ssize_t setup_configfs_mid_ctx_restore_bb(struct xe_lrc *lrc,
struct xe_hw_engine *hwe,
- u32 *batch, size_t max_len)
+ u32 *batch, size_t max_len,
+ bool indirect)
{
struct xe_device *xe = gt_to_xe(lrc->gt);
const u32 *user_batch;
@@ -1227,7 +1234,8 @@ static ssize_t setup_configfs_mid_ctx_restore_bb(struct xe_lrc *lrc,
static ssize_t setup_invalidate_state_cache_wa(struct xe_lrc *lrc,
struct xe_hw_engine *hwe,
- u32 *batch, size_t max_len)
+ u32 *batch, size_t max_len,
+ bool indirect)
{
u32 *cmd = batch;
@@ -1247,7 +1255,8 @@ static ssize_t setup_invalidate_state_cache_wa(struct xe_lrc *lrc,
static ssize_t setup_invalidate_auxccs_wa(struct xe_lrc *lrc,
struct xe_hw_engine *hwe,
- u32 *batch, size_t max_len)
+ u32 *batch, size_t max_len,
+ bool indirect)
{
struct xe_gt *gt = lrc->gt;
u32 *(*emit)(struct xe_gt *gt, u32 *cmd) =
@@ -1264,7 +1273,7 @@ static ssize_t setup_invalidate_auxccs_wa(struct xe_lrc *lrc,
struct bo_setup {
ssize_t (*setup)(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
- u32 *batch, size_t max_size);
+ u32 *batch, size_t max_size, bool indirect);
};
struct bo_setup_state {
@@ -1273,6 +1282,7 @@ struct bo_setup_state {
struct xe_hw_engine *hwe;
size_t max_size;
size_t reserve_dw;
+ bool indirect;
unsigned int offset;
const struct bo_setup *funcs;
unsigned int num_funcs;
@@ -1298,7 +1308,8 @@ static int setup_bo(struct bo_setup_state *state)
for (size_t i = 0; i < state->num_funcs; i++) {
ssize_t len = state->funcs[i].setup(state->lrc, state->hwe,
- state->ptr, remain);
+ state->ptr, remain,
+ state->indirect);
remain -= len;
@@ -1404,6 +1415,7 @@ setup_indirect_ctx(struct xe_lrc *lrc, struct xe_hw_engine *hwe)
struct bo_setup_state state = {
.lrc = lrc,
.hwe = hwe,
+ .indirect = true,
.max_size = (63 * 64) /* max 63 cachelines */,
.buffer = NULL,
.offset = __xe_lrc_indirect_ctx_offset(lrc),
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 219/281] net: make dev_xdp_sb_prog_count() see programs attached through a link
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (217 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 218/281] drm/xe: Do not emit Wa_16010904313 twice Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 220/281] net/mlx5: Lag, split aggregate speed into oper and max helpers Greg Kroah-Hartman
` (68 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stanislav Fomichev, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit d333c8bca6dc3c5e978f6698d39dd799f3b0dc8d ]
ethtool refuses to enable tcp-data-split on a device running
a single-buffer XDP program (which can't deal with the payload
landing in a separate buffer). dev_xdp_sb_prog_count() only looks
at xdp_state[].prog though, ignoring bpf_link integration.
Get the prog pointer from dev_xdp_prog(), which will consult both.
bpf_xdp_link_update() needs a bit of a touch-up, too, since
ethtool calls dev_xdp_sb_prog_count() with just the instance
lock (for ops-locked devices) - we now have to make sure the
link updates happen under that lock.
Spotted by AI while reviewing the XDP propagation series,
verified and tested on netdevsim with a C test along these lines:
link = bpf_program__attach_xdp(prog, ifindex);
system("ethtool -G eth0 tcp-data-split on")
Fixes: 197258f0ef68 ("net: ethtool: add hds_config member in ethtool_netdev_state")
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20261001012559.297751-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/dev.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 6f75d1d1af32c..1a06976e19563 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -10356,13 +10356,15 @@ EXPORT_SYMBOL_GPL(dev_xdp_prog_count);
u8 dev_xdp_sb_prog_count(struct net_device *dev)
{
+ struct bpf_prog *prog;
u8 count = 0;
int i;
- for (i = 0; i < __MAX_XDP_MODE; i++)
- if (dev->xdp_state[i].prog &&
- !dev->xdp_state[i].prog->aux->xdp_has_frags)
+ for (i = 0; i < __MAX_XDP_MODE; i++) {
+ prog = dev_xdp_prog(dev, i);
+ if (prog && !prog->aux->xdp_has_frags)
count++;
+ }
return count;
}
@@ -10742,11 +10744,12 @@ static int bpf_xdp_link_update(struct bpf_link *link, struct bpf_prog *new_prog,
bpf_op = dev_xdp_bpf_op(xdp_link->dev, mode);
err = dev_xdp_install(xdp_link->dev, mode, bpf_op, NULL,
xdp_link->flags, new_prog);
+ if (!err)
+ old_prog = xchg(&link->prog, new_prog);
netdev_unlock_ops(xdp_link->dev);
if (err)
goto out_unlock;
- old_prog = xchg(&link->prog, new_prog);
bpf_prog_put(old_prog);
out_unlock:
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 220/281] net/mlx5: Lag, split aggregate speed into oper and max helpers
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (218 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 219/281] net: make dev_xdp_sb_prog_count() see programs attached through a link Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 221/281] net: stmmac: Do not advertise S-VLAN stripping when it is disabled Greg Kroah-Hartman
` (67 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Or Har-Toov, Shay Drori, Mark Bloch,
Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Or Har-Toov <ohartoov@nvidia.com>
[ Upstream commit fe4114221364899ab33c3f9574da6b108d3fa79e ]
mlx5_lag_sum_devices_speed computes the LAG aggregate by summing oper
speeds across all ports. This has two bugs.
First, it relies on the assumption that a port whose carrier is down
will report an oper speed of zero and therefore not contribute to the
sum. This assumption does not always hold: when the link partner
disconnects the port transitions to DOWN state but firmware may still
report a non-zero oper speed, causing the aggregate to include a port
that is not actively carrying traffic.
Second, in active-backup mode only one port transmits at a time, so
the aggregate should reflect a single port speed rather than the sum
of all ports.
Fix this by splitting mlx5_lag_sum_devices_speed into two helpers.
mlx5_lag_get_devices_oper_speed reflects the speed currently available:
it queries the vport state of each port and skips any port that is not
UP, rather than relying on oper speed being zero.
mlx5_lag_get_devices_max_speed is state-independent and returns the
maximum achievable speed used as a fallback when speed is 0; for
active-backup it takes the maximum single-port speed instead of the sum.
The bugs were discovered during integration and reproduced on a
back-to-back ConnectX-8 setup.
The first bug (stale oper speed when link goes down) was observed: after
the link partner disconnected, the aggregate TX speed reported to vports
remained full speed because firmware still returned the last oper speed,
causing vports to be rate-limited to the old aggregate speed.
The second bug (active-backup summing all port speeds instead of the
active port's speed) was also triggered: in active-backup mode the
computed aggregate was double the expected value since both port speeds
were summed even though only one port was active.
Fixes: 28ea6036dad2 ("net/mlx5: Handle port and vport speed change events in MPESW")
Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
Reviewed-by: Shay Drori <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260930170406.148548-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/mellanox/mlx5/core/lag/lag.c | 79 +++++++++++++------
1 file changed, 57 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
index 3b34bec559e08..4e173b08cb37a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
@@ -1432,30 +1432,40 @@ static bool mlx5_lag_should_disable_lag(struct mlx5_lag *ldev, bool do_bond)
}
#ifdef CONFIG_MLX5_ESWITCH
-static int
-mlx5_lag_sum_devices_speed(struct mlx5_lag *ldev, u32 *sum_speed,
- int (*get_speed)(struct mlx5_core_dev *, u32 *))
+static int mlx5_lag_get_devices_oper_speed(struct mlx5_lag *ldev,
+ u32 *sum_speed)
{
- struct mlx5_core_dev *pf_mdev;
- struct lag_func *pf;
int pf_idx;
- u32 speed;
- int ret;
*sum_speed = 0;
mlx5_ldev_for_each(pf_idx, 0, ldev) {
+ u8 opmod = MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT;
+ struct mlx5_core_dev *pf_mdev;
+ struct lag_func *pf;
+ u32 speed;
+ u8 state;
+ int ret;
+
pf = mlx5_lag_pf(ldev, pf_idx);
if (!pf)
continue;
pf_mdev = pf->dev;
if (!pf_mdev)
continue;
+ ret = mlx5_query_vport_max_tx_speed(pf_mdev, opmod, 0, 0,
+ &speed, &state);
+ if (ret) {
+ mlx5_core_dbg(pf_mdev, "State query failed (err=%d)\n",
+ ret);
+ return ret;
+ }
+ if (state != VPORT_STATE_UP)
+ continue;
- ret = get_speed(pf_mdev, &speed);
+ ret = mlx5_port_oper_linkspeed(pf_mdev, &speed);
if (ret) {
mlx5_core_dbg(pf_mdev,
- "Failed to get device speed using %ps. Device %s speed is not available (err=%d)\n",
- get_speed, dev_name(pf_mdev->device),
+ "Failed to get oper speed (err=%d)\n",
ret);
return ret;
}
@@ -1466,17 +1476,42 @@ mlx5_lag_sum_devices_speed(struct mlx5_lag *ldev, u32 *sum_speed,
return 0;
}
-static int mlx5_lag_sum_devices_max_speed(struct mlx5_lag *ldev, u32 *max_speed)
+static int mlx5_lag_get_devices_max_speed(struct mlx5_lag *ldev, u32 *max_speed)
{
- return mlx5_lag_sum_devices_speed(ldev, max_speed,
- mlx5_port_max_linkspeed);
-}
+ bool take_max;
+ int pf_idx;
-static int mlx5_lag_sum_devices_oper_speed(struct mlx5_lag *ldev,
- u32 *oper_speed)
-{
- return mlx5_lag_sum_devices_speed(ldev, oper_speed,
- mlx5_port_oper_linkspeed);
+ take_max = ldev->tracker.tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP;
+ if (ldev->mode == MLX5_LAG_MODE_MPESW)
+ take_max = false;
+
+ *max_speed = 0;
+ mlx5_ldev_for_each(pf_idx, 0, ldev) {
+ struct mlx5_core_dev *pf_mdev;
+ struct lag_func *pf;
+ u32 speed;
+ int ret;
+
+ pf = mlx5_lag_pf(ldev, pf_idx);
+ if (!pf)
+ continue;
+ pf_mdev = pf->dev;
+ if (!pf_mdev)
+ continue;
+
+ ret = mlx5_port_max_linkspeed(pf_mdev, &speed);
+ if (ret) {
+ mlx5_core_dbg(pf_mdev,
+ "Failed to get max speed (err=%d)\n",
+ ret);
+ return ret;
+ }
+
+ *max_speed = take_max ?
+ max(*max_speed, speed) : *max_speed + speed;
+ }
+
+ return 0;
}
static void mlx5_lag_modify_device_vports_speed(struct mlx5_core_dev *mdev,
@@ -1525,7 +1560,7 @@ void mlx5_lag_set_vports_agg_speed(struct mlx5_lag *ldev)
int pf_idx;
if (ldev->mode == MLX5_LAG_MODE_MPESW) {
- if (mlx5_lag_sum_devices_oper_speed(ldev, &speed))
+ if (mlx5_lag_get_devices_oper_speed(ldev, &speed))
return;
} else {
speed = ldev->tracker.bond_speed_mbps;
@@ -1533,8 +1568,8 @@ void mlx5_lag_set_vports_agg_speed(struct mlx5_lag *ldev)
return;
}
- /* If speed is not set, use the sum of max speeds of all PFs */
- if (!speed && mlx5_lag_sum_devices_max_speed(ldev, &speed))
+ /* If speed is not set, fall back to the max achievable speed */
+ if (!speed && mlx5_lag_get_devices_max_speed(ldev, &speed))
return;
speed = speed / MLX5_MAX_TX_SPEED_UNIT;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 221/281] net: stmmac: Do not advertise S-VLAN stripping when it is disabled
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (219 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 220/281] net/mlx5: Lag, split aggregate speed into oper and max helpers Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 222/281] net: stmmac: Disable S-Tag processing on dwmac4 Greg Kroah-Hartman
` (66 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ovidiu Panait, Maxime Chevallier,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
[ Upstream commit c63ce7b9c7e7b68267899e4a0fc14b35d2c1dfcc ]
C-VLAN and S-VLAN tag stripping are both controlled by the EVLS bit,
so disabling rx-vlan-offload also disables S-VLAN tag stripping.
However, rx-vlan-stag-hw-parse keeps being advertised as enabled:
root@rzv2h-evk:~# ethtool -K end1 rx-vlan-offload off
root@rzv2h-evk:~# ethtool -k end1 | grep -i vlan
rx-vlan-offload: off
tx-vlan-offload: off [fixed]
rx-vlan-filter: on [fixed]
vlan-challenged: off [fixed]
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: on [fixed]
rx-vlan-stag-filter: on [fixed]
Fix this inconsistency by making NETIF_F_HW_VLAN_STAG_RX follow
NETIF_F_HW_VLAN_CTAG_RX.
Fixes: 750011e239a5 ("net: stmmac: Add support for HW-accelerated VLAN stripping")
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260928203441.34876-5-ovidiu.panait.rb@renesas.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 034d9f941d402..78e2ad0af6623 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -6264,6 +6264,13 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
features &= ~NETIF_F_CSUM_MASK;
+ if (dwmac_is_xmac(priv->plat->core_type)) {
+ if (features & NETIF_F_HW_VLAN_CTAG_RX)
+ features |= NETIF_F_HW_VLAN_STAG_RX;
+ else
+ features &= ~NETIF_F_HW_VLAN_STAG_RX;
+ }
+
return features;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 222/281] net: stmmac: Disable S-Tag processing on dwmac4
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (220 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 221/281] net: stmmac: Do not advertise S-VLAN stripping when it is disabled Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:38 ` [PATCH 7.2 223/281] net: airoha: Add retry mechanism to airoha_qdma_set_trtcm_param() Greg Kroah-Hartman
` (65 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ovidiu Panait, Maxime Chevallier,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
[ Upstream commit da17990421d79f1bfb4142f9d767fd33daecc3d8 ]
Currently, hardware VLAN stripping is broken for 802.1ad tags. vlan_rx_hw()
hardcodes ETH_P_8021Q when putting the hardware tag into the skb, rather
than using the actual protocol from the packet. Because of this, packets
that contain a 802.1ad outer tag are incorrectly passed up the stack as
having an 802.1Q tag. This causes QinQ ping between two hosts to fail.
vlan_rx_hw() is shared by dwxgmac2 and dwmac4: on dwxgmac2 the tag type
is available in the RDES3 write-back descriptor (the ET_LT field), so the
outer tag type can be determined based on that info. However, dwmac4
doesn't seem to provide the tag type. The Length/Type field in RDES3 only
indicates whether the packet is single or double-tagged, not which tag
type was stripped.
Since dwmac4 cannot report the stripped tag type, it cannot support
hardware S-Tag stripping correctly. Therefore, restrict the
NETIF_F_HW_VLAN_STAG_RX and NETIF_F_HW_VLAN_STAG_FILTER advertisement
to dwxgmac2 only.
With this, 802.1ad tags are left in place and handled by the software
VLAN path.
Fixes: 750011e239a5 ("net: stmmac: Add support for HW-accelerated VLAN stripping")
Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260928203441.34876-6-ovidiu.panait.rb@renesas.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 78e2ad0af6623..22c94fca01822 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -6264,7 +6264,7 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
features &= ~NETIF_F_CSUM_MASK;
- if (dwmac_is_xmac(priv->plat->core_type)) {
+ if (priv->plat->core_type == DWMAC_CORE_XGMAC) {
if (features & NETIF_F_HW_VLAN_CTAG_RX)
features |= NETIF_F_HW_VLAN_STAG_RX;
else
@@ -8073,14 +8073,18 @@ static int __stmmac_dvr_probe(struct device *device,
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
#ifdef STMMAC_VLAN_TAG_USED
/* Both mac100 and gmac support receive VLAN tag detection */
- ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX;
+ ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+ if (priv->plat->core_type == DWMAC_CORE_XGMAC)
+ ndev->features |= NETIF_F_HW_VLAN_STAG_RX;
+
if (dwmac_is_xmac(priv->plat->core_type)) {
ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
priv->hw->hw_vlan_en = true;
}
if (priv->dma_cap.vlhash) {
ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
- ndev->features |= NETIF_F_HW_VLAN_STAG_FILTER;
+ if (priv->plat->core_type == DWMAC_CORE_XGMAC)
+ ndev->features |= NETIF_F_HW_VLAN_STAG_FILTER;
}
if (priv->dma_cap.vlins)
ndev->features |= NETIF_F_HW_VLAN_CTAG_TX;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 223/281] net: airoha: Add retry mechanism to airoha_qdma_set_trtcm_param()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (221 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 222/281] net: stmmac: Disable S-Tag processing on dwmac4 Greg Kroah-Hartman
@ 2026-10-13 11:38 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 224/281] riscv: vector: Fix data pointer constraints in context save/restore Greg Kroah-Hartman
` (64 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:38 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Leto Liu , Christian Marangi,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leto Liu (刘涛) <Leto.Liu@airoha.com>
[ Upstream commit 7e170da2edec9fb0717543571cc14b0aabee2b46 ]
CPU accesses QDMA via the bus. When multiple modules are using the bus
simultaneously, CPU access to QDMA may encounter bus timeouts and fails,
resulting in QDMA configuration failures and potentially causing packet
transmission issues. In order to mitigate the issue, introduce a retry
mechanism to airoha_qdma_set_trtcm_param routine in order to ensure the
configuration is correctly applied to the hardware.
It's enough to try a second time for the TRTCM config to be actually
applied to make sure we are not in the middle of bucket handling as it does
operate on fixed time slot internally.
Fixes: ef1ca9271313b ("net: airoha: Add sched HTB offload support")
Signed-off-by: Leto Liu (刘涛) <Leto.Liu@airoha.com>
[ improve commit description, drop memory block, apply better loop logic]
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Link: https://patch.msgid.link/20260930065855.46171-1-ansuelsmth@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 32 +++++++++++++++++++-----
drivers/net/ethernet/airoha/airoha_eth.h | 2 ++
2 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 2fc8c91f210c6..d4faf4503487e 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2716,14 +2716,34 @@ static int airoha_qdma_set_trtcm_param(struct airoha_qdma *qdma, int channel,
FIELD_PREP(TRTCM_METER_GROUP_MASK, group) |
FIELD_PREP(TRTCM_PARAM_INDEX_MASK, idx) |
FIELD_PREP(TRTCM_PARAM_RATE_TYPE_MASK, mode);
+ int i;
- airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val);
- airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config);
+ /*
+ * HW might be in the middle of bucket handling and might
+ * require an additional try to actually apply the new TRTCM
+ * config.
+ */
+ for (i = 0; i < TRTCM_CONFIG_RETRY_MAX; i++) {
+ u32 data = 0;
- return read_poll_timeout(airoha_qdma_rr, val,
- val & TRTCM_PARAM_RW_DONE_MASK,
- USEC_PER_MSEC, 10 * USEC_PER_MSEC, true,
- qdma, REG_TRTCM_CFG_PARAM(addr));
+ airoha_qdma_wr(qdma, REG_TRTCM_DATA_LOW(addr), val);
+ airoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config);
+
+ if (read_poll_timeout(airoha_qdma_rr, data,
+ data & TRTCM_PARAM_RW_DONE_MASK,
+ USEC_PER_MSEC, 10 * USEC_PER_MSEC,
+ true, qdma, REG_TRTCM_CFG_PARAM(addr)))
+ continue;
+
+ if (airoha_qdma_get_trtcm_param(qdma, channel, addr, param,
+ mode, &data, NULL))
+ continue;
+
+ if (data == val)
+ return 0;
+ }
+
+ return -EBUSY;
}
static int airoha_qdma_set_trtcm_config(struct airoha_qdma *qdma, int channel,
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 70f16189b2582..dc0c29001f810 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -171,6 +171,8 @@ enum trtcm_param {
#define TRTCM_TOKEN_RATE_MASK GENMASK(23, 6)
#define TRTCM_TOKEN_RATE_FRACTION_MASK GENMASK(5, 0)
+#define TRTCM_CONFIG_RETRY_MAX 2
+
enum airoha_dma_map_type {
AIROHA_DMA_UNMAPPED,
AIROHA_DMA_MAP_SINGLE,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 224/281] riscv: vector: Fix data pointer constraints in context save/restore
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (222 preceding siblings ...)
2026-10-13 11:38 ` [PATCH 7.2 223/281] net: airoha: Add retry mechanism to airoha_qdma_set_trtcm_param() Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 225/281] riscv: vector: Fix output operands in context save Greg Kroah-Hartman
` (63 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Troy Mitchell, GUO Ren (XuanTie),
Aurelien Jarno, Andy Chiu, Paul Walmsley, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Troy Mitchell <troy.mitchell@linux.dev>
[ Upstream commit 572b25f3a6453d8e7fc28cc0cefe41ed15be166c ]
The standard vector save/restore asm advances datap but declares it as
input-only. An inlined caller reusing the original pointer may therefore
use the advanced address instead.
Declare datap as read-write so the compiler can preserve the original
pointer when needed.
Fixes: 03c3fcd9941a ("riscv: Introduce struct/helpers to save/restore per-task Vector state")
Signed-off-by: Troy Mitchell <troy.mitchell@linux.dev>
Reviewed-by: GUO Ren (XuanTie) <guoren@kernel.org>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Andy Chiu <tchiu@tenstorrent.com>
Link: https://patch.msgid.link/20260908-riscv-vector-asm-fix-v1-1-147f314efb2b@linux.dev
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/riscv/include/asm/vector.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index 00cb9c0982b1a..e94f81cedda56 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -225,7 +225,7 @@ static inline void __riscv_v_vstate_save(struct __riscv_v_ext_state *save_to,
"add %1, %1, %0\n\t"
"vse8.v v24, (%1)\n\t"
".option pop\n\t"
- : "=&r" (vl) : "r" (datap) : "memory");
+ : "=&r" (vl), "+r" (datap) : : "memory");
}
riscv_v_disable();
}
@@ -261,7 +261,7 @@ static inline void __riscv_v_vstate_restore(struct __riscv_v_ext_state *restore_
"add %1, %1, %0\n\t"
"vle8.v v24, (%1)\n\t"
".option pop\n\t"
- : "=&r" (vl) : "r" (datap) : "memory");
+ : "=&r" (vl), "+r" (datap) : : "memory");
}
__vstate_csr_restore(restore_from);
riscv_v_disable();
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 225/281] riscv: vector: Fix output operands in context save
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (223 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 224/281] riscv: vector: Fix data pointer constraints in context save/restore Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 226/281] Revert "net: stmmac: propagate PTP addend and system time programming errors" Greg Kroah-Hartman
` (62 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aurelien Jarno, Paul Walmsley,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aurelien Jarno <aurelien@aurel32.net>
[ Upstream commit 55b1276ef9c1c27e8a2b2c5e8ef0515b5ad0332c ]
The __vstate_csr_save() inline assembly declares vcsr as an output
operand while the assembly only writes vstart, vtype, and vl. Remove it
as it is later saved by the C code.
Fixes: d863910eabaf ("riscv: vector: Support xtheadvector save/restore")
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Link: https://patch.msgid.link/20260911194218.3379486-1-aurelien@aurel32.net
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/riscv/include/asm/vector.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index e94f81cedda56..8d736e826d84d 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -132,8 +132,8 @@ static __always_inline void __vstate_csr_save(struct __riscv_v_ext_state *dest)
"csrr %0, " __stringify(CSR_VSTART) "\n\t"
"csrr %1, " __stringify(CSR_VTYPE) "\n\t"
"csrr %2, " __stringify(CSR_VL) "\n\t"
- : "=r" (dest->vstart), "=r" (dest->vtype), "=r" (dest->vl),
- "=r" (dest->vcsr) : :);
+ : "=r" (dest->vstart), "=r" (dest->vtype), "=r" (dest->vl)
+ : :);
if (has_xtheadvector()) {
unsigned long status;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 226/281] Revert "net: stmmac: propagate PTP addend and system time programming errors"
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (224 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 225/281] riscv: vector: Fix output operands in context save Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 227/281] scsi: ufs: mediatek: Handle mPHY power-on failures Greg Kroah-Hartman
` (61 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Anirudh Srinivasan, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit d5a007b9b457c915ab1a53227e8939e4018aa97a ]
This reverts commit 232d49dd4b40a666283de9e722899f088ed581b2.
Anirudh reports a regression from this change.
It is not appropriate for net this late in the release cycle
in the first place, so let's revert and revisit in net-next.
Reported-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Link: https://lore.kernel.org/CAEev2e8+fr1tJnSErD+2TtLDw5fGJbQOMcM5eefMnLyFUR+m7w@mail.gmail.com
Fixes: 232d49dd4b40 ("net: stmmac: propagate PTP addend and system time programming errors")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 106 +++++-------------
.../net/ethernet/stmicro/stmmac/stmmac_ptp.c | 10 +-
2 files changed, 32 insertions(+), 84 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 22c94fca01822..0da3da7d0d1b8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -601,64 +601,31 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
}
}
-static void stmmac_restore_subsecond_increment(struct stmmac_priv *priv,
- u32 default_addend)
+static void stmmac_update_subsecond_increment(struct stmmac_priv *priv)
{
bool xmac = dwmac_is_xmac(priv->plat->core_type);
u32 sec_inc = 0;
-
- stmmac_config_addend(priv, priv->ptpaddr, default_addend);
- stmmac_config_hw_tstamping(priv, priv->ptpaddr, priv->systime_flags);
- stmmac_config_sub_second_increment(priv, priv->ptpaddr,
- priv->plat->clk_ptp_rate,
- xmac, &sec_inc);
- priv->default_addend = default_addend;
- priv->sub_second_inc = sec_inc;
-}
-
-static int stmmac_update_subsecond_increment(struct stmmac_priv *priv,
- u32 systime_flags)
-{
- bool xmac = dwmac_is_xmac(priv->plat->core_type);
- u32 sec_inc = 0, val;
u64 temp = 0;
- int ret;
- stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags);
+ stmmac_config_hw_tstamping(priv, priv->ptpaddr, priv->systime_flags);
/* program Sub Second Increment reg */
stmmac_config_sub_second_increment(priv, priv->ptpaddr,
priv->plat->clk_ptp_rate,
xmac, &sec_inc);
- if (!sec_inc) {
- ret = -EINVAL;
- goto error;
- }
+ temp = div_u64(1000000000ULL, sec_inc);
+
+ /* Store sub second increment for later use */
+ priv->sub_second_inc = sec_inc;
/* calculate default added value:
* formula is :
* addend = (2^32)/freq_div_ratio;
* where, freq_div_ratio = 1e9ns/sec_inc
*/
- temp = div_u64(1000000000ULL, sec_inc);
temp = (u64)(temp << 32);
- val = div_u64(temp, priv->plat->clk_ptp_rate);
-
- ret = stmmac_config_addend(priv, priv->ptpaddr, val);
- if (ret)
- goto error;
-
- priv->sub_second_inc = sec_inc;
- priv->default_addend = val;
-
- return 0;
-error:
- /* Restore previous configuration */
- stmmac_config_hw_tstamping(priv, priv->ptpaddr, priv->systime_flags);
- stmmac_config_sub_second_increment(priv, priv->ptpaddr,
- priv->plat->clk_ptp_rate, xmac,
- NULL);
- return ret;
+ priv->default_addend = div_u64(temp, priv->plat->clk_ptp_rate);
+ stmmac_config_addend(priv, priv->ptpaddr, priv->default_addend);
}
/**
@@ -887,42 +854,35 @@ static int stmmac_hwtstamp_get(struct net_device *dev,
/**
* stmmac_init_tstamp_counter - init hardware timestamping counter
* @priv: driver private structure
+ * @systime_flags: timestamping flags
* Description:
* Initialize hardware counter for packet timestamping.
* This is valid as long as the interface is open and not suspended.
* Will be rerun after resuming from suspend, case in which the timestamping
* flags updated by stmmac_hwtstamp_set() also need to be restored.
*/
-static int stmmac_init_tstamp_counter(struct stmmac_priv *priv)
+static int stmmac_init_tstamp_counter(struct stmmac_priv *priv,
+ u32 systime_flags)
{
- u32 default_addend = priv->default_addend;
struct timespec64 now;
- int ret;
if (!priv->plat->clk_ptp_rate) {
netdev_err(priv->dev, "Invalid PTP clock rate");
return -EINVAL;
}
- ret = stmmac_update_subsecond_increment(priv, priv->systime_flags);
- if (ret)
- return ret;
+ stmmac_config_hw_tstamping(priv, priv->ptpaddr, systime_flags);
+ priv->systime_flags = systime_flags;
+
+ stmmac_update_subsecond_increment(priv);
/* initialize system time */
ktime_get_real_ts64(&now);
/* lower 32 bits of tv_sec are safe until y2106 */
- ret = stmmac_init_systime(priv, priv->ptpaddr, (u32)now.tv_sec,
- now.tv_nsec);
- if (ret)
- goto error;
+ stmmac_init_systime(priv, priv->ptpaddr, (u32)now.tv_sec, now.tv_nsec);
return 0;
-error:
- /* Restore previous configuration */
- stmmac_restore_subsecond_increment(priv, default_addend);
-
- return ret;
}
/**
@@ -945,14 +905,8 @@ static int stmmac_init_timestamping(struct stmmac_priv *priv)
return -EOPNOTSUPP;
}
- /* Reset hw ts configuration */
- memset(&priv->tstamp_config, 0, sizeof(priv->tstamp_config));
- priv->systime_flags = STMMAC_HWTS_ACTIVE | PTP_TCR_TSCFUPDT;
- priv->tsfupdt_coarse = false;
- priv->hwts_tx_en = 0;
- priv->hwts_rx_en = 0;
-
- ret = stmmac_init_tstamp_counter(priv);
+ ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE |
+ PTP_TCR_TSCFUPDT);
if (ret) {
netdev_warn(priv->dev, "PTP init failed\n");
return ret;
@@ -973,6 +927,10 @@ static int stmmac_init_timestamping(struct stmmac_priv *priv)
netdev_info(priv->dev,
"IEEE 1588-2008 Advanced Timestamp supported\n");
+ memset(&priv->tstamp_config, 0, sizeof(priv->tstamp_config));
+ priv->hwts_tx_en = 0;
+ priv->hwts_rx_en = 0;
+
if (priv->plat->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY)
stmmac_hwtstamp_correct_latency(priv, priv);
@@ -7767,26 +7725,18 @@ static int stmmac_dl_ts_coarse_set(struct devlink *dl, u32 id,
{
struct stmmac_devlink_priv *dl_priv = devlink_priv(dl);
struct stmmac_priv *priv = dl_priv->stmmac_priv;
- u32 systime_flags = priv->systime_flags;
- int ret;
- if (ctx->val.vbool)
- systime_flags &= ~PTP_TCR_TSCFUPDT;
+ priv->tsfupdt_coarse = ctx->val.vbool;
+
+ if (priv->tsfupdt_coarse)
+ priv->systime_flags &= ~PTP_TCR_TSCFUPDT;
else
- systime_flags |= PTP_TCR_TSCFUPDT;
+ priv->systime_flags |= PTP_TCR_TSCFUPDT;
/* In Coarse mode, we can use a smaller subsecond increment, let's
* reconfigure the systime, subsecond increment and addend.
*/
- ret = stmmac_update_subsecond_increment(priv, systime_flags);
- if (ret) {
- NL_SET_ERR_MSG_MOD(extack,
- "failed to reconfigure PTP adjustment");
- return ret;
- }
-
- priv->tsfupdt_coarse = ctx->val.vbool;
- priv->systime_flags = systime_flags;
+ stmmac_update_subsecond_increment(priv);
return 0;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 493c5d81a36bf..3bfcc9760dce7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -28,15 +28,14 @@ static int stmmac_adjust_freq(struct ptp_clock_info *ptp, long scaled_ppm)
container_of(ptp, struct stmmac_priv, ptp_clock_ops);
unsigned long flags;
u32 addend;
- int ret;
addend = adjust_by_scaled_ppm(priv->default_addend, scaled_ppm);
write_lock_irqsave(&priv->ptp_lock, flags);
- ret = stmmac_config_addend(priv, priv->ptpaddr, addend);
+ stmmac_config_addend(priv, priv->ptpaddr, addend);
write_unlock_irqrestore(&priv->ptp_lock, flags);
- return ret;
+ return 0;
}
/**
@@ -154,13 +153,12 @@ static int stmmac_set_time(struct ptp_clock_info *ptp,
struct stmmac_priv *priv =
container_of(ptp, struct stmmac_priv, ptp_clock_ops);
unsigned long flags;
- int ret;
write_lock_irqsave(&priv->ptp_lock, flags);
- ret = stmmac_init_systime(priv, priv->ptpaddr, ts->tv_sec, ts->tv_nsec);
+ stmmac_init_systime(priv, priv->ptpaddr, ts->tv_sec, ts->tv_nsec);
write_unlock_irqrestore(&priv->ptp_lock, flags);
- return ret;
+ return 0;
}
static int stmmac_enable(struct ptp_clock_info *ptp,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 227/281] scsi: ufs: mediatek: Handle mPHY power-on failures
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (225 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 226/281] Revert "net: stmmac: propagate PTP addend and system time programming errors" Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 228/281] wifi: mt76: mt7996: take over connection monitoring Greg Kroah-Hartman
` (60 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, Peter Wang,
Stanley Jhu, Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <hppiscas@163.com>
[ Upstream commit 78e04810542da416d3bead707b60cec773f1524d ]
The MediaTek helper enables VA09 before powering on the mPHY, but ignores
the PHY result. A failure can leave VA09 enabled and publish
mphy_powered_on as true, so a later power-on attempt is skipped.
Check phy_power_on(), attempt to unwind VA09 on failure, and leave the
state flag unchanged. Propagate the helper result from host initialization
as well as its existing resume caller. Keep the original PHY error if the
supply rollback also fails, and report that rollback separately.
The issue was found by our static-analysis tool.
Fixes: 561e3a8726b2 ("scsi: ufs-mediatek: Fix unbalanced clock on/off")
Fixes: cf137b3ea49a ("scsi: ufs-mediatek: Support VA09 regulator operations")
Assisted-by: gpt 5
Signed-off-by: Pengpeng Hou <hppiscas@163.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: Stanley Jhu <stanleyjhu@google.com>
Link: https://patch.msgid.link/20260920034953.19535-1-hppiscas@163.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ufs/host/ufs-mediatek.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c
index 3991a51263a6d..a2defbe3b7483 100644
--- a/drivers/ufs/host/ufs-mediatek.c
+++ b/drivers/ufs/host/ufs-mediatek.c
@@ -509,6 +509,7 @@ static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
struct phy *mphy = host->mphy;
struct arm_smccc_res res;
+ int err;
int ret = 0;
if (!mphy || !(on ^ host->mphy_powered_on))
@@ -523,7 +524,18 @@ static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on)
usleep_range(200, 210);
ufs_mtk_va09_pwr_ctrl(res, 1);
}
- phy_power_on(mphy);
+ ret = phy_power_on(mphy);
+ if (ret) {
+ if (ufs_mtk_is_va09_supported(hba)) {
+ ufs_mtk_va09_pwr_ctrl(res, 0);
+ err = regulator_disable(host->reg_va09);
+ if (err)
+ dev_err(hba->dev,
+ "failed to unwind va09: %d\n", err);
+ }
+ dev_err(hba->dev, "failed to enable mphy: %d\n", ret);
+ return ret;
+ }
} else {
phy_power_off(mphy);
if (ufs_mtk_is_va09_supported(hba)) {
@@ -1295,7 +1307,9 @@ static int ufs_mtk_init(struct ufs_hba *hba)
*
* Enable phy clocks specifically here.
*/
- ufs_mtk_mphy_power_on(hba, true);
+ err = ufs_mtk_mphy_power_on(hba, true);
+ if (err)
+ goto out_variant_clear;
if (ufs_mtk_is_rtff_mtcmos(hba)) {
/* First Restore here, to avoid backup unexpected value */
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 228/281] wifi: mt76: mt7996: take over connection monitoring
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (226 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 227/281] scsi: ufs: mediatek: Handle mPHY power-on failures Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 229/281] wifi: mac80211: add AQL support for multicast packets Greg Kroah-Hartman
` (59 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Felix Fietkau, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 0ec14f8c8c5da1c9c314bce4f0bf53c009fbc998 ]
mt76 runs its own beacon monitor. mt76_beacon_mon_check() counts a miss
for each affiliated link of an MLD, and it stops the count while the phy
is off channel. mt7996 supplies it through mt76_rx_beacon(), but it does
not set CONNECTION_MONITOR. Therefore mac80211 also starts its legacy
monitor.
The legacy monitor knows one interface, not a set of links. It also
counts while the radio serves a different link. After seven beacon
intervals it removes an association that still carries traffic on the
other links.
Set the CONNECTION_MONITOR flag to disable the legacy monitor.
Fixes: 4df75606ece5 ("wifi: mt76: add per-link beacon monitoring for MLO")
Link: https://patch.msgid.link/20260818125825.395538-3-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/init.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
index be6e105f5f063..95fb30404b857 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c
@@ -536,6 +536,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed)
ieee80211_hw_set(hw, NO_VIRTUAL_MONITOR);
ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
ieee80211_hw_set(hw, CHANCTX_STA_CSA);
+ ieee80211_hw_set(hw, CONNECTION_MONITOR);
hw->max_tx_fragments = 4;
wiphy->txq_memory_limit = 32 << 20; /* 32 MiB */
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 229/281] wifi: mac80211: add AQL support for multicast packets
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (227 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 228/281] wifi: mt76: mt7996: take over connection monitoring Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 230/281] wifi: mac80211: add ieee80211_txq_aql_pending() Greg Kroah-Hartman
` (58 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Fietkau, Johannes Berg,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 836c1addd3bf42d47ca5f7a5780a7ec52abf332e ]
Excessive multicast traffic with little competing unicast traffic can easily
flood hardware queues, leading to throughput issues. Additionally, filling
the hardware queues with too many packets breaks FQ for multicast data.
Fix this by enabling AQL for multicast packets.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/20260724115429.3921457-3-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: 752770d7a58c ("wifi: mt76: account non-AQL frames per peer rather than per link")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/cfg80211.h | 1 +
include/net/mac80211.h | 3 ++-
net/mac80211/debugfs.c | 13 ++++++++--
net/mac80211/ieee80211_i.h | 2 ++
net/mac80211/main.c | 1 +
net/mac80211/sta_info.c | 17 ++++++++++++-
net/mac80211/sta_info.h | 3 ++-
net/mac80211/status.c | 5 ++--
net/mac80211/tx.c | 52 ++++++++++++++++++++------------------
9 files changed, 66 insertions(+), 31 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f5abf1db7558b..7354ba079363a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3722,6 +3722,7 @@ enum wiphy_params_flags {
/* The per TXQ device queue limit in airtime */
#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L 5000
#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H 12000
+#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_MC 50000
/* The per interface airtime threshold to switch to lower queue limit */
#define IEEE80211_AQL_THRESHOLD 24000
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 36055d40172a1..8007d3e5a8483 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1317,6 +1317,7 @@ ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate)
* @status_data: internal data for TX status handling, assigned privately,
* see also &enum ieee80211_status_data for the internal documentation
* @status_data_idr: indicates status data is IDR allocated ID for ack frame
+ * @tx_time_mc: TX time estimate is for a multicast frame, used internally
* @tx_time_est: TX time estimate in units of 4us, used internally
* @control: union part for control data
* @control.rates: TX rates array to try
@@ -1354,8 +1355,8 @@ struct ieee80211_tx_info {
status_data_idr:1,
status_data:13,
hw_queue:4,
+ tx_time_mc:1,
tx_time_est:10;
- /* 1 free bit */
union {
struct {
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index f36cc25903050..3a671225c1277 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -210,11 +210,13 @@ static ssize_t aql_pending_read(struct file *file,
"VI %u us\n"
"BE %u us\n"
"BK %u us\n"
+ "MC %u us\n"
"total %u us\n",
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VO]),
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VI]),
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BE]),
atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BK]),
+ atomic_read(&local->aql_mc_pending_airtime),
atomic_read(&local->aql_total_pending_airtime));
return simple_read_from_buffer(user_buf, count, ppos,
buf, len);
@@ -239,7 +241,8 @@ static ssize_t aql_txq_limit_read(struct file *file,
"VO %u %u\n"
"VI %u %u\n"
"BE %u %u\n"
- "BK %u %u\n",
+ "BK %u %u\n"
+ "MC %u\n",
local->aql_txq_limit_low[IEEE80211_AC_VO],
local->aql_txq_limit_high[IEEE80211_AC_VO],
local->aql_txq_limit_low[IEEE80211_AC_VI],
@@ -247,7 +250,8 @@ static ssize_t aql_txq_limit_read(struct file *file,
local->aql_txq_limit_low[IEEE80211_AC_BE],
local->aql_txq_limit_high[IEEE80211_AC_BE],
local->aql_txq_limit_low[IEEE80211_AC_BK],
- local->aql_txq_limit_high[IEEE80211_AC_BK]);
+ local->aql_txq_limit_high[IEEE80211_AC_BK],
+ local->aql_txq_limit_mc);
return simple_read_from_buffer(user_buf, count, ppos,
buf, len);
}
@@ -273,6 +277,11 @@ static ssize_t aql_txq_limit_write(struct file *file,
else
buf[count] = '\0';
+ if (sscanf(buf, "mcast %u", &q_limit_low) == 1) {
+ local->aql_txq_limit_mc = q_limit_low;
+ return count;
+ }
+
if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
return -EINVAL;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 011ec7fbb7118..2854dcc86b21b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1464,10 +1464,12 @@ struct ieee80211_local {
spinlock_t handle_wake_tx_queue_lock;
u16 airtime_flags;
+ u32 aql_txq_limit_mc;
u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
u32 aql_threshold;
atomic_t aql_total_pending_airtime;
+ atomic_t aql_mc_pending_airtime;
atomic_t aql_ac_pending_airtime[IEEE80211_NUM_ACS];
const struct ieee80211_ops *ops;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 8edfef2b57f80..d5ef44f2b3f2d 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -988,6 +988,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
spin_lock_init(&local->rx_path_lock);
spin_lock_init(&local->queue_stop_reason_lock);
+ local->aql_txq_limit_mc = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_MC;
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
INIT_LIST_HEAD(&local->active_txqs[i]);
spin_lock_init(&local->active_txq_lock[i]);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 01d70f71c43ec..ce7a3f839ce2e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -2493,13 +2493,28 @@ EXPORT_SYMBOL(ieee80211_sta_recalc_aggregates);
void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
struct sta_info *sta, u8 ac,
- u16 tx_airtime, bool tx_completed)
+ u16 tx_airtime, bool tx_completed,
+ bool mcast)
{
int tx_pending;
if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
return;
+ if (mcast) {
+ if (!tx_completed) {
+ atomic_add(tx_airtime, &local->aql_mc_pending_airtime);
+ return;
+ }
+
+ tx_pending = atomic_sub_return(tx_airtime,
+ &local->aql_mc_pending_airtime);
+ if (tx_pending < 0)
+ atomic_cmpxchg(&local->aql_mc_pending_airtime,
+ tx_pending, 0);
+ return;
+ }
+
if (!tx_completed) {
if (sta)
atomic_add(tx_airtime,
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 5da3142d8516e..ee0d32877c5b4 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -147,7 +147,8 @@ struct airtime_info {
void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
struct sta_info *sta, u8 ac,
- u16 tx_airtime, bool tx_completed);
+ u16 tx_airtime, bool tx_completed,
+ bool mcast);
struct sta_info;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index e10e5bcc279b6..a9da9fe87cf15 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -774,7 +774,7 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
ieee80211_sta_update_pending_airtime(local, sta,
skb_get_queue_mapping(skb),
tx_time_est,
- true);
+ true, info->tx_time_mc);
rcu_read_unlock();
}
@@ -1255,10 +1255,11 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
/* Do this here to avoid the expensive lookup of the sta
* in ieee80211_report_used_skb().
*/
+ bool mcast = IEEE80211_SKB_CB(skb)->tx_time_mc;
ieee80211_sta_update_pending_airtime(local, sta,
skb_get_queue_mapping(skb),
tx_time_est,
- true);
+ true, mcast);
ieee80211_info_set_tx_time_est(IEEE80211_SKB_CB(skb), 0);
}
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 65c5a6519b895..546646aabb41c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4083,20 +4083,20 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
encap_out:
info->control.vif = vif;
- if (tx.sta &&
- wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
- bool ampdu = txq->ac != IEEE80211_AC_VO;
+ if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
+ bool ampdu = txq->sta && txq->ac != IEEE80211_AC_VO;
u32 airtime;
airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
skb->len, ampdu);
- if (airtime) {
- airtime = ieee80211_info_set_tx_time_est(info, airtime);
- ieee80211_sta_update_pending_airtime(local, tx.sta,
- txq->ac,
- airtime,
- false);
- }
+ if (!airtime)
+ return skb;
+
+ airtime = ieee80211_info_set_tx_time_est(info, airtime);
+ info->tx_time_mc = !tx.sta;
+ ieee80211_sta_update_pending_airtime(local, tx.sta, txq->ac,
+ airtime, false,
+ info->tx_time_mc);
}
return skb;
@@ -4148,6 +4148,7 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
struct ieee80211_txq *ret = NULL;
struct txq_info *txqi = NULL, *head = NULL;
bool found_eligible_txq = false;
+ bool aql_check;
spin_lock_bh(&local->active_txq_lock[ac]);
@@ -4171,26 +4172,28 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
if (!head)
head = txqi;
+ aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
+ if (aql_check)
+ found_eligible_txq = true;
+
if (txqi->txq.sta) {
struct sta_info *sta = container_of(txqi->txq.sta,
struct sta_info, sta);
- bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
- s32 deficit = ieee80211_sta_deficit(sta, txqi->txq.ac);
- if (aql_check)
- found_eligible_txq = true;
-
- if (deficit < 0)
+ if (ieee80211_sta_deficit(sta, txqi->txq.ac) < 0) {
sta->airtime[txqi->txq.ac].deficit +=
sta->airtime_weight;
- if (deficit < 0 || !aql_check) {
- list_move_tail(&txqi->schedule_order,
- &local->active_txqs[txqi->txq.ac]);
- goto begin;
+ aql_check = false;
}
}
+ if (!aql_check) {
+ list_move_tail(&txqi->schedule_order,
+ &local->active_txqs[txqi->txq.ac]);
+ goto begin;
+ }
+
if (txqi->schedule_round == local->schedule_round[ac])
goto out;
@@ -4257,7 +4260,8 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
return true;
if (!txq->sta)
- return true;
+ return atomic_read(&local->aql_mc_pending_airtime) <
+ local->aql_txq_limit_mc;
if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
return true;
@@ -4306,15 +4310,15 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
spin_lock_bh(&local->active_txq_lock[ac]);
- if (!txqi->txq.sta)
- goto out;
-
if (list_empty(&txqi->schedule_order))
goto out;
if (!ieee80211_txq_schedule_airtime_check(local, ac))
goto out;
+ if (!txqi->txq.sta)
+ goto out;
+
list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
schedule_order) {
if (iter == txqi)
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 230/281] wifi: mac80211: add ieee80211_txq_aql_pending()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (228 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 229/281] wifi: mac80211: add AQL support for multicast packets Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 231/281] wifi: mt76: add PS buffering support for HW-managed TIM drivers Greg Kroah-Hartman
` (57 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Fietkau, Johannes Berg,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 9a197e71eb7b45860e37a9f3bdf61a843781ae12 ]
Add a function to allow drivers to query the pending AQL airtime
for a given txq, for both unicast and broadcast.
This will be used for mt76 to limit buffering in AP mode for power-save
stations.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/20260724115429.3921457-4-nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: 752770d7a58c ("wifi: mt76: account non-AQL frames per peer rather than per link")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/mac80211.h | 11 +++++++++++
net/mac80211/tx.c | 18 ++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 8007d3e5a8483..7b610dfee2867 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -6877,6 +6877,17 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
bool
ieee80211_txq_airtime_check(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
+/**
+ * ieee80211_txq_aql_pending - get pending AQL airtime for a txq
+ *
+ * @hw: pointer obtained from ieee80211_alloc_hw()
+ * @txq: pointer obtained from station or virtual interface
+ *
+ * Return: pending airtime (in usec) for the given txq.
+ */
+u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq);
+
/**
* ieee80211_iter_keys - iterate keys programmed into the device
* @hw: pointer obtained from ieee80211_alloc_hw()
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 546646aabb41c..3e5b1c05f4a3e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4281,6 +4281,24 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
}
EXPORT_SYMBOL(ieee80211_txq_airtime_check);
+u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct sta_info *sta;
+
+ if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
+ return 0;
+
+ if (!txq->sta)
+ return atomic_read(&local->aql_mc_pending_airtime);
+
+ sta = container_of(txq->sta, struct sta_info, sta);
+
+ return atomic_read(&sta->airtime[txq->ac].aql_tx_pending);
+}
+EXPORT_SYMBOL(ieee80211_txq_aql_pending);
+
static bool
ieee80211_txq_schedule_airtime_check(struct ieee80211_local *local, u8 ac)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 231/281] wifi: mt76: add PS buffering support for HW-managed TIM drivers
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (229 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 230/281] wifi: mac80211: add ieee80211_txq_aql_pending() Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 232/281] wifi: mt76: account non-AQL frames per peer rather than per link Greg Kroah-Hartman
` (56 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Felix Fietkau, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit a547b414bf7ea9877456b5630573293cc0e2cae7 ]
Add MT_DRV_HW_PS_BUFFERING flag for drivers where firmware controls
the TIM bit based on buffered frames. Instead of blocking all TX to
PS stations (which starves firmware and prevents TIM from being set),
allow limited frame delivery using AQL pending airtime as the
throttle. Replenish the firmware buffer on TX completion.
Add mt76_sta_ps_transition() helper for drivers to call from MCU
PS sync events.
Link: https://patch.msgid.link/20260801145334.1166751-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Stable-dep-of: 752770d7a58c ("wifi: mt76: account non-AQL frames per peer rather than per link")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 3 +
.../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 +
drivers/net/wireless/mediatek/mt76/tx.c | 77 +++++++++++++++++--
3 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 476578e2fbf0c..61ef1b80feb85 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -539,6 +539,7 @@ struct mt76_hw_cap {
#define MT_DRV_HW_MGMT_TXQ BIT(4)
#define MT_DRV_AMSDU_OFFLOAD BIT(5)
#define MT_DRV_IGNORE_TXS_FAILED BIT(6)
+#define MT_DRV_HW_PS_BUFFERING BIT(7)
struct mt76_driver_ops {
u32 drv_flags;
@@ -1541,6 +1542,8 @@ void mt76_release_buffered_frames(struct ieee80211_hw *hw,
u16 tids, int nframes,
enum ieee80211_frame_release_type reason,
bool more_data);
+void mt76_sta_ps_transition(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ bool ps);
bool mt76_has_tx_pending(struct mt76_phy *phy);
int mt76_update_channel(struct mt76_phy *phy);
void mt76_update_survey(struct mt76_phy *phy);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index a9a4a87ae0a76..fe03bc70e63a4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -1068,6 +1068,7 @@ enum {
MCU_UNI_EVENT_IE_COUNTDOWN = 0x09,
MCU_UNI_EVENT_COREDUMP = 0x0a,
MCU_UNI_EVENT_BSS_BEACON_LOSS = 0x0c,
+ MCU_UNI_EVENT_PS_SYNC = 0x0d,
MCU_UNI_EVENT_SCAN_DONE = 0x0e,
MCU_UNI_EVENT_RDD_REPORT = 0x11,
MCU_UNI_EVENT_ROC = 0x27,
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index b03be0eb47128..12c615b1294b4 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -267,6 +267,21 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *
wcid = __mt76_wcid_ptr(dev, wcid_idx);
mt76_tx_check_non_aql(dev, wcid, skb);
+ if (wcid && (dev->drv->drv_flags & MT_DRV_HW_PS_BUFFERING) &&
+ test_bit(MT_WCID_FLAG_PS, &wcid->flags)) {
+ struct ieee80211_sta *sta = wcid_to_sta(wcid);
+
+ if (sta) {
+ struct ieee80211_hw *hw = mt76_phy_hw(dev, wcid->phy_idx);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
+ if (sta->txq[i])
+ ieee80211_schedule_txq(hw, sta->txq[i]);
+ mt76_worker_schedule(&dev->tx_worker);
+ }
+ }
+
#ifdef CONFIG_NL80211_TESTMODE
if (mt76_is_testmode_skb(dev, skb, &hw)) {
struct mt76_phy *phy = hw->priv;
@@ -476,8 +491,12 @@ mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_queue *q,
bool stop = false;
int idx;
- if (test_bit(MT_WCID_FLAG_PS, &wcid->flags))
- return 0;
+ if (test_bit(MT_WCID_FLAG_PS, &wcid->flags)) {
+ if (!(dev->drv->drv_flags & MT_DRV_HW_PS_BUFFERING))
+ return 0;
+ if (ieee80211_txq_aql_pending(phy->hw, txq))
+ return 0;
+ }
if (atomic_read(&wcid->non_aql_packets) >= MT_MAX_NON_AQL_PKT)
return 0;
@@ -497,6 +516,9 @@ mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_queue *q,
if (idx < 0)
return idx;
+ if (test_bit(MT_WCID_FLAG_PS, &wcid->flags))
+ goto out;
+
do {
if (test_bit(MT76_RESET, &phy->state) || phy->offchannel)
break;
@@ -522,6 +544,7 @@ mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_queue *q,
n_frames++;
} while (1);
+out:
spin_lock(&q->lock);
dev->queue_ops->kick(dev, q);
spin_unlock(&q->lock);
@@ -548,10 +571,7 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)
mtxq = (struct mt76_txq *)txq->drv_priv;
wcid = __mt76_wcid_ptr(dev, mtxq->wcid);
- if (!wcid || test_bit(MT_WCID_FLAG_PS, &wcid->flags))
- continue;
-
- if (atomic_read(&wcid->non_aql_packets) >= MT_MAX_NON_AQL_PKT)
+ if (!wcid)
continue;
phy = mt76_dev_phy(dev, wcid->phy_idx);
@@ -559,6 +579,24 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)
continue;
q = phy->q_tx[qid];
+
+ if (test_bit(MT_WCID_FLAG_PS, &wcid->flags)) {
+ if (!(dev->drv->drv_flags & MT_DRV_HW_PS_BUFFERING))
+ continue;
+
+ if (!mt76_txq_stopped(q))
+ n_frames = mt76_txq_send_burst(phy, q, mtxq, wcid);
+
+ ieee80211_return_txq(phy->hw, txq, false);
+
+ if (unlikely(n_frames < 0))
+ return n_frames;
+ ret += n_frames;
+ continue;
+ }
+
+ if (atomic_read(&wcid->non_aql_packets) >= MT_MAX_NON_AQL_PKT)
+ continue;
if (dev->queue_ops->tx_cleanup &&
q->queued + 2 * MT_TXQ_FREE_THR >= q->ndesc) {
dev->queue_ops->tx_cleanup(dev, q, false);
@@ -765,6 +803,33 @@ void mt76_stop_tx_queues(struct mt76_phy *phy, struct ieee80211_sta *sta,
}
EXPORT_SYMBOL_GPL(mt76_stop_tx_queues);
+void mt76_sta_ps_transition(struct mt76_dev *dev, struct mt76_wcid *wcid,
+ bool ps)
+{
+ struct ieee80211_sta *sta;
+ struct ieee80211_hw *hw;
+ int i;
+
+ if (ps) {
+ set_bit(MT_WCID_FLAG_PS, &wcid->flags);
+ mt76_worker_schedule(&dev->tx_worker);
+ return;
+ }
+
+ clear_bit(MT_WCID_FLAG_PS, &wcid->flags);
+
+ sta = wcid_to_sta(wcid);
+ if (!sta)
+ return;
+
+ hw = mt76_phy_hw(dev, wcid->phy_idx);
+ for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
+ if (sta->txq[i])
+ ieee80211_schedule_txq(hw, sta->txq[i]);
+ mt76_worker_schedule(&dev->tx_worker);
+}
+EXPORT_SYMBOL_GPL(mt76_sta_ps_transition);
+
void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
{
struct mt76_phy *phy = hw->priv;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 232/281] wifi: mt76: account non-AQL frames per peer rather than per link
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (230 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 231/281] wifi: mt76: add PS buffering support for HW-managed TIM drivers Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 233/281] wifi: mt76: use ALTX queue for packets to disassociated stations Greg Kroah-Hartman
` (55 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Felix Fietkau, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 752770d7a58c821c17909c3ca67f9f14ab146a40 ]
The driver increments wcid->non_aql_packets when a frame goes to the
hardware queue. The completion path decrements the counter again.
For an MLO peer, the hardware reports the completion on the link that it
used for the transmission. This link can differ from the link that the
driver queued the frame on. In that case, the increment and the
decrement go to different link wcids, and the count drifts upwards until
it blocks the station.
Keep the count on the wcid of the primary link, like the other peer-wide
state.
Fixes: 86c051f2c418 ("wifi: mt76: mt7925: enabling MLO when the firmware supports it")
Link: https://patch.msgid.link/20260818125825.395538-5-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 7 +++++++
drivers/net/wireless/mediatek/mt76/tx.c | 11 ++++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 61ef1b80feb85..9188a27e78652 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -1425,6 +1425,13 @@ mtxq_to_txq(struct mt76_txq *mtxq)
return container_of(ptr, struct ieee80211_txq, drv_priv);
}
+/* peer-wide state uses the wcid of the primary link */
+static inline struct mt76_wcid *
+mt76_wcid_primary(struct mt76_wcid *wcid)
+{
+ return wcid->def_wcid ? wcid->def_wcid : wcid;
+}
+
static inline struct ieee80211_sta *
wcid_to_sta(struct mt76_wcid *wcid)
{
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 12c615b1294b4..c6245b10abb0c 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -234,6 +234,8 @@ mt76_tx_check_non_aql(struct mt76_dev *dev, struct mt76_wcid *wcid,
if (!wcid || info->tx_time_est)
return;
+ wcid = mt76_wcid_primary(wcid);
+
pending = atomic_dec_return(&wcid->non_aql_packets);
if (pending < 0)
atomic_cmpxchg(&wcid->non_aql_packets, pending, 0);
@@ -344,7 +346,8 @@ __mt76_tx_queue_skb(struct mt76_phy *phy, int qid, struct sk_buff *skb,
if (!non_aql)
return idx;
- pending = atomic_inc_return(&wcid->non_aql_packets);
+ /* the hardware can report the completion on a different link */
+ pending = atomic_inc_return(&mt76_wcid_primary(wcid)->non_aql_packets);
if (stop && pending >= MT_MAX_NON_AQL_PKT)
*stop = true;
@@ -498,7 +501,8 @@ mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_queue *q,
return 0;
}
- if (atomic_read(&wcid->non_aql_packets) >= MT_MAX_NON_AQL_PKT)
+ if (atomic_read(&mt76_wcid_primary(wcid)->non_aql_packets) >=
+ MT_MAX_NON_AQL_PKT)
return 0;
skb = mt76_txq_dequeue(phy, mtxq);
@@ -595,7 +599,8 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)
continue;
}
- if (atomic_read(&wcid->non_aql_packets) >= MT_MAX_NON_AQL_PKT)
+ if (atomic_read(&mt76_wcid_primary(wcid)->non_aql_packets) >=
+ MT_MAX_NON_AQL_PKT)
continue;
if (dev->queue_ops->tx_cleanup &&
q->queued + 2 * MT_TXQ_FREE_THR >= q->ndesc) {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 233/281] wifi: mt76: use ALTX queue for packets to disassociated stations
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (231 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 232/281] wifi: mt76: account non-AQL frames per peer rather than per link Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 234/281] wifi: mt76: mt7925: restore the legacy BSS after MLO teardown Greg Kroah-Hartman
` (54 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Felix Fietkau,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit 7c2e6b43c3082c2242ecfa5875b2b4b2cd06140f ]
Running these packets through regular buffering queues could cause them
to hang, especially when the packets were for stations that in disassoc
state.
Fixes: dedf2ec30fe4 ("wifi: mt76: fix queue assignment for deauth packets")
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260901092232.461379-1-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7915/main.c | 2 ++
drivers/net/wireless/mediatek/mt76/mt7996/main.c | 1 +
drivers/net/wireless/mediatek/mt76/tx.c | 3 ++-
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 4783e5f52d229..1830398ff719f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -805,6 +805,7 @@ __mt7915_drop_sta(void *ptr, u8 *mac, struct ieee80211_vif *vif)
msta = (struct mt7915_sta *)sta->drv_priv;
mt7915_mcu_add_sta(data->dev, vif, sta, CONN_STATE_DISCONNECT, false);
+ msta->wcid.tx_info &= ~MT_WCID_TX_INFO_SET;
msta->wcid.sta_disabled = 1;
msta->wcid.sta = 0;
}
@@ -871,6 +872,7 @@ int mt7915_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,
mutex_unlock(&dev->mt76.mutex);
mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, false);
+ msta->wcid.tx_info &= ~MT_WCID_TX_INFO_SET;
msta->wcid.sta_disabled = 1;
msta->wcid.sta = 0;
return 0;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 484fe880232b4..ae006f29091ff 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -1429,6 +1429,7 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif,
else if (sta->mlo && links == BIT(link_id)) /* last link */
mt7996_mcu_teardown_mld_sta(dev, link,
msta_link);
+ msta_link->wcid.tx_info &= ~MT_WCID_TX_INFO_SET;
msta_link->wcid.sta_disabled = 1;
msta_link->wcid.sta = 0;
links = links & ~BIT(link_id);
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index c6245b10abb0c..65703dbb185c9 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -672,7 +672,8 @@ mt76_txq_schedule_pending_wcid(struct mt76_phy *phy, struct mt76_wcid *wcid,
if ((dev->drv->drv_flags & MT_DRV_HW_MGMT_TXQ) &&
!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
!ieee80211_is_data_present(hdr->frame_control) &&
- (!ieee80211_is_bufferable_mmpdu(skb) ||
+ (!(wcid->tx_info & MT_WCID_TX_INFO_SET) ||
+ !ieee80211_is_bufferable_mmpdu(skb) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control) ||
head == &wcid->tx_offchannel))
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 234/281] wifi: mt76: mt7925: restore the legacy BSS after MLO teardown
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (232 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 233/281] wifi: mt76: use ALTX queue for packets to disassociated stations Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 235/281] wifi: mt76: mt7996: fix struct mt7996_mcu_wed_rro_ba_delete_event layout Greg Kroah-Hartman
` (53 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Aaron Ma, Felix Fietkau, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Ma <aaron.ma@canonical.com>
[ Upstream commit 8f9e5807671ee97cacf1957f4a09e43f4f1017a9 ]
Removing the last link of an MLD interface leaves the firmware with the
MLD BSS and DEV entry: the removal loop skips the deflink, and the
hweight16(mvif->valid_links) fallback reads the stale pre-update
valid_links, which is still non-zero. The entry keeps the per-link MAC
address, so every subsequent legacy association fails authentication
until the interface is removed or the module is reloaded.
Remove the deflink BSS and add it back as a legacy BSS on the transition
to zero links.
Fixes: 69acd6d910b0 ("wifi: mt76: mt7925: add mt7925_change_vif_links")
Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
Link: https://patch.msgid.link/20260826043658.2255553-1-aaron.ma@canonical.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7925/main.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index 9f080da13341b..e6e5c26307a11 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -2220,6 +2220,18 @@ mt7925_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mvif->valid_links = new_links;
+ /* Restore the legacy BSS after disabling MLO */
+ if (old_links && !new_links) {
+ mt792x_mac_link_bss_remove(dev, &mvif->bss_conf,
+ &mvif->sta.deflink);
+ err = mt7925_mac_link_bss_add(dev, &vif->bss_conf,
+ &mvif->sta.deflink);
+ if (err < 0) {
+ mt792x_mutex_release(dev);
+ return err;
+ }
+ }
+
mt792x_mutex_release(dev);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 235/281] wifi: mt76: mt7996: fix struct mt7996_mcu_wed_rro_ba_delete_event layout
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (233 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 234/281] wifi: mt76: mt7925: restore the legacy BSS after MLO teardown Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 236/281] wifi: mt76: mt7915: disable rx napi when removing device Greg Kroah-Hartman
` (52 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tao Gong, Felix Fietkau, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tao Gong <gongtao0607@gmail.com>
[ Upstream commit 9c9e4e4c8b45873e53774ab8207825b37b7565ec ]
Correct the definition of struct mt7996_mcu_wed_rro_ba_delete_event to
match the 12-byte event record layout observed from firmware.
The event TLV sent by firmware is 12 bytes in length rather than 8 bytes.
It contains an additional 4 bytes that appear to be wlan_id and tid.
For example, a captured batch deletion of sessions 8, 9, and 10 (TIDs 6,
0, and 1) shows:
00000000: 02 00 0c 00 08 00 01 00 06 00 00 00 02 00 0c 00
00000010: 09 00 01 00 00 00 00 00 02 00 0c 00 0a 00 01 00
00000020: 01 00 00 00
The previous 8-byte structure corrupts the parsing of subsequent TLVs,
leading to unhandled delete events and erroneous session deletions.
Consequently, clients that create and tear down BA sessions in batches
(such as Apple Wi-Fi clients) fail to properly clean up stale sessions,
causing HW_RRO to be lost upon subsequent reassociations.
Fixes: a5d028d66836 ("wifi: mt76: mt7996: add wed rro delete session garbage collector")
Signed-off-by: Tao Gong <gongtao0607@gmail.com>
Link: https://patch.msgid.link/20260823053739.186748-1-gongtao0607@gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7996/mcu.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
index c673e986ecb52..288b923750c0d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
@@ -284,6 +284,9 @@ struct mt7996_mcu_wed_rro_ba_delete_event {
__le16 len;
__le16 session_id;
+ __le16 wlan_id;
+ u8 tid;
+ u8 __rsv1;
u8 __rsv2[2];
} __packed;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 236/281] wifi: mt76: mt7915: disable rx napi when removing device
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (234 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 235/281] wifi: mt76: mt7996: fix struct mt7996_mcu_wed_rro_ba_delete_event layout Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 237/281] wifi: mt76: mt7925: dont put the band auto marker in TGID Greg Kroah-Hartman
` (51 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolas Cavallari, Felix Fietkau,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
[ Upstream commit 916c484d29d82f45c281da2786fcd6a1284430ce ]
Unloading the mt7915e module with a MT7916 triggers multiples WARN in
__netif_napi_del_locked() and in page_pool_disable_direct_recycling()
because the driver does not disable the napi before destroying it.
This is troublesome since on MT7916 it is required to unload the module
and reinsert it with a different enable_6ghz parameter to change the
frequency. The system generally becomes unstable after reinserting the
module.
Fix it by disabling rx napi inside mt7915e itself, even through napi rx is
enabled in the mt76 generic code. Disabling it in the mt76 generic code
was previously attempted and reverted because napi was disabled too
late and rx handlers could access freed structures. Note that the tx
side is enabled and disabled by the mt76 generic code.
It is disabled in mt7915_stop_hardware() since, unlike
mt7915_unregister_device(), is it also called in the probe path if an
error happens after rx napi is enabled.
Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Signed-off-by: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
Link: https://patch.msgid.link/20260810154923.32546-1-nicolas.cavallari@green-communications.fr
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7915/init.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 2ab38f9e52581..e768f4f72ed8e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -1208,6 +1208,12 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
static void mt7915_stop_hardware(struct mt7915_dev *dev)
{
+ int i;
+
+ mt76_for_each_q_rx(&dev->mt76, i) {
+ if (!mt76_queue_is_wed_rro(&dev->mt76.q_rx[i]))
+ napi_disable(&dev->mt76.napi[i]);
+ }
mt7915_mcu_exit(dev);
mt76_connac2_tx_token_put(&dev->mt76);
mt7915_dma_cleanup(dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 237/281] wifi: mt76: mt7925: dont put the band auto marker in TGID
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (235 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 236/281] wifi: mt76: mt7915: disable rx napi when removing device Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 238/281] wifi: mt76: mt792x: treat 0xff ACPI SAR entries as no limit Greg Kroah-Hartman
` (50 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Devin Wittmayer, Felix Fietkau,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devin Wittmayer <lucid_duck@justthetip.ca>
[ Upstream commit 5796b2bf9ff718342773ac760d86eb126c112a4f ]
band_idx starts out as 0xff, which tells the firmware to pick the band on
its own. A remain-on-channel grant normally writes a real index over it
before anything else looks. Two cases never see that: an MLD station
throws the grant away, and an AP has no association to trigger one.
The TX descriptor reads the same field into a two-bit slot, so the marker
comes out as 3. Every data frame from those two goes out tagged band 3.
Beacons are fine, they reach the firmware separately and never build a
descriptor.
Same numbers on an MT7925 and on a Netgear A9000:
stock patched
station, one link 0x00000001 0x00000001
station, two links 0x00003001 0x00000001
AP 0x00003013 0x00000013
real band index, STA 0x00001001 0x00001001
real band index, AP 0x00001013 0x00001013
Only the marker cases move.
Fixes: 0cb349d742d1 ("wifi: mt76: mt7925: update mt7925_mac_link_bss_add for MLO")
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260911024428.65244-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
index b52b678330604..8603915ddc2ef 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
@@ -781,7 +781,8 @@ mt7925_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
val = FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) |
FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx);
- if (band_idx)
+ /* 0xff means BAND_AUTO to the firmware, and TGID cannot encode it */
+ if (band_idx && band_idx != 0xff)
val |= FIELD_PREP(MT_TXD1_TGID, band_idx);
txwi[1] = cpu_to_le32(val);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 238/281] wifi: mt76: mt792x: treat 0xff ACPI SAR entries as no limit
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (236 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 237/281] wifi: mt76: mt7925: dont put the band auto marker in TGID Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 239/281] wifi: mt76: mt792x: pick the SAR table layout from the table itself Greg Kroah-Hartman
` (49 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Huy Nguyen Dinh Quang, Junjie Cao,
Cristian Fleischer, Felix Fietkau, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junjie Cao <junjie.cao@intel.com>
[ Upstream commit 45f53d98cbaa078907b6a300ff3974dfb5ae8776 ]
Some ASUS firmware carries 0xff in MTGS power slots. The driver narrows
the byte to s8, so the slot reads as -1 in its 0.5 dBm units, wins the
min() against the regulatory limit and caps every rate the driver
programs. On an ASUS Zenbook 14 UM3406HA (MT7922) all six MTGS tables
hold 0xff in every power byte, and txpower_sku shows tmac 3 on every
supported OFDM/HT/VHT/HE rate against EEPROM entries of 25-39, under
both the FR and the world regulatory domain. Huy Nguyen Dinh Quang saw
the same clamp on a Vivobook S 14 M5406WA, with 5 GHz TX at ~40 Mbps,
and proposed skipping the geo entry.
Skip a geo entry whose power byte is 0xff. The MTDS entry is narrowed
the same way on its way into the geo lookup, so give it the same
treatment, and clamp the dynamic value plus offset at 127 so a no-limit
entry cannot wrap.
Fixes: f965333e491e ("mt76: mt7921: introduce ACPI SAR support")
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2515420
Reported-by: Huy Nguyen Dinh Quang <huynguyendinhquang@gmail.com>
Closes: https://lore.kernel.org/linux-wireless/20260827134820.2607530-1-huynguyendinhquang@gmail.com/
Signed-off-by: Junjie Cao <junjie.cao@intel.com>
Tested-by: Cristian Fleischer <cristian.fleischer@gmail.com>
Link: https://patch.msgid.link/acb947435fc78d5c06039c7bd5609c735468b0ee.1789002236.git.junjie.cao@intel.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../wireless/mediatek/mt76/mt792x_acpi_sar.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c
index 946dd7956e4a0..9f0ea3d23e0f5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c
@@ -279,10 +279,18 @@ mt792x_asar_get_geo_pwr(struct mt792x_phy *phy,
if (idx >= max)
return dyn_power;
- geo_power = (band_pwr + idx)->pwr;
- dyn_power += (band_pwr + idx)->offset;
+ band_pwr += idx;
- return min(geo_power, dyn_power);
+ /* Some OEM tables carry 0xff here; narrowed to s8 that is -1 and
+ * wins the min() below. Take it as no limit.
+ */
+ if (band_pwr->pwr == 0xff)
+ return dyn_power;
+
+ geo_power = band_pwr->pwr;
+
+ return min_t(int, geo_power,
+ min_t(int, dyn_power + band_pwr->offset, 127));
}
static s8
@@ -315,7 +323,9 @@ mt792x_asar_range_pwr(struct mt792x_phy *phy,
else
band = NL80211_BAND_2GHZ;
- return mt792x_asar_get_geo_pwr(phy, band, limit[idx]);
+ /* 0xff: no dynamic limit, see mt792x_asar_get_geo_pwr() */
+ return mt792x_asar_get_geo_pwr(phy, band,
+ limit[idx] == 0xff ? 127 : limit[idx]);
}
int mt792x_init_acpi_sar_power(struct mt792x_phy *phy, bool set_default)
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 239/281] wifi: mt76: mt792x: pick the SAR table layout from the table itself
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (237 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 238/281] wifi: mt76: mt792x: treat 0xff ACPI SAR entries as no limit Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 240/281] drm/xe/sysctrl: Fix mailbox header handling Greg Kroah-Hartman
` (48 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sagun Kayastha, Devin Wittmayer,
Felix Fietkau, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devin Wittmayer <lucid_duck@justthetip.ca>
[ Upstream commit af97bf5a7e72da9026de184676df8e2fa57e1058 ]
The SAR power tables are parsed with a version byte from a different
ACPI table, never their own.
Some firmware declares version 1 and ships version 2 tables. The
entries then start a byte early, and the 6 GHz limits the table
carries are dropped, because the older layout has no room for them.
ASUS GA503RM, MTCL declares v1:
MTGS 28 bytes v1: (28-6) % 5 = 2, no fit v2: 3 tables
MTDS 19 bytes v1: (19-6) % 6 = 1, no fit v2: 1 table
The layouts accept disjoint lengths, so take whichever one fits and
keep it per table.
Reported-by: Sagun Kayastha <sgn.kayastha@gmail.com>
Closes: https://github.com/morrownr/mt76/issues/62
Fixes: f965333e491e ("mt76: mt7921: introduce ACPI SAR support")
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260905013551.24635-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../wireless/mediatek/mt76/mt792x_acpi_sar.c | 110 +++++++++++-------
.../wireless/mediatek/mt76/mt792x_acpi_sar.h | 2 +
2 files changed, 73 insertions(+), 39 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c
index 9f0ea3d23e0f5..ce5d5909d838d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.c
@@ -108,68 +108,98 @@ mt792x_asar_acpi_read_mtcl(struct mt792x_dev *dev, u8 **table, u8 *version)
return ret;
}
+/* A table's layout is decided by the version byte in MTCL, but some firmware
+ * labels a version 2 table as version 1. Accept whichever layout the table
+ * actually has: for every accepted entry count the two do not overlap, since
+ * one is 6 + 5n bytes and the other 7 + 7n.
+ */
+static bool
+mt792x_asar_fits(u8 *table, int len, int prelen, int sarlen, int nr_off,
+ int min, int max)
+{
+ int tblcnt;
+
+ if (len < prelen || (len - prelen) % sarlen)
+ return false;
+
+ tblcnt = (len - prelen) / sarlen;
+ if (tblcnt < min || tblcnt > max)
+ return false;
+
+ return tblcnt == table[nr_off];
+}
+
/* MTDS : Dynamic SAR Power Table */
static int
-mt792x_asar_acpi_read_mtds(struct mt792x_dev *dev, u8 **table, u8 version)
+mt792x_asar_acpi_read_mtds(struct mt792x_dev *dev, u8 **table, u8 version,
+ u8 *used)
{
- int len, ret, sarlen, prelen, tblcnt;
- bool enable;
+ int len, ret;
+ u8 *t;
ret = mt792x_acpi_read(dev, MT792x_ACPI_MTDS, table, &len);
if (ret)
return ret;
+ t = *table;
+
/* Table content validation */
- switch (version) {
- case 1:
- enable = ((struct mt792x_asar_dyn *)*table)->enable;
- sarlen = sizeof(struct mt792x_asar_dyn_limit);
- prelen = sizeof(struct mt792x_asar_dyn);
- break;
- case 2:
- enable = ((struct mt792x_asar_dyn_v2 *)*table)->enable;
- sarlen = sizeof(struct mt792x_asar_dyn_limit_v2);
- prelen = sizeof(struct mt792x_asar_dyn_v2);
- break;
- default:
+ if (mt792x_asar_fits(t, len, sizeof(struct mt792x_asar_dyn),
+ sizeof(struct mt792x_asar_dyn_limit),
+ offsetof(struct mt792x_asar_dyn, nr_tbl),
+ MT792x_ASAR_MIN_DYN, MT792x_ASAR_MAX_DYN))
+ *used = 1;
+ else if (mt792x_asar_fits(t, len, sizeof(struct mt792x_asar_dyn_v2),
+ sizeof(struct mt792x_asar_dyn_limit_v2),
+ offsetof(struct mt792x_asar_dyn_v2, nr_tbl),
+ MT792x_ASAR_MIN_DYN, MT792x_ASAR_MAX_DYN))
+ *used = 2;
+ else
return -EINVAL;
- }
- tblcnt = (len - prelen) / sarlen;
- if (!enable ||
- tblcnt > MT792x_ASAR_MAX_DYN || tblcnt < MT792x_ASAR_MIN_DYN)
+ if (!t[offsetof(struct mt792x_asar_dyn, enable)])
return -EINVAL;
+ if (version && *used != version)
+ dev_info(dev->mt76.dev,
+ "MTDS is v%u, MTCL says v%u; using v%u\n",
+ *used, version, *used);
+
return 0;
}
/* MTGS : Geo SAR Power Table */
static int
-mt792x_asar_acpi_read_mtgs(struct mt792x_dev *dev, u8 **table, u8 version)
+mt792x_asar_acpi_read_mtgs(struct mt792x_dev *dev, u8 **table, u8 version,
+ u8 *used)
{
- int len, ret, sarlen, prelen, tblcnt;
+ int len, ret;
+ u8 *t;
ret = mt792x_acpi_read(dev, MT792x_ACPI_MTGS, table, &len);
if (ret)
return ret;
+ t = *table;
+
/* Table content validation */
- switch (version) {
- case 1:
- sarlen = sizeof(struct mt792x_asar_geo_limit);
- prelen = sizeof(struct mt792x_asar_geo);
- break;
- case 2:
- sarlen = sizeof(struct mt792x_asar_geo_limit_v2);
- prelen = sizeof(struct mt792x_asar_geo_v2);
- break;
- default:
+ if (mt792x_asar_fits(t, len, sizeof(struct mt792x_asar_geo),
+ sizeof(struct mt792x_asar_geo_limit),
+ offsetof(struct mt792x_asar_geo, nr_tbl),
+ MT792x_ASAR_MIN_GEO, MT792x_ASAR_MAX_GEO))
+ *used = 1;
+ else if (mt792x_asar_fits(t, len, sizeof(struct mt792x_asar_geo_v2),
+ sizeof(struct mt792x_asar_geo_limit_v2),
+ offsetof(struct mt792x_asar_geo_v2, nr_tbl),
+ MT792x_ASAR_MIN_GEO, MT792x_ASAR_MAX_GEO))
+ *used = 2;
+ else
return -EINVAL;
- }
- tblcnt = (len - prelen) / sarlen;
- if (tblcnt > MT792x_ASAR_MAX_GEO || tblcnt < MT792x_ASAR_MIN_GEO)
- return -EINVAL;
+ if (version && *used != version)
+ dev_info(dev->mt76.dev,
+ "MTGS is v%u, MTCL says v%u; using v%u\n",
+ *used, version, *used);
return 0;
}
@@ -205,14 +235,16 @@ int mt792x_init_acpi_sar(struct mt792x_dev *dev)
asar->countrylist = NULL;
}
- ret = mt792x_asar_acpi_read_mtds(dev, (u8 **)&asar->dyn, asar->ver);
+ ret = mt792x_asar_acpi_read_mtds(dev, (u8 **)&asar->dyn, asar->ver,
+ &asar->dyn_ver);
if (ret) {
devm_kfree(dev->mt76.dev, asar->dyn);
asar->dyn = NULL;
}
/* MTGS is optional */
- ret = mt792x_asar_acpi_read_mtgs(dev, (u8 **)&asar->geo, asar->ver);
+ ret = mt792x_asar_acpi_read_mtgs(dev, (u8 **)&asar->geo, asar->ver,
+ &asar->geo_ver);
if (ret) {
devm_kfree(dev->mt76.dev, asar->geo);
asar->geo = NULL;
@@ -254,7 +286,7 @@ mt792x_asar_get_geo_pwr(struct mt792x_phy *phy,
break;
}
- if (asar->ver == 1) {
+ if (asar->geo_ver == 1) {
band_pwr = &asar->geo->tbl[idx].band[0];
max = ARRAY_SIZE(asar->geo->tbl[idx].band);
} else {
@@ -305,7 +337,7 @@ mt792x_asar_range_pwr(struct mt792x_phy *phy,
if (!capa)
return 127;
- if (asar->ver == 1) {
+ if (asar->dyn_ver == 1) {
limit = &asar->dyn->tbl[0].frp[0];
max = ARRAY_SIZE(asar->dyn->tbl[0].frp);
} else {
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h
index 4740330738315..1d42f24b05f66 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_acpi_sar.h
@@ -105,6 +105,8 @@ struct mt792x_asar_fg {
struct mt792x_acpi_sar {
u8 ver;
+ u8 dyn_ver;
+ u8 geo_ver;
union {
struct mt792x_asar_dyn *dyn;
struct mt792x_asar_dyn_v2 *dyn_v2;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 240/281] drm/xe/sysctrl: Fix mailbox header handling
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (238 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 239/281] wifi: mt76: mt792x: pick the SAR table layout from the table itself Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 241/281] Revert "wifi: ath12k: add panic handler" Greg Kroah-Hartman
` (47 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michal Wajdeczko, Mallesh Koujalagi,
Anoop Vijay, Umesh Nerlige Ramappa, Rodrigo Vivi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mallesh Koujalagi <mallesh.koujalagi@intel.com>
[ Upstream commit f0a4447789ef28ba1aded2db19543d69c640b5e5 ]
The mailbox header was defined as __le32, which required
cpu_to_le32() and le32_to_cpu() conversions whenever it was
write or read.
These conversions are unnecessary because the header is always
handled as a 32-bit value, not as raw bytes. It is written with
xe_mmio_write32() and read with xe_mmio_read32(), which already
handle any required byte-order conversion through the underlying
writel()/readl() accessors.
As a result, the header value is already in CPU byte order when
used by the driver. Keeping the extra conversions had no effect
on little-endian systems and could cause an incorrect on
big-endian systems.
So use u32 for the mailbox header and remove the unnecessary
endianness conversions.
Fixes: 1f95f618182b ("drm/xe/xe_sysctrl: Add System Controller mailbox communication support")
Suggested-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Signed-off-by: Mallesh Koujalagi <mallesh.koujalagi@intel.com>
Tested-by: Anoop Vijay <anoop.c.vijay@intel.com>
Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Signed-off-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
Link: https://patch.msgid.link/20260924060900.146167-18-mallesh.koujalagi@intel.com
(cherry picked from commit 5137b391599579371c32f555958d3cf55e19bd88)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/xe/xe_sysctrl_mailbox.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_sysctrl_mailbox.c b/drivers/gpu/drm/xe/xe_sysctrl_mailbox.c
index 72baf1aa4b3ad..a0179e62abaaf 100644
--- a/drivers/gpu/drm/xe/xe_sysctrl_mailbox.c
+++ b/drivers/gpu/drm/xe/xe_sysctrl_mailbox.c
@@ -19,20 +19,20 @@
#include "xe_sysctrl_mailbox_types.h"
struct xe_sysctrl_mailbox_msg_hdr {
- __le32 data;
-} __packed;
+ u32 data;
+};
#define XE_SYSCTRL_HDR_GROUP_ID(hdr) \
- FIELD_GET(SYSCTRL_HDR_GROUP_ID_MASK, le32_to_cpu((hdr)->data))
+ FIELD_GET(SYSCTRL_HDR_GROUP_ID_MASK, (hdr)->data)
#define XE_SYSCTRL_HDR_COMMAND(hdr) \
- FIELD_GET(SYSCTRL_HDR_COMMAND_MASK, le32_to_cpu((hdr)->data))
+ FIELD_GET(SYSCTRL_HDR_COMMAND_MASK, (hdr)->data)
#define XE_SYSCTRL_HDR_IS_RESPONSE(hdr) \
- FIELD_GET(SYSCTRL_HDR_IS_RESPONSE, le32_to_cpu((hdr)->data))
+ FIELD_GET(SYSCTRL_HDR_IS_RESPONSE, (hdr)->data)
#define XE_SYSCTRL_HDR_RESULT(hdr) \
- FIELD_GET(SYSCTRL_HDR_RESULT_MASK, le32_to_cpu((hdr)->data))
+ FIELD_GET(SYSCTRL_HDR_RESULT_MASK, (hdr)->data)
static bool sysctrl_wait_bit_clear(struct xe_sysctrl *sc, u32 bit_mask,
unsigned int timeout_ms)
@@ -126,8 +126,8 @@ static int sysctrl_prepare_command(struct xe_device *xe,
return -ENOMEM;
hdr = (struct xe_sysctrl_mailbox_msg_hdr *)buffer;
- hdr->data = cpu_to_le32(FIELD_PREP(SYSCTRL_HDR_GROUP_ID_MASK, group_id) |
- FIELD_PREP(SYSCTRL_HDR_COMMAND_MASK, command));
+ hdr->data = FIELD_PREP(SYSCTRL_HDR_GROUP_ID_MASK, group_id) |
+ FIELD_PREP(SYSCTRL_HDR_COMMAND_MASK, command);
if (data_in && data_in_len)
memcpy(buffer + sizeof(*hdr), data_in, data_in_len);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 241/281] Revert "wifi: ath12k: add panic handler"
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (239 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 240/281] drm/xe/sysctrl: Fix mailbox header handling Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 242/281] ASoC: adau1372: allow sleepy powerdown GPIOs Greg Kroah-Hartman
` (46 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yingying Tang, Joonhoe Kim,
Rameshkumar Sundaram, Jeff Johnson, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yingying Tang <yingying.tang@oss.qualcomm.com>
[ Upstream commit 05165f7b3b9ab6817fe216c24f90755b7c5e15f3 ]
ath12k_core_panic_handler() is invoked via atomic_notifier_call_chain(),
which runs inside an RCU read-side critical section. The current code calls
ath12k_pci_sw_reset() synchronously from this context, which eventually
reaches mhi_device_get_sync() and schedule_timeout(), triggering a voluntary
context switch within RCU.
Call trace:
rcu_note_context_switch+0x4c4/0x508 (P)
__schedule+0xbc/0x1204
schedule+0x34/0x110
schedule_timeout+0x84/0x11c
__mhi_device_get_sync+0x164/0x228 [mhi]
mhi_device_get_sync+0x1c/0x3c [mhi]
ath12k_wifi7_pci_bus_wake_up+0x20/0x2c [ath12k_wifi7]
ath12k_pci_read32+0x58/0x350 [ath12k]
ath12k_pci_clear_dbg_registers+0x28/0xb8 [ath12k]
ath12k_pci_panic_handler+0x20/0x44 [ath12k] ath12k_core_panic_handler+0x28/0x3c [ath12k]
notifier_call_chain+0x78/0x1c0
atomic_notifier_call_chain+0x3c/0x5c
Revert change "wifi: ath12k: add panic handler" to avoid this issue.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c7-00108-QCAHMTSWPL_V1.0_V2.0_SILICONZ_UPSTREAM-3
Signed-off-by: Yingying Tang <yingying.tang@oss.qualcomm.com>
Tested-by: Joonhoe Kim <26rote@gmail.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Fixes: 809055628bce ("wifi: ath12k: add panic handler")
Link: https://patch.msgid.link/20260612032332.2278338-1-yingying.tang@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/ath12k/core.c | 33 +-------------------------
drivers/net/wireless/ath/ath12k/core.h | 3 ---
drivers/net/wireless/ath/ath12k/hif.h | 9 -------
drivers/net/wireless/ath/ath12k/pci.c | 8 -------
4 files changed, 1 insertion(+), 52 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 5cdf4973d986a..992602965fb49 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -1770,29 +1770,6 @@ int ath12k_core_pre_init(struct ath12k_base *ab)
return 0;
}
-static int ath12k_core_panic_handler(struct notifier_block *nb,
- unsigned long action, void *data)
-{
- struct ath12k_base *ab = container_of(nb, struct ath12k_base,
- panic_nb);
-
- return ath12k_hif_panic_handler(ab);
-}
-
-static int ath12k_core_panic_notifier_register(struct ath12k_base *ab)
-{
- ab->panic_nb.notifier_call = ath12k_core_panic_handler;
-
- return atomic_notifier_chain_register(&panic_notifier_list,
- &ab->panic_nb);
-}
-
-static void ath12k_core_panic_notifier_unregister(struct ath12k_base *ab)
-{
- atomic_notifier_chain_unregister(&panic_notifier_list,
- &ab->panic_nb);
-}
-
static inline
bool ath12k_core_hw_group_create_ready(struct ath12k_hw_group *ag)
{
@@ -2208,18 +2185,13 @@ int ath12k_core_init(struct ath12k_base *ab)
struct ath12k_hw_group *ag;
int ret;
- ret = ath12k_core_panic_notifier_register(ab);
- if (ret)
- ath12k_warn(ab, "failed to register panic handler: %d\n", ret);
-
mutex_lock(&ath12k_hw_group_mutex);
ag = ath12k_core_hw_group_assign(ab);
if (!ag) {
mutex_unlock(&ath12k_hw_group_mutex);
ath12k_warn(ab, "unable to get hw group\n");
- ret = -ENODEV;
- goto err_unregister_notifier;
+ return -ENODEV;
}
mutex_unlock(&ath12k_hw_group_mutex);
@@ -2244,8 +2216,6 @@ int ath12k_core_init(struct ath12k_base *ab)
err_unassign_hw_group:
ath12k_core_hw_group_unassign(ab);
-err_unregister_notifier:
- ath12k_core_panic_notifier_unregister(ab);
return ret;
}
@@ -2254,7 +2224,6 @@ void ath12k_core_deinit(struct ath12k_base *ab)
{
ath12k_core_hw_group_destroy(ab->ag);
ath12k_core_hw_group_unassign(ab);
- ath12k_core_panic_notifier_unregister(ab);
}
void ath12k_core_free(struct ath12k_base *ab)
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index f28d2e90b67b2..708479df4b89e 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -15,7 +15,6 @@
#include <linux/ctype.h>
#include <linux/firmware.h>
#include <linux/of_reserved_mem.h>
-#include <linux/panic_notifier.h>
#include <linux/average.h>
#include <linux/of.h>
#include <linux/rhashtable.h>
@@ -1146,8 +1145,6 @@ struct ath12k_base {
#endif /* CONFIG_ACPI */
- struct notifier_block panic_nb;
-
struct ath12k_hw_group *ag;
struct ath12k_wsi_info wsi_info;
enum ath12k_firmware_mode fw_mode;
diff --git a/drivers/net/wireless/ath/ath12k/hif.h b/drivers/net/wireless/ath/ath12k/hif.h
index 4de8667690e91..aecdb0c5f2858 100644
--- a/drivers/net/wireless/ath/ath12k/hif.h
+++ b/drivers/net/wireless/ath/ath12k/hif.h
@@ -30,7 +30,6 @@ struct ath12k_hif_ops {
void (*ce_irq_enable)(struct ath12k_base *ab);
void (*ce_irq_disable)(struct ath12k_base *ab);
void (*get_ce_msi_idx)(struct ath12k_base *ab, u32 ce_id, u32 *msi_idx);
- int (*panic_handler)(struct ath12k_base *ab);
void (*coredump_download)(struct ath12k_base *ab);
};
@@ -149,14 +148,6 @@ static inline void ath12k_hif_power_down(struct ath12k_base *ab, bool is_suspend
ab->hif.ops->power_down(ab, is_suspend);
}
-static inline int ath12k_hif_panic_handler(struct ath12k_base *ab)
-{
- if (!ab->hif.ops->panic_handler)
- return NOTIFY_DONE;
-
- return ab->hif.ops->panic_handler(ab);
-}
-
static inline void ath12k_hif_coredump_download(struct ath12k_base *ab)
{
if (ab->hif.ops->coredump_download)
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index fee4129ea4055..a41544665080a 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -1473,13 +1473,6 @@ void ath12k_pci_power_down(struct ath12k_base *ab, bool is_suspend)
ath12k_pci_sw_reset(ab_pci->ab, false);
}
-static int ath12k_pci_panic_handler(struct ath12k_base *ab)
-{
- ath12k_pci_sw_reset(ab, false);
-
- return NOTIFY_OK;
-}
-
static const struct ath12k_hif_ops ath12k_pci_hif_ops = {
.start = ath12k_pci_start,
.stop = ath12k_pci_stop,
@@ -1497,7 +1490,6 @@ static const struct ath12k_hif_ops ath12k_pci_hif_ops = {
.ce_irq_enable = ath12k_pci_hif_ce_irq_enable,
.ce_irq_disable = ath12k_pci_hif_ce_irq_disable,
.get_ce_msi_idx = ath12k_pci_get_ce_msi_idx,
- .panic_handler = ath12k_pci_panic_handler,
#ifdef CONFIG_ATH12K_COREDUMP
.coredump_download = ath12k_pci_coredump_download,
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 242/281] ASoC: adau1372: allow sleepy powerdown GPIOs
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (240 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 241/281] Revert "wifi: ath12k: add panic handler" Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 243/281] ASoC: adau1372: fix invalid default state of output ASRC and DAC muxes Greg Kroah-Hartman
` (45 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alvin Šipraga, Nuno Sá,
Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alvin Šipraga <alvin.sipraga@analog.com>
[ Upstream commit 64dd172bbffe6135d79a06ddad53dd2da4d8bd62 ]
gpiod_set_value() emits a WARN when the GPIO provider indicates that it
can sleep, as is typical for I2C controlled GPIO expanders. Since the
powerdown GPIO is only manipulated in process context, use the _cansleep
variant instead. This lets the driver use sleepy GPIOs to power off the
chip.
Fixes: 6cd4c6459e47 ("ASoC: Add ADAU1372 audio CODEC support")
Signed-off-by: Alvin Šipraga <alvin.sipraga@analog.com>
Acked-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20261006-asoc-adau1372-fixes-v1-1-599cc17fb5f6@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/adau1372.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/sound/soc/codecs/adau1372.c b/sound/soc/codecs/adau1372.c
index cc174ec3a1f82..b84495371b0b4 100644
--- a/sound/soc/codecs/adau1372.c
+++ b/sound/soc/codecs/adau1372.c
@@ -798,7 +798,7 @@ static int adau1372_set_power(struct adau1372 *adau1372, bool enable)
if (ret)
return ret;
if (adau1372->pd_gpio)
- gpiod_set_value(adau1372->pd_gpio, 0);
+ gpiod_set_value_cansleep(adau1372->pd_gpio, 0);
if (adau1372->switch_mode)
adau1372->switch_mode(adau1372->dev);
@@ -818,8 +818,7 @@ static int adau1372_set_power(struct adau1372 *adau1372, bool enable)
ADAU1372_CLK_CTRL_PLL_EN,
0);
regcache_cache_only(adau1372->regmap, true);
- if (adau1372->pd_gpio)
- gpiod_set_value(adau1372->pd_gpio, 1);
+ gpiod_set_value_cansleep(adau1372->pd_gpio, 1);
clk_disable_unprepare(adau1372->mclk);
return ret;
}
@@ -836,7 +835,7 @@ static int adau1372_set_power(struct adau1372 *adau1372, bool enable)
* map. No need to do any register writes to manually
* turn things off.
*/
- gpiod_set_value(adau1372->pd_gpio, 1);
+ gpiod_set_value_cansleep(adau1372->pd_gpio, 1);
regcache_mark_dirty(adau1372->regmap);
} else {
regmap_update_bits(adau1372->regmap, ADAU1372_REG_CLK_CTRL,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 243/281] ASoC: adau1372: fix invalid default state of output ASRC and DAC muxes
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (241 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 242/281] ASoC: adau1372: allow sleepy powerdown GPIOs Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 244/281] ASoC: samsung: i2s: enable op_clk in probe to balance runtime PM Greg Kroah-Hartman
` (44 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alvin Šipraga, Nuno Sá,
Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alvin Šipraga <alvin.sipraga@analog.com>
[ Upstream commit 36d0e05815ce84266c8b138cd4f84c3feeaf15f4 ]
The chip has strange power-on reset values for the registers that
control the output ASRC and DAC source muxes - the values are actually
marked "Reserved" in the datasheet [1]. This means that until the
underlying kcontrols are modified, the codec will not function as
expected.
The registers in question are:
register / field reset value valid values
ASRCO_SOURCE_0_1 0x10
ASRC_OUT_SOURCE0 0 4 .. 16
ASRC_OUT_SOURCE1 1 4 .. 16
ASRCO_SOURCE_2_3 0x10
ASRC_OUT_SOURCE2 2 4 .. 16
ASRC_OUT_SOURCE3 3 4 .. 16
DAC_SOURCE_0_1 0x10
DAC_SOURCE_0 0 12 .. 13
DAC_SOURCE_1 1 12 .. 13
Set some sane defaults during the driver probe:
ADC Decimator0 -> Output ASRC0
ADC Decimator1 -> Output ASRC1
ADC Decimator2 -> Output ASRC2
ADC Decimator3 -> Output ASRC3
Input ASRC0 -> DAC0
Input ASRC1 -> DAC1
With this, the chip will behave as advertised by the default kcontrol
state exposed by the driver.
[1] https://www.analog.com/media/en/technical-documentation/data-sheets/ADAU1372.pdf
Fixes: 6cd4c6459e47 ("ASoC: Add ADAU1372 audio CODEC support")
Signed-off-by: Alvin Šipraga <alvin.sipraga@analog.com>
Acked-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20261006-asoc-adau1372-fixes-v1-2-599cc17fb5f6@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/adau1372.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/sound/soc/codecs/adau1372.c b/sound/soc/codecs/adau1372.c
index b84495371b0b4..c3d3be898ba6c 100644
--- a/sound/soc/codecs/adau1372.c
+++ b/sound/soc/codecs/adau1372.c
@@ -1002,6 +1002,17 @@ int adau1372_probe(struct device *dev, struct regmap *regmap,
regmap_write(regmap, ADAU1372_REG_OP_STAGE_MUTE, 0x0);
+ /*
+ * Set sane default values for the Output ASRC and DAC input muxes,
+ * since the power-on reset defaults are invalid "Reserved" states.
+ */
+ regmap_write(regmap, ADAU1372_REG_ASRCO_SOURCE_0_1,
+ 0x54); /* Decimator0, Decimator1 */
+ regmap_write(regmap, ADAU1372_REG_ASRCO_SOURCE_2_3,
+ 0x76); /* Decimator2, Decimator3 */
+ regmap_write(regmap, ADAU1372_REG_DAC_SOURCE,
+ 0xdc); /* Input ASRC0, Input ASRC1 */
+
regmap_write(regmap, 0x7, 0x01); /* CLOCK OUT */
return devm_snd_soc_register_component(dev, &adau1372_driver, &adau1372_dai_driver, 1);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 244/281] ASoC: samsung: i2s: enable op_clk in probe to balance runtime PM
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (242 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 243/281] ASoC: adau1372: fix invalid default state of output ASRC and DAC muxes Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 245/281] spi: sg2044-nor: Return transfer errors Greg Kroah-Hartman
` (43 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marek Szyprowski, Mark Brown,
Sasha Levin, Claude Opus 5.5
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <m.szyprowski@samsung.com>
[ Upstream commit 7529254014764ae0b8c33d5c61a58f36c65b1a1c ]
The probe function puts the device into the runtime PM active state with
only the "iis" bus clock enabled, but it also sets priv->op_clk to the
parent of the RCLK_SRC mux without enabling it. The runtime PM suspend
callback disables both clocks, so the first runtime suspend after probe
disables op_clk once more than it was enabled.
On Exynos5250 Arndale both clocks resolve to the same EXYNOS_I2S_BUS gate,
so this triggers the following warning during boot:
WARNING: drivers/clk/clk.c:1270 at clk_core_disable+0xe4/0x23c, CPU#0: kworker/u8:3/45
i2s_bus already disabled
...
Workqueue: pm pm_runtime_work
Call trace:
...
clk_core_disable from clk_disable+0x28/0x34
clk_disable from i2s_runtime_suspend+0x58/0x68 [snd_soc_i2s]
i2s_runtime_suspend [snd_soc_i2s] from genpd_runtime_suspend+0xc4/0x298
genpd_runtime_suspend from __rpm_callback+0x48/0x18c
__rpm_callback from rpm_callback+0x4c/0x50
rpm_callback from rpm_suspend+0xf4/0x718
rpm_suspend from pm_runtime_work+0x9c/0xa0
...
Fix this by enabling op_clk in probe right after getting it, so the clock
state matches the runtime PM active state, and by disabling it in remove.
Fixes: 48279c53fd1d ("ASoC: samsung: i2s: Prevent external abort on exynos5433 I2S1 access")
Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://patch.msgid.link/20261002092116.585466-1-m.szyprowski@samsung.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/samsung/i2s.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index f80e8d4981565..525126ecb0c30 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -1518,9 +1518,16 @@ static int samsung_i2s_probe(struct platform_device *pdev)
goto err_disable_pm;
priv->op_clk = clk_get_parent(priv->clk_table[CLK_I2S_RCLK_SRC]);
+ ret = clk_prepare_enable(priv->op_clk);
+ if (ret < 0) {
+ priv->op_clk = NULL;
+ goto err_unregister_clk;
+ }
return 0;
+err_unregister_clk:
+ i2s_unregister_clock_provider(priv);
err_disable_pm:
pm_runtime_disable(&pdev->dev);
err_del_sec:
@@ -1543,6 +1550,7 @@ static void samsung_i2s_remove(struct platform_device *pdev)
i2s_unregister_clock_provider(priv);
i2s_delete_secondary_device(priv);
+ clk_disable_unprepare(priv->op_clk);
clk_disable_unprepare(priv->clk);
pm_runtime_put_noidle(&pdev->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 245/281] spi: sg2044-nor: Return transfer errors
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (243 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 244/281] ASoC: samsung: i2s: enable op_clk in probe to balance runtime PM Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 246/281] spi: sg2044-nor: Honor SPI clock limits Greg Kroah-Hartman
` (42 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Han Gao, Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Han Gao <gaohan@iscas.ac.cn>
[ Upstream commit e130c54fbb603f9aeacf5029789b4a2c8c48f416 ]
The transfer helpers return errors, but both dispatchers discard them.
Return these errors to the SPI memory layer instead of reporting success.
Fixes: de16c322eefb ("spi: sophgo: add SG2044 SPI NOR controller driver")
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
Link: https://patch.msgid.link/20261001-fix-sg204xspi-v2-1-014dbaf22b5e@iscas.ac.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-sg2044-nor.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/spi/spi-sg2044-nor.c b/drivers/spi/spi-sg2044-nor.c
index f3bcb8a1b92bb..ff026ca0f7663 100644
--- a/drivers/spi/spi-sg2044-nor.c
+++ b/drivers/spi/spi-sg2044-nor.c
@@ -307,15 +307,15 @@ static ssize_t sg2044_spifmc_tran_cmd(struct sg2044_spifmc *spifmc,
return 0;
}
-static void sg2044_spifmc_trans(struct sg2044_spifmc *spifmc,
- const struct spi_mem_op *op)
+static int sg2044_spifmc_trans(struct sg2044_spifmc *spifmc,
+ const struct spi_mem_op *op)
{
if (op->data.dir == SPI_MEM_DATA_IN)
- sg2044_spifmc_read(spifmc, op);
+ return sg2044_spifmc_read(spifmc, op);
else if (op->data.dir == SPI_MEM_DATA_OUT)
- sg2044_spifmc_write(spifmc, op);
+ return sg2044_spifmc_write(spifmc, op);
else
- sg2044_spifmc_tran_cmd(spifmc, op);
+ return sg2044_spifmc_tran_cmd(spifmc, op);
}
static ssize_t sg2044_spifmc_trans_reg(struct sg2044_spifmc *spifmc,
@@ -389,19 +389,20 @@ static int sg2044_spifmc_exec_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
struct sg2044_spifmc *spifmc;
+ int ret;
spifmc = spi_controller_get_devdata(mem->spi->controller);
mutex_lock(&spifmc->lock);
if (op->addr.nbytes == 0)
- sg2044_spifmc_trans_reg(spifmc, op);
+ ret = sg2044_spifmc_trans_reg(spifmc, op);
else
- sg2044_spifmc_trans(spifmc, op);
+ ret = sg2044_spifmc_trans(spifmc, op);
mutex_unlock(&spifmc->lock);
- return 0;
+ return ret;
}
static const struct spi_controller_mem_ops sg2044_spifmc_mem_ops = {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 246/281] spi: sg2044-nor: Honor SPI clock limits
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (244 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 245/281] spi: sg2044-nor: Return transfer errors Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 247/281] cgroup/cpuset: Call is_in_v2_mode() after acquiring cpuset_mutex in cpuset_handle_hotplug() Greg Kroah-Hartman
` (41 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Han Gao, Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Han Gao <gaohan@iscas.ac.cn>
[ Upstream commit 61d44a2c07b2ad3f7db167f17ff2461ffe78441c ]
The fixed divider ignores device and operation clock limits. Calculate
the divider before each transfer so SCK does not exceed either limit.
Advertise the controller maximum speed so the SPI core supplies a default
when the device omits its maximum speed. Use the fastest divider when no
speed limit is supplied.
Fixes: de16c322eefb ("spi: sophgo: add SG2044 SPI NOR controller driver")
Signed-off-by: Han Gao <gaohan@iscas.ac.cn>
Link: https://patch.msgid.link/20261001-fix-sg204xspi-v2-2-014dbaf22b5e@iscas.ac.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-sg2044-nor.c | 39 ++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/drivers/spi/spi-sg2044-nor.c b/drivers/spi/spi-sg2044-nor.c
index ff026ca0f7663..bc9a8ee9bce44 100644
--- a/drivers/spi/spi-sg2044-nor.c
+++ b/drivers/spi/spi-sg2044-nor.c
@@ -385,6 +385,29 @@ static ssize_t sg2044_spifmc_trans_reg(struct sg2044_spifmc *spifmc,
return 0;
}
+static int sg2044_spifmc_set_speed(struct sg2044_spifmc *spifmc,
+ unsigned int speed_hz)
+{
+ unsigned long rate = clk_get_rate(spifmc->clk);
+ u64 div;
+ u32 reg;
+
+ if (!rate)
+ return -EINVAL;
+
+ /* SCK = HCLK / (2 * (SckDiv + 1)); round down the resulting SCK. */
+ div = speed_hz ? DIV_ROUND_UP_ULL(rate, 2ULL * speed_hz) : 1;
+ if (div > SPIFMC_CTRL_SCK_DIV_MASK + 1)
+ return -EINVAL;
+
+ reg = readl(spifmc->io_base + SPIFMC_CTRL);
+ reg &= ~SPIFMC_CTRL_SCK_DIV_MASK;
+ reg |= div - 1;
+ writel(reg, spifmc->io_base + SPIFMC_CTRL);
+
+ return 0;
+}
+
static int sg2044_spifmc_exec_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
@@ -395,11 +418,18 @@ static int sg2044_spifmc_exec_op(struct spi_mem *mem,
mutex_lock(&spifmc->lock);
+ ret = sg2044_spifmc_set_speed(spifmc, op->max_freq ?
+ min(op->max_freq, mem->spi->max_speed_hz) :
+ mem->spi->max_speed_hz);
+ if (ret)
+ goto out_unlock;
+
if (op->addr.nbytes == 0)
ret = sg2044_spifmc_trans_reg(spifmc, op);
else
ret = sg2044_spifmc_trans(spifmc, op);
+out_unlock:
mutex_unlock(&spifmc->lock);
return ret;
@@ -409,6 +439,10 @@ static const struct spi_controller_mem_ops sg2044_spifmc_mem_ops = {
.exec_op = sg2044_spifmc_exec_op,
};
+static const struct spi_controller_mem_caps sg2044_spifmc_mem_caps = {
+ .per_op_freq = true,
+};
+
static void sg2044_spifmc_init(struct sg2044_spifmc *spifmc)
{
u32 tran_csr;
@@ -448,6 +482,10 @@ static int sg2044_spifmc_probe(struct platform_device *pdev)
if (IS_ERR(spifmc->clk))
return dev_err_probe(dev, PTR_ERR(spifmc->clk), "Cannot get and enable AHB clock\n");
+ ctrl->max_speed_hz = clk_get_rate(spifmc->clk) / 2;
+ if (!ctrl->max_speed_hz)
+ return dev_err_probe(dev, -EINVAL, "Invalid AHB clock rate\n");
+
spifmc->dev = &pdev->dev;
spifmc->ctrl = ctrl;
@@ -459,6 +497,7 @@ static int sg2044_spifmc_probe(struct platform_device *pdev)
ctrl->bits_per_word_mask = SPI_BPW_MASK(8);
ctrl->auto_runtime_pm = false;
ctrl->mem_ops = &sg2044_spifmc_mem_ops;
+ ctrl->mem_caps = &sg2044_spifmc_mem_caps;
ctrl->mode_bits = SPI_RX_DUAL | SPI_TX_DUAL | SPI_RX_QUAD | SPI_TX_QUAD;
ret = devm_mutex_init(dev, &spifmc->lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 247/281] cgroup/cpuset: Call is_in_v2_mode() after acquiring cpuset_mutex in cpuset_handle_hotplug()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (245 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 246/281] spi: sg2044-nor: Honor SPI clock limits Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 248/281] flow_dissector: avoid u16 truncation of skb->len when computing thoff Greg Kroah-Hartman
` (40 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Waiman Long, Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <longman@redhat.com>
[ Upstream commit b8eb5fd5bdb4c03758b056c70e5e1d962ca89757 ]
It is reported by sashiko that calling is_in_v2_mode() outside of
cpuset_mutex critical section in cpuset_handle_hotplug() can introduce
a TOCTOU race where cgroup hierarchy may have changed from v1 to v2 or
vice versa after is_in_v2_mode() is called leading to erroneously skip
the allocation of tmpmasks or incorrectly modify cpus_allowed masks,
resulting in cpuset state corruption. Fix that by calling is_in_v2_mode()
after acquiring the cpuset_mutex.
Fixes: b8d1b8ee93df ("cpuset: Allow v2 behavior in v1 cgroup")
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/cgroup/cpuset.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 16c554df4a50e..501f12de533f4 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -3925,15 +3925,16 @@ static void cpuset_handle_hotplug(void)
static cpumask_t new_cpus;
static nodemask_t new_mems;
bool cpus_updated, mems_updated;
- bool on_dfl = is_in_v2_mode();
+ bool on_dfl;
struct tmpmasks tmp, *ptmp = NULL;
- if (on_dfl && !alloc_tmpmasks(&tmp))
- ptmp = &tmp;
-
lockdep_assert_cpus_held();
mutex_lock(&cpuset_mutex);
+ on_dfl = is_in_v2_mode();
+ if (on_dfl && !alloc_tmpmasks(&tmp))
+ ptmp = &tmp;
+
/* fetch the available cpus/mems and find out which changed how */
cpumask_copy(&new_cpus, cpu_active_mask);
new_mems = node_states[N_MEMORY];
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 248/281] flow_dissector: avoid u16 truncation of skb->len when computing thoff
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (246 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 247/281] cgroup/cpuset: Call is_in_v2_mode() after acquiring cpuset_mutex in cpuset_handle_hotplug() Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 249/281] net: always dissect GSO packets in __virtio_net_hdr_to_skb() Greg Kroah-Hartman
` (39 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Willem de Bruijn,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@kernel.org>
[ Upstream commit 99bda1ecbd56905f8bd934b9cdccd3bd251192b1 ]
__skb_flow_dissect() computes key_control->thoff using:
key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
min_t(u16, ...) casts both arguments to u16 before comparing them.
Whenever skb->len (or hlen) modulo 65536 is smaller than nhoff, the
truncated length wins and thoff is set to a bogus small value, even
when the dissection succeeded. For example, an IPv4/TCP frame with
skb->len == 65540 and nhoff == 34 gets thoff == 4, so callers such as
skb_probe_transport_header() point the transport header inside the
Ethernet header.
Such skbs are not exotic:
- At the time of commit d0c081b49137 ("flow_dissector: properly cap
thoff field"), AF_PACKET with PACKET_VNET_HDR could already build GSO
skbs larger than 64KB (MTU checks are skipped for GSO, and
alloc_skb_with_frags() accepted up to MAX_SKB_FRAGS (17) order-0
pages on top of the linear part).
- BIG TCP now makes skbs larger than 64KB common.
- The following patch makes tun_get_user() dissect IFF_TAP frames
before eth_type_trans() pulls the Ethernet header, so a GSO frame
carrying a 65522..65535 byte L3 packet will be dissected with
skb->len in [65536, 65549].
Compare as u32 instead. If the resulting offset cannot be represented
in the u16 key_control->thoff, cap it to U16_MAX and report the
dissection as failed rather than silently returning a wrong transport
offset. thoff is still set on failure, as some callers (such as
eth_get_headlen()) use it regardless of the return value.
Fixes: d0c081b49137 ("flow_dissector: properly cap thoff field")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20261001191140.2818991-2-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/flow_dissector.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 8aa4f9b4df810..27d8a01bc9230 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -1071,6 +1071,7 @@ bool __skb_flow_dissect(const struct net *net,
int mpls_lse = 0;
int num_hdrs = 0;
u8 ip_proto = 0;
+ u32 thoff;
bool ret;
if (!data) {
@@ -1692,7 +1693,13 @@ bool __skb_flow_dissect(const struct net *net,
ret = true;
out:
- key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
+ thoff = min_t(u32, nhoff, skb ? skb->len : hlen);
+ if (unlikely(thoff > U16_MAX)) {
+ /* Cannot be represented in key_control->thoff. */
+ thoff = U16_MAX;
+ ret = false;
+ }
+ key_control->thoff = thoff;
key_basic->n_proto = proto;
key_basic->ip_proto = ip_proto;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 249/281] net: always dissect GSO packets in __virtio_net_hdr_to_skb()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (247 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 248/281] flow_dissector: avoid u16 truncation of skb->len when computing thoff Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 250/281] net: sparx5: start the TOD counters on non-PTP lan969x variants Greg Kroah-Hartman
` (38 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Weiming Shi, Eric Dumazet,
Willem de Bruijn, Michael S. Tsirkin, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@kernel.org>
[ Upstream commit 44378d02c5aaae24b60a75fbbb539b4aa4db503d ]
Commit 9e8db5913264 ("net: avoid false positives in untrusted gso
validation") added a '&& skb->network_header' check before flow-dissecting
GSO packets without VIRTIO_NET_HDR_F_NEEDS_CSUM in
__virtio_net_hdr_to_skb(), because some callers (such as tun_get_user(),
tun_xdp_one(), virtnet_receive_done(), and raw_verify_header()) called
virtio_net_hdr_*_to_skb() before initializing skb->network_header and
skb->dev.
Because __alloc_skb() and __build_skb_around() zero-initialize
skb->network_header to 0 (unlike mac_header and transport_header which
are initialized to ~0U), those four callers always had
skb->network_header == 0 and bypassed flow dissection in
__virtio_net_hdr_to_skb(). More generally, skb->network_header is an
offset from skb->head (where 0 is also a valid offset whenever
skb_headroom(skb) is 0), not a boolean flag.
Whenever the 'if (gso_type && skb->network_header)' branch was skipped,
the fallback 'else if (gso_type)' only pulled nh_min_len + thlen (40 bytes
for TCPv4) without dissecting the packet, without validating ip_proto or
n_proto, and without setting skb->transport_header.
If the packet has a malformed network header, it is not rejected and a
subsequent skb_probe_transport_header() also fails, leaving
skb->transport_header at ~0U (0xffff). Similarly, if an IPv4 packet
carries IP options (ihl > 5) or an IPv6 packet carries extension headers,
pulling only nh_min_len + thlen can leave the TCP header outside
skb->head. In both cases, tcp_hdrlen(skb) in skb_gso_transport_seglen()
reads out-of-bounds:
BUG: KASAN: slab-out-of-bounds in skb_gso_transport_seglen
Read of size 2 by task poc/133
skb_gso_transport_seglen (net/core/gso.c:155)
skb_gso_validate_mac_len (net/core/gso.c:270)
tbf_enqueue (net/sched/sch_tbf.c:260)
dev_qdisc_enqueue (net/core/dev.c:4227)
__dev_queue_xmit (net/core/dev.c:4884)
In addition, checking virtio_net_hdr_match_proto() only inside
'if (!skb->protocol)' before flow dissection both skipped validation when
skb->protocol was pre-set by the caller and rejected VLAN-tagged frames
whose outer L2 protocol is ETH_P_8021Q or ETH_P_8021AD.
Fix this by:
1. Initializing skb->dev and skb->network_header (plus skb->protocol for
IFF_TUN) before virtio_net_hdr_*_to_skb() in tun_get_user(),
tun_xdp_one(), virtnet_receive_done(), and raw_verify_header(). In
tun_get_user(), drop the redundant skb_reset_mac_header(skb) in the
IFF_TUN case since __virtio_net_hdr_to_skb() unconditionally resets
mac_header.
2. Removing '&& skb->network_header' and the unvalidated
'else if (gso_type)' fallback in __virtio_net_hdr_to_skb() so all GSO
packets without VIRTIO_NET_HDR_F_NEEDS_CSUM are flow-dissected, have
their transport header pulled into linear data, and have
skb->transport_header set.
3. Moving the virtio_net_hdr_match_proto() check to after
skb_flow_dissect_flow_keys_basic(), validating keys.basic.n_proto
against hdr_gso_type.
Fixes: 9e8db5913264 ("net: avoid false positives in untrusted gso validation")
Fixes: d5be7f632bad ("net: validate untrusted gso packets without csum offload")
Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
Reported-by: Weiming Shi <bestswngs@gmail.com>
Closes: https://lore.kernel.org/netdev/20260927163117.746432-2-bestswngs@gmail.com/
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Cc: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20261001191140.2818991-3-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/um/drivers/vector_transports.c | 1 +
drivers/net/tun.c | 23 ++++++-----
drivers/net/virtio_net.c | 2 +
include/linux/virtio_net.h | 60 ++++++++++++-----------------
4 files changed, 42 insertions(+), 44 deletions(-)
diff --git a/arch/um/drivers/vector_transports.c b/arch/um/drivers/vector_transports.c
index ddd127ee96785..e1fb2a76fdff5 100644
--- a/arch/um/drivers/vector_transports.c
+++ b/arch/um/drivers/vector_transports.c
@@ -209,6 +209,7 @@ static int raw_verify_header(
if ((vheader->flags & VIRTIO_NET_HDR_F_DATA_VALID) > 0)
return 1;
+ skb_set_network_header(skb, ETH_HLEN);
virtio_net_hdr_to_skb(skb, vheader, virtio_legacy_is_little_endian());
return 0;
}
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 5bbe3123979e0..dcd39815205a9 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1818,12 +1818,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
}
}
- if (tun_vnet_hdr_tnl_to_skb(tun->flags, features, skb, &hdr)) {
- atomic_long_inc(&tun->rx_frame_errors);
- err = -EINVAL;
- goto free_skb;
- }
-
+ skb->dev = tun->dev;
switch (tun->flags & TUN_TYPE_MASK) {
case IFF_TUN:
if (tun->flags & IFF_NO_PI) {
@@ -1848,9 +1843,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
}
}
- skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
skb->protocol = pi.proto;
- skb->dev = tun->dev;
break;
case IFF_TAP:
if (!pskb_may_pull(skb, ETH_HLEN)) {
@@ -1858,10 +1852,19 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
drop_reason = SKB_DROP_REASON_HDR_TRUNC;
goto drop;
}
- skb->protocol = eth_type_trans(skb, tun->dev);
+ skb_set_network_header(skb, ETH_HLEN);
break;
}
+ if (tun_vnet_hdr_tnl_to_skb(tun->flags, features, skb, &hdr)) {
+ atomic_long_inc(&tun->rx_frame_errors);
+ err = -EINVAL;
+ goto free_skb;
+ }
+
+ if ((tun->flags & TUN_TYPE_MASK) == IFF_TAP)
+ skb->protocol = eth_type_trans(skb, tun->dev);
+
/* copy skb_ubuf_info for callback when skb has no error */
if (zerocopy) {
skb_zcopy_init(skb, msg_control);
@@ -2469,6 +2472,8 @@ static int tun_xdp_one(struct tun_struct *tun,
features = tun_vnet_hdr_guest_features(READ_ONCE(tun->vnet_hdr_sz));
tnl_hdr = (struct virtio_net_hdr_v1_hash_tunnel *)gso;
+ skb->dev = tun->dev;
+ skb_set_network_header(skb, ETH_HLEN);
if (tun_vnet_hdr_tnl_to_skb(tun->flags, features, skb, tnl_hdr)) {
atomic_long_inc(&tun->rx_frame_errors);
kfree_skb(skb);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index bf82ef9874abb..daab43ac92ce4 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2515,6 +2515,8 @@ static void virtnet_receive_done(struct virtnet_info *vi, struct receive_queue *
goto frame_err;
}
+ skb->dev = dev;
+ skb_set_network_header(skb, ETH_HLEN);
if (virtio_net_hdr_tnl_to_skb(skb, &hdr->tnl_hdr, vi->rx_tnl,
vi->rx_tnl_csum,
virtio_is_little_endian(vi->vdev))) {
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index c381b916c1b54..d6466f96cdd00 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -111,48 +111,38 @@ static inline int __virtio_net_hdr_to_skb(struct sk_buff *skb,
p_off = nh_min_len + thlen;
if (!pskb_may_pull(skb, p_off))
return -EINVAL;
- } else {
+ } else if (gso_type) {
/* gso packets without NEEDS_CSUM do not set transport_offset.
* probe and drop if does not match one of the above types.
*/
- if (gso_type && skb->network_header) {
- struct flow_keys_basic keys;
-
- if (!skb->protocol) {
- __be16 protocol = dev_parse_header_protocol(skb);
-
- if (!protocol)
- virtio_net_hdr_set_proto(skb, hdr);
- else if (!virtio_net_hdr_match_proto(protocol,
- hdr_gso_type))
- return -EINVAL;
- else
- skb->protocol = protocol;
- }
+ struct flow_keys_basic keys;
+
+ if (!skb->protocol) {
+ skb->protocol = dev_parse_header_protocol(skb);
+ if (!skb->protocol)
+ virtio_net_hdr_set_proto(skb, hdr);
+ }
retry:
- if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
- NULL, 0, 0, 0,
- 0)) {
- /* UFO does not specify ipv4 or 6: try both */
- if (gso_type & SKB_GSO_UDP &&
- skb->protocol == htons(ETH_P_IP)) {
- skb->protocol = htons(ETH_P_IPV6);
- goto retry;
- }
- return -EINVAL;
+ if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
+ NULL, 0, 0, 0,
+ 0)) {
+ /* UFO does not specify ipv4 or 6: try both */
+ if (gso_type & SKB_GSO_UDP &&
+ skb->protocol == htons(ETH_P_IP)) {
+ skb->protocol = htons(ETH_P_IPV6);
+ goto retry;
}
+ return -EINVAL;
+ }
- p_off = keys.control.thoff + thlen;
- if (!pskb_may_pull(skb, p_off) ||
- keys.basic.ip_proto != ip_proto)
- return -EINVAL;
+ p_off = keys.control.thoff + thlen;
+ if (!pskb_may_pull(skb, p_off) ||
+ keys.basic.ip_proto != ip_proto ||
+ !virtio_net_hdr_match_proto(keys.basic.n_proto,
+ hdr_gso_type))
+ return -EINVAL;
- skb_set_transport_header(skb, keys.control.thoff);
- } else if (gso_type) {
- p_off = nh_min_len + thlen;
- if (!pskb_may_pull(skb, p_off))
- return -EINVAL;
- }
+ skb_set_transport_header(skb, keys.control.thoff);
}
if (hdr_gso_type != VIRTIO_NET_HDR_GSO_NONE) {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 250/281] net: sparx5: start the TOD counters on non-PTP lan969x variants
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (248 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 249/281] net: always dissect GSO packets in __virtio_net_hdr_to_skb() Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 251/281] devlink: fix devlink_rel reference leak when notify work is pending Greg Kroah-Hartman
` (37 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daniel Machon, Quentin Freimanis,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Quentin Freimanis <quentin@q-lab.dev>
[ Upstream commit ca5012757bf027df83d51593a07656cb8c80caee ]
Currently the base non-PTP-capable lan969x variants don't forward any
Ethernet frames:
$ ip link set eth10 up
$ ip addr add 10.0.0.54/24 dev eth10
$ ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1): 56 data bytes
--- 10.0.0.1 ping statistics ---
7 packets transmitted, 0 packets received, 100% packet loss
$ cat /proc/interrupts | grep fdma
20: 0 GIC-0 120 Level sparx5-fdma
$ ip -s link show dev eth10
RX: bytes packets errors dropped missed mcast
20828 102 0 0 0 72
TX: bytes packets errors dropped carrier collsns
0 0 0 0 0 0
Testing showed that starting the domain 0 TOD counter gets networking
working again, but start all three for consistency with the PTP variants.
Fixes: 207966787b71 ("net: sparx5: add feature support")
Suggested-by: Daniel Machon <daniel.machon@microchip.com>
Signed-off-by: Quentin Freimanis <quentin@q-lab.dev>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261005052826.14251-1-quentin@q-lab.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../ethernet/microchip/sparx5/sparx5_ptp.c | 28 +++++++++++--------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
index 5953e04ef14e6..2826e48af1033 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
@@ -622,18 +622,9 @@ int sparx5_ptp_init(struct sparx5 *sparx5)
sparx5->ptp = 1;
}
- if (!sparx5->ptp)
- return 0;
-
- for (i = 0; i < SPARX5_PHC_COUNT; ++i) {
- err = sparx5_ptp_phc_init(sparx5, i, &sparx5_ptp_clock_info);
- if (err)
- return err;
- }
-
- spin_lock_init(&sparx5->ptp_clock_lock);
- spin_lock_init(&sparx5->ptp_ts_id_lock);
- mutex_init(&sparx5->ptp_lock);
+ /* The base, non-PTP-capable lan969x variants need the
+ * first TOD counter running to forward frames.
+ */
/* Disable master counters */
spx5_wr(PTP_PTP_DOM_CFG_PTP_ENA_SET(0), sparx5, PTP_PTP_DOM_CFG);
@@ -657,6 +648,19 @@ int sparx5_ptp_init(struct sparx5 *sparx5)
/* Enable master counters */
spx5_wr(PTP_PTP_DOM_CFG_PTP_ENA_SET(0x7), sparx5, PTP_PTP_DOM_CFG);
+ if (!sparx5->ptp)
+ return 0;
+
+ for (i = 0; i < SPARX5_PHC_COUNT; ++i) {
+ err = sparx5_ptp_phc_init(sparx5, i, &sparx5_ptp_clock_info);
+ if (err)
+ return err;
+ }
+
+ spin_lock_init(&sparx5->ptp_clock_lock);
+ spin_lock_init(&sparx5->ptp_ts_id_lock);
+ mutex_init(&sparx5->ptp_lock);
+
for (i = 0; i < sparx5->data->consts->n_ports; i++) {
port = sparx5->ports[i];
if (!port)
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 251/281] devlink: fix devlink_rel reference leak when notify work is pending
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (249 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 250/281] net: sparx5: start the TOD counters on non-PTP lan969x variants Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 252/281] net/sched: cls_route: reject change with no routing attribute Greg Kroah-Hartman
` (36 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Haishuang Yan, Simon Horman,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
[ Upstream commit c5381ae1cd1481cc431c2bd79460472c6f1d3ce3 ]
devlink_rel_nested_in_notify_work_schedule() takes a reference on the
devlink_rel for the notify work and then queues the work, ignoring the
return value of schedule_delayed_work(). If the work is already pending,
nothing new is queued, the work runs only once and drops only one
reference, so the extra one is leaked together with the devlink_rel and
its index in devlink_rels.
This is easy to hit. devl_register() of a nested instance queues the
work, and if the instance is unregistered before the work has run,
devlink_rel_put() queues it again while it is still pending. The work
also keeps rescheduling itself for as long as the parent devlink lock
cannot be taken, which widens the window. Registering and unregistering
a nested devlink instance 100 times while holding the parent lock leaks
all 100 devlink_rel objects.
The reschedule path in devlink_rel_nested_in_notify_work() has the same
problem: if the work was queued again while it was running, the
reference it holds is never dropped.
Drop the reference in both places when the work was already pending.
The pending work holds its own reference, so this can not be the last
one.
Fixes: c137743bce02 ("devlink: introduce object and nested devlink relationship infra")
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20261001042232.222987-1-yanhaishuang@cmss.chinamobile.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/devlink/core.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/devlink/core.c b/net/devlink/core.c
index fe9f6a0a67d5b..42c16940e4c43 100644
--- a/net/devlink/core.c
+++ b/net/devlink/core.c
@@ -96,13 +96,19 @@ static void devlink_rel_nested_in_notify_work(struct work_struct *work)
return;
reschedule_work:
- schedule_delayed_work(&rel->nested_in.notify_work, 1);
+ /* The work may have been queued again meanwhile, which took its own
+ * reference. Drop ours in that case.
+ */
+ if (!schedule_delayed_work(&rel->nested_in.notify_work, 1))
+ __devlink_rel_put(rel);
}
static void devlink_rel_nested_in_notify_work_schedule(struct devlink_rel *rel)
{
__devlink_rel_get(rel);
- schedule_delayed_work(&rel->nested_in.notify_work, 0);
+ /* The pending work holds a reference already, drop the new one. */
+ if (!schedule_delayed_work(&rel->nested_in.notify_work, 0))
+ __devlink_rel_put(rel);
}
static struct devlink_rel *devlink_rel_alloc(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 252/281] net/sched: cls_route: reject change with no routing attribute
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (250 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 251/281] devlink: fix devlink_rel reference leak when notify work is pending Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 253/281] Revert "net/mlx5: E-Switch, preserve max tx speed on vport state modification" Greg Kroah-Hartman
` (35 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Jamal Hadi Salim,
Victor Nogueira, Simon Horman, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <victor@mojatatu.com>
[ Upstream commit b72e025ac556984766392001e74b7587e145bcd0 ]
route4_change on a filter change that supplies no routing attribute
at all (no to/from/iif) reaches route4_set_parms with fold set, so the
handle-mismatch check -- which only fires when creating -- is skipped.
nhandle is built as the all-wildcard bucket (0x8000 | 0xFFFF << 16) and
the filter is rekeyed to 0xFFFF8000, so the handle userspace already
stored no longer addresses the filter. (The netlink reply carries the
new handle; what goes stale is the handle the caller holds.)
The rekey actually misclassifies the packets. The new handle's from_hash
is the wildcard chain (route4_hash_wild), whose filters route4_classify
applies without any id/iif comparison, and its bucket (256) is reached
by every packet through the h < 256 restart. A filter that matched only
a specific realm therefore becomes an unconditional catch-all that applies
its classid and actions to all otherwise-unmatched traffic.
Reject a change that would rekey the filter this way, with the
routing-attributes-required error. A change that names at least one of
to/from/iif, and an in-place replace that keeps the routing identity via
a supplied attribute, are unaffected. A change of a filter that already
sits at the wildcard handle is a metadata-only update and remains valid,
so only a change that actually moves the handle is rejected.
This is a follow-up to commit 41e85e54e564 ("net/sched: cls_route: Fix
in-place replace"); this patch closes the no-routing-attribute variant
that the parent series did not address.
Conditions to recreate the bug:
tc qdisc add dev lo clsact
tc filter add dev lo ingress protocol ip pref 100 route from 1 to 1
tc filter change dev lo ingress protocol ip pref 100 handle 0x10001 \
route classid 1:2
tc filter show dev lo ingress # handle became 0xffff8000; iproute2's
# stored 0x10001 no longer addresses it
A change of a filter already at the wildcard handle, e.g. one created by
"tc filter add dev lo ingress protocol ip pref 100 route classid 1:1"
(iproute2 defaults the handle to 0xffff8000), stays a valid metadata-only
update.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260907192133.2639067-1-victor@mojatatu.com
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/QDISC-0JB3.v1.20260929143022@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/cls_route.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 0f211f030fd9a..dca812a752698 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -434,6 +434,12 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
if (handle && (!fold || nhandle == (handle & ~0x7F00)))
nhandle |= handle & 0x7F00;
+ if (fold && !tb[TCA_ROUTE4_TO] && !tb[TCA_ROUTE4_FROM] &&
+ !tb[TCA_ROUTE4_IIF] && nhandle != fold->handle) {
+ NL_SET_ERR_MSG(extack, "Routing attributes required");
+ return -EINVAL;
+ }
+
if (handle && !fold && nhandle != handle) {
NL_SET_ERR_MSG_FMT(extack,
"Handle mismatch constructed: %x (expected: %x)",
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 253/281] Revert "net/mlx5: E-Switch, preserve max tx speed on vport state modification"
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (251 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 252/281] net/sched: cls_route: reject change with no routing attribute Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 254/281] net: bcmgenet: if UMAC was suspended in SW_RESET, restore it to SW_RESET Greg Kroah-Hartman
` (34 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Or Har-Toov, Mark Bloch,
Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Or Har-Toov <ohartoov@nvidia.com>
[ Upstream commit 86b785b18f8f4a6b4a7392d1e2b29d6bb095011a ]
This reverts commit ad0ae7aefa7a ("net/mlx5: E-Switch, preserve max tx
speed on vport state modification").
mlx5_modify_vport_admin_state() and mlx5_esw_adj_vport_modify() query
the vport's current max_tx_speed before modifying its state, and
write that value back, to avoid resetting it to 0 as a side effect
of an unrelated admin-state change.
That's unnecessary: max_tx_speed is optional in MODIFY_VPORT_STATE -
FW skips writing it whenever it's 0, treating that as "not provided"
rather than "reset to zero". Leaving it unset already preserves FW's
current value, with no query needed.
Fixes: ad0ae7aefa7a ("net/mlx5: E-Switch, preserve max tx speed on vport state modification")
Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20261004083531.216988-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../mellanox/mlx5/core/esw/adj_vport.c | 20 ----------------
.../net/ethernet/mellanox/mlx5/core/vport.c | 24 -------------------
2 files changed, 44 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/adj_vport.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/adj_vport.c
index 7950b82d8b8ae..3624c680a861a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/adj_vport.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/adj_vport.c
@@ -11,26 +11,6 @@ int mlx5_esw_adj_vport_modify(struct mlx5_core_dev *dev, u16 vport,
lockdep_assert_held(&dev->priv.eswitch->state_lock);
- if (MLX5_CAP_ESW(dev, esw_vport_state_max_tx_speed)) {
- u8 op_mod = MLX5_VPORT_STATE_OP_MOD_ESW_VPORT;
- struct mlx5_vport *esw_vport;
- u32 speed = 0;
- int err;
-
- err = mlx5_query_vport_max_tx_speed(dev, op_mod, vport,
- true, &speed, NULL);
- if (err) {
- esw_vport = mlx5_eswitch_get_vport(dev->priv.eswitch,
- vport);
- speed = IS_ERR(esw_vport) ? 0 :
- esw_vport->agg_max_tx_speed;
- mlx5_core_dbg(dev,
- "Failed to query vport %d max tx speed, err=%d, using cached %u\n",
- vport, err, speed);
- }
- MLX5_SET(modify_vport_state_in, in, max_tx_speed, speed);
- }
-
MLX5_SET(modify_vport_state_in, in, opcode,
MLX5_CMD_OP_MODIFY_VPORT_STATE);
MLX5_SET(modify_vport_state_in, in, op_mod,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
index 8aa94ec87a0e3..edac2d694e0f0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c
@@ -93,30 +93,6 @@ int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
lockdep_assert_held(&mdev->priv.eswitch->state_lock);
#endif
- if (MLX5_CAP_ESW(mdev, esw_vport_state_max_tx_speed) &&
- opmod == MLX5_VPORT_STATE_OP_MOD_ESW_VPORT &&
- vport != MLX5_VPORT_UPLINK) {
- u32 speed = 0;
- int err;
-
- err = mlx5_query_vport_max_tx_speed(mdev, opmod, vport,
- other_vport, &speed, NULL);
- if (err) {
-#ifdef CONFIG_MLX5_ESWITCH
- struct mlx5_vport *esw_vport;
-
- esw_vport = mlx5_eswitch_get_vport(mdev->priv.eswitch,
- vport);
- speed = IS_ERR(esw_vport) ? 0 :
- esw_vport->agg_max_tx_speed;
-#endif
- mlx5_core_dbg(mdev,
- "Failed to query vport %d max tx speed, err=%d, using cached %u\n",
- vport, err, speed);
- }
- MLX5_SET(modify_vport_state_in, in, max_tx_speed, speed);
- }
-
MLX5_SET(modify_vport_state_in, in, opcode,
MLX5_CMD_OP_MODIFY_VPORT_STATE);
MLX5_SET(modify_vport_state_in, in, op_mod, opmod);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 254/281] net: bcmgenet: if UMAC was suspended in SW_RESET, restore it to SW_RESET
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (252 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 253/281] Revert "net/mlx5: E-Switch, preserve max tx speed on vport state modification" Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 255/281] pfcp: make sure the SEID is linear before reading it Greg Kroah-Hartman
` (33 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Justin Chen, Florian Fainelli,
Nicolai Buchwitz, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Chen <justin.chen@broadcom.com>
[ Upstream commit 5857e5a196b069766a39ceb754736326a43bc6bc ]
When the revised suspend/resume sequence was introduced this led to an edge
case where the TX is left disabled in the following sequence.
1. phy link is down, so UMAC is held in reset and then network interface
is WoL enabled
2. Enter suspend, bcmgenet_wol_power_down_cfg() enables UMAC_RX since MAC
is in SW_RESET
4. Enter resume, UMAC_RX is left enabled. Since we only enable UMAC_TX
and UMAC_RX in SW_RESET. The UMAC_TX is never enabled again on link up.
The issue was hit in production and I verified the sequence keeps
the TX disabled in my standalone test. I tested on an internal
development board with bcm77122, but should be reproducible
on any genet HW that supports power management.
Fixes: 254f3239dd07 ("net: bcmgenet: revise suspend/resume")
Signed-off-by: Justin Chen <justin.chen@broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20260930230634.3132729-1-justin.chen@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
index 96d5d4f7f51fe..984432952963a 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
@@ -253,6 +253,17 @@ int bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
reg &= ~CMD_CRC_FWD;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+
+ /*
+ * Mirror wol_power_down_cfg(). If only UMAC_RX
+ * is enabled, then we must place the UMAC back
+ * into SW_RESET.
+ */
+ reg = bcmgenet_umac_readl(priv, UMAC_CMD);
+ if ((reg & CMD_RX_EN) && !(reg & CMD_TX_EN)) {
+ reg |= CMD_SW_RESET;
+ bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+ }
spin_unlock_bh(&priv->reg_lock);
/* Resume link status tracking */
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 255/281] pfcp: make sure the SEID is linear before reading it
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (253 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 254/281] net: bcmgenet: if UMAC was suspended in SW_RESET, restore it to SW_RESET Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 256/281] ASoC: sdw_utils: Add codec info for CS35L62 Greg Kroah-Hartman
` (32 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Haishuang Yan, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
[ Upstream commit 23609bce9e1de525d1d0e73fc68c6e7971d0b49e ]
pfcp_encap_recv() only makes sure that the UDP header and the 4 byte
PFCP header are in the linear area. When the S flag is set,
pfcp_session_recv() then reads the 8 byte SEID that follows, which is
not covered by the pskb_may_pull() check.
A short PFCP packet with the S flag set, or one whose session header
lies in a fragment, therefore makes pfcp_session_recv() read beyond the
end of the packet data, and whatever it finds there is stored in the
tunnel metadata that flower later classifies on.
Pull up to the end of the SEID before reading it, and drop packets
that are too short to contain it. Reload the header pointer afterwards
since pskb_may_pull() may reallocate the skb head.
Use offsetofend() rather than sizeof(struct pfcphdr_session): the
structure is not packed, so its size is 16 bytes because of the
alignment of the __be64 member, while the header on the wire is only 12
bytes, and valid session messages would be dropped.
Fixes: 6dd514f48110 ("pfcp: always set pfcp metadata")
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
Link: https://patch.msgid.link/20260930124818.114224-3-yanhaishuang@cmss.chinamobile.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/pfcp.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/pfcp.c b/drivers/net/pfcp.c
index 8bbaf167db759..08557c0381809 100644
--- a/drivers/net/pfcp.c
+++ b/drivers/net/pfcp.c
@@ -64,6 +64,13 @@ static int pfcp_encap_recv(struct sock *sk, struct sk_buff *skb)
goto drop;
unparsed = pfcp_hdr(skb);
+ if (unparsed->flags & PFCP_SEID_FLAG) {
+ if (unlikely(!pskb_may_pull(skb, PFCP_HLEN +
+ offsetofend(struct pfcphdr_session,
+ seid))))
+ goto drop;
+ unparsed = pfcp_hdr(skb);
+ }
ip_tunnel_flags_zero(flags);
tun_dst = udp_tun_rx_dst(skb, sk->sk_family, flags, 0,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 256/281] ASoC: sdw_utils: Add codec info for CS35L62
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (254 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 255/281] pfcp: make sure the SEID is linear before reading it Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 257/281] ASoC: sdw_utils: Switch CS35L56/57/62/63 to use OT25 DAI Greg Kroah-Hartman
` (31 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefan Binding, Richard Fitzgerald,
Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Binding <sbinding@opensource.cirrus.com>
[ Upstream commit 0306d211558196e051b83e067ee4c30e1b6f94a8 ]
CS35L62 is very similar to CS35L63, and uses the same driver, so we
can use the same configuration.
Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260715120135.939280-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 4b7f393a01f8 ("ASoC: sdw_utils: Switch CS35L56/57/62/63 to use OT25 DAI")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/sdw_utils/soc_sdw_utils.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 5266720e58b3c..2570f40673bdf 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -834,6 +834,35 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
.dai_num = 2,
},
+ {
+ .vendor_id = 0x01fa,
+ .part_id = 0x3562,
+ .name_prefix = "AMP",
+ .is_amp = true,
+ .dais = {
+ {
+ .direction = {true, false},
+ .dai_name = "cs35l56-sdw1",
+ .component_name = "cs35l56",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_cs_amp_init,
+ .rtd_init = asoc_sdw_cs_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ {
+ .direction = {false, true},
+ .dai_name = "cs35l56-sdw1c",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ .rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
+ },
+ },
+ .dai_num = 2,
+ },
{
.vendor_id = 0x01fa,
.part_id = 0x3563,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 257/281] ASoC: sdw_utils: Switch CS35L56/57/62/63 to use OT25 DAI
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (255 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 256/281] ASoC: sdw_utils: Add codec info for CS35L62 Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 258/281] riscv: fix NR_CPUS range leaking 64-bit default onto 32-bit builds Greg Kroah-Hartman
` (30 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Richard Fitzgerald, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <rf@opensource.cirrus.com>
[ Upstream commit 4b7f393a01f88e8d03cba94cf4948652de14789b ]
Change the CS35L56/57/62/63 entries in codec_info_list[] to use
the OT25 DAI for amp feedback.
The AMP feedback was incorrectly using a DAI connected to DP3,
but that is reserved for SDCA companion amp. The correct amp
output is DP4, which is the SDCA OT25 feedback output.
Fixes: 898cd43bde307 ("ASoC: intel: sof_sdw: Add support for CS35L63 into machine driver")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20261005155235.1386525-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/sdw_utils/soc_sdw_utils.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 2570f40673bdf..a47f34afd1d19 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -797,7 +797,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
- .dai_name = "cs35l56-sdw1c",
+ .dai_name = "cs35l56-ot25",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
.rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
@@ -826,7 +826,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
- .dai_name = "cs35l56-sdw1c",
+ .dai_name = "cs35l56-ot25",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
.rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
@@ -855,7 +855,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
- .dai_name = "cs35l56-sdw1c",
+ .dai_name = "cs35l56-ot25",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
.rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
@@ -884,7 +884,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
{
.direction = {false, true},
- .dai_name = "cs35l56-sdw1c",
+ .dai_name = "cs35l56-ot25",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
.rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 258/281] riscv: fix NR_CPUS range leaking 64-bit default onto 32-bit builds
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (256 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 257/281] ASoC: sdw_utils: Switch CS35L56/57/62/63 to use OT25 DAI Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 259/281] riscv: ptrace: Zero-initialize regset buffers before copyin Greg Kroah-Hartman
` (29 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Leo Yu-Chi Liang, Paul Walmsley,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Yu-Chi Liang <leo.liang@sifive.com>
[ Upstream commit 07e23d0b6f58eec351e52058b9a0a8af7b019c09 ]
rv32_defconfig is built in two stages:
- the generic (64-bit-oriented) "defconfig" target runs first
and resolves a concrete NR_CPUS value using the 64BIT default.
- then 32-bit.config is merged on top via merge_config.sh,
which does not touch NR_CPUS.
The final "make olddefconfig" pass sees NR_CPUS=256 is still within
the "2 512" range therefore never recalculates it against the 32BIT
default of 32, silently keeping the leaked 64-bit-stage value.
The NR_CPUS-scaled regions (percpu areas, ...etc) of the resulting
CONFIG_NR_CPUS=256 on a 32-bit build bloats and does not fit in the
percpu/stack layout for rv32 and hangs early boot on QEMU's virt machine.
Fix this by explicitly specify the range for 32/64 and SBI_V01/!SBI_V01.
Fixes: 0fa749771993 ("riscv: Raise default NR_CPUS for 64BIT to 256")
Signed-off-by: Leo Yu-Chi Liang <leo.liang@sifive.com>
Link: https://patch.msgid.link/20261007045229.36114-1-leo.liang@sifive.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/riscv/Kconfig | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index f7028caaeae06..e5166df510bb6 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -450,9 +450,10 @@ config SMP
config NR_CPUS
int "Maximum number of CPUs (2-512)"
depends on SMP
- range 2 512 if !RISCV_SBI_V01
- range 2 32 if RISCV_SBI_V01 && 32BIT
+ range 2 512 if !RISCV_SBI_V01 && 64BIT
+ range 2 128 if !RISCV_SBI_V01 && 32BIT
range 2 64 if RISCV_SBI_V01 && 64BIT
+ range 2 32 if RISCV_SBI_V01 && 32BIT
default "32" if 32BIT
default "64" if RISCV_SBI_V01 && 64BIT
default "256" if !RISCV_SBI_V01 && 64BIT
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 259/281] riscv: ptrace: Zero-initialize regset buffers before copyin
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (257 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 258/281] riscv: fix NR_CPUS range leaking 64-bit default onto 32-bit builds Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 260/281] bnxt_en: Add bnxt_clear_bars() helper Greg Kroah-Hartman
` (28 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zongmin Zhou, Paul Walmsley,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zongmin Zhou <zhouzongmin@kylinos.cn>
[ Upstream commit 59052a88ba5fe4a7bb34b3a0a42aa5d453d3bb97 ]
user_regset_copyin() only copies `count` bytes, so a PTRACE_SETREGSET
request with a short iov_len leaves the rest of the stack buffer
uninitialized. In riscv_vr_set() that garbage is validated and copied
into the target's vstate, and in riscv_cfi_set() it can be stored as
the target's shadow stack pointer. Zero both buffers, as the get path
already does.
Fixes: 9300f0043974 ("RISC-V: Add ptrace support for vectors")
Fixes: 2af7c9cf021c ("riscv/ptrace: expose riscv CFI status and state via ptrace and in core files")
Signed-off-by: Zongmin Zhou <zhouzongmin@kylinos.cn>
Link: https://patch.msgid.link/20260826115711.86861-1-min_halo@163.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/riscv/kernel/ptrace.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 566856e42f658..a0055743d3ba5 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -230,6 +230,7 @@ static int riscv_vr_set(struct task_struct *target,
return -ENODATA;
/* Copy rest of the vstate except datap */
+ memset(&ptrace_vstate, 0, sizeof(ptrace_vstate));
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ptrace_vstate, 0,
sizeof(struct __riscv_v_regset_state));
if (unlikely(ret))
@@ -345,6 +346,7 @@ static int riscv_cfi_set(struct task_struct *target,
regs = task_pt_regs(target);
+ memset(&user_cfi, 0, sizeof(user_cfi));
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &user_cfi, 0, -1);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 260/281] bnxt_en: Add bnxt_clear_bars() helper
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (258 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 259/281] riscv: ptrace: Zero-initialize regset buffers before copyin Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 261/281] bnxt_en: Fix driver init in kdump kernel Greg Kroah-Hartman
` (27 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kalesh AP, Somnath Kotur, Joe Damato,
Pavan Chebbi, Michael Chan, Jacob Keller, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Chan <michael.chan@broadcom.com>
[ Upstream commit 8f5d59b9cfa69beab3b52cca621bb301c5af98aa ]
In bnxt_io_slot_reset(), we clear the 6 BAR registers. Add a helper
function to do that. The helper will be used again in the next patch.
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20261005204246.3822563-2-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 386f887c8290 ("bnxt_en: Fix driver init in kdump kernel")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index cad3bbe1b12f0..da35fec65d1b0 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -17066,6 +17066,14 @@ void bnxt_print_device_info(struct bnxt *bp)
pcie_print_link_status(bp->pdev);
}
+static void bnxt_clear_bars(struct pci_dev *pdev)
+{
+ int off;
+
+ for (off = PCI_BASE_ADDRESS_0; off <= PCI_BASE_ADDRESS_5; off += 4)
+ pci_write_config_dword(pdev, off, 0);
+}
+
static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct bnxt_hw_resc *hw_resc;
@@ -17547,7 +17555,6 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
struct bnxt *bp = netdev_priv(netdev);
int retry = 0;
int err = 0;
- int off;
netdev_info(bp->dev, "PCI Slot Reset\n");
@@ -17576,11 +17583,8 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
* write the BARs to 0 to force restore, in case of fatal error.
*/
if (test_and_clear_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN,
- &bp->state)) {
- for (off = PCI_BASE_ADDRESS_0;
- off <= PCI_BASE_ADDRESS_5; off += 4)
- pci_write_config_dword(bp->pdev, off, 0);
- }
+ &bp->state))
+ bnxt_clear_bars(pdev);
pci_restore_state(pdev);
bnxt_inv_fw_health_reg(bp);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 261/281] bnxt_en: Fix driver init in kdump kernel
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (259 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 260/281] bnxt_en: Add bnxt_clear_bars() helper Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 262/281] bnxt_en: Re-write the BARs following any type of PCIe errors Greg Kroah-Hartman
` (26 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kalesh AP, Pavan Chebbi,
Michael Chan, Jacob Keller, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Chan <michael.chan@broadcom.com>
[ Upstream commit 386f887c8290f0747dd0180e98ec7a82811bc506 ]
Fix and strengthen the FLR sequence when initializing in the kdump
kernel. If the NIC is behind a PCIe switch in synthetic (smart)
mode, the switch may need to see that the BARs have been initialized
before it will pass mem read/write TLPs to the NIC.
On a Dell system with a PEX89144 PCIe switch, echo c > /proc/sysrq-trigger
will trigger fatal AER without this patch:
bnxt_en 0000:67:00.0: enabling device (0000 -> 0002)
[Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 5
[Hardware Error]: event severity: recoverable
[Hardware Error]: Error 0, type: fatal
[Hardware Error]: section_type: PCIe error
[Hardware Error]: port_type: 5, upstream switch port
...
Add a new bnxt_kdump_reset() to do the expanded FLR sequence in the
kdump kernel. We now disable bus master and memory, save the PCI
state, do the FLR, clear the BARs, and restore the PCI state. The
BARs have to be cleared to ensure that they get re-initialized and
visible to the PCIe switch.
Since it is the kdump kernel, we make every effort to continue in
the best possible way even if pci_save_state() or pcie_flr() returns
error. After FLR, we poll for an additional 5 seconds before
aborting in case the device is not properly returning CRS. This is
similar to the 5-second wait in bnxt_io_slot_reset().
Fixes: 8743db4a9acf ("bnxt_en: Issue PCIe FLR in kdump kernel to cleanup pending DMAs.")
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20261005204246.3822563-3-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 45 ++++++++++++++++++++---
1 file changed, 40 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index da35fec65d1b0..5a2efb262b769 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -17074,6 +17074,43 @@ static void bnxt_clear_bars(struct pci_dev *pdev)
pci_write_config_dword(pdev, off, 0);
}
+/* Clear any pending DMA transactions from crash kernel while loading driver in
+ * capture kernel.
+ */
+static int bnxt_kdump_reset(struct pci_dev *pdev)
+{
+ int rc, i;
+ u16 cmd;
+
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+ pci_write_config_word(pdev, PCI_COMMAND, cmd);
+
+ if (pci_save_state(pdev))
+ dev_warn(&pdev->dev, "Failed to save PCI state, PCI restore may be incomplete\n");
+
+ rc = pcie_flr(pdev);
+ if (rc)
+ dev_warn(&pdev->dev, "pcie_flr() failed (rc: %d), trying to continue\n",
+ rc);
+
+ /* In case device is not returning CRS, wait 5 seconds longer */
+ for (i = 0; i < 50; i++) {
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+ if (!PCI_POSSIBLE_ERROR(cmd))
+ break;
+ msleep(100);
+ }
+ if (PCI_POSSIBLE_ERROR(cmd)) {
+ dev_err(&pdev->dev, "PCI config space inaccessible after FLR, aborting\n");
+ return -ENODEV;
+ }
+
+ bnxt_clear_bars(pdev);
+ pci_restore_state(pdev);
+ return 0;
+}
+
static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct bnxt_hw_resc *hw_resc;
@@ -17089,12 +17126,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return -ENODEV;
}
- /* Clear any pending DMA transactions from crash kernel
- * while loading driver in capture kernel.
- */
if (is_kdump_kernel()) {
- pci_clear_master(pdev);
- pcie_flr(pdev);
+ rc = bnxt_kdump_reset(pdev);
+ if (rc)
+ return rc;
}
max_irqs = bnxt_get_max_irq(pdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 262/281] bnxt_en: Re-write the BARs following any type of PCIe errors
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (260 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 261/281] bnxt_en: Fix driver init in kdump kernel Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 263/281] flow_dissector: avoid u16 truncation of hlen in bpf_flow_dissect() Greg Kroah-Hartman
` (25 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kalesh AP, Scott Branden,
Pavan Chebbi, Michael Chan, Jacob Keller, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavan Chebbi <pavan.chebbi@broadcom.com>
[ Upstream commit 2e52da27096d9dbc487f303bbc10d44ad837a8c4 ]
Currently the driver zeroes the BARs only when fatal PCIe errors
are reported so that pci_restore_state() restores it. However
firmware handles both fatal and non-fatal errors the same way when
it sees the slot reset resulting from the PCI_ERS_RESULT_NEED_RESET
return code from the driver. This means that we must re-write the
BARs post recovery even during non-fatal errors. Otherwise we will
see that every MMIO access returns all-ones and the firmware appears
dead.
Zero-out the BARs during PCIe error recovery regardless of type of
PCIe error, and make the wait after the hot reset unconditional.
Disable memory decode and bus mastering before rewriting the BARs so
the device doesn't decode a half-updated address, bailing out if
config space is still inaccessible. Defer pci_enable_device() until
after the BAR rewrite and restore, so the device isn't re-enabled
while its BARs are still being rewritten, then re-enable the device
and re-assert bus mastering. Guard the same Command register cleanup
on the re-enable failure path against an inaccessible device.
Skip re-enabling the device in bnxt_io_slot_reset() if it is already
enabled, so enable_cnt does not go unbalanced. A concurrent
bnxt_fw_reset_task() can also be re-enabling the same device in its
ENABLE_DEV state, so guard that call the same way.
Fixes: f75d9a0aa967 ("bnxt_en: Re-write PCI BARs after PCI fatal error.")
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Scott Branden <scott.branden@broadcom.com>
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/20261005204246.3822563-4-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 107 ++++++++++++----------
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 -
2 files changed, 60 insertions(+), 48 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 5a2efb262b769..78583cee3414f 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -15505,7 +15505,7 @@ static void bnxt_fw_reset_task(struct work_struct *work)
if (test_and_clear_bit(BNXT_STATE_FW_ACTIVATE_RESET, &bp->state) &&
!test_bit(BNXT_STATE_FW_ACTIVATE, &bp->state))
bnxt_dl_remote_reload(bp);
- if (pci_enable_device(bp->pdev)) {
+ if (!pci_is_enabled(bp->pdev) && pci_enable_device(bp->pdev)) {
netdev_err(bp->dev, "Cannot re-enable PCI device\n");
rc = -ENODEV;
goto fw_reset_abort;
@@ -17557,10 +17557,8 @@ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev,
* so we disable bus master to prevent any potential bad DMAs before
* freeing kernel memory.
*/
- if (state == pci_channel_io_frozen) {
- set_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN, &bp->state);
+ if (state == pci_channel_io_frozen)
bnxt_fw_fatal_close(bp);
- }
if (netif_running(netdev))
__bnxt_close_nic(bp, true, true);
@@ -17590,65 +17588,80 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
struct bnxt *bp = netdev_priv(netdev);
int retry = 0;
int err = 0;
+ u16 cmd;
netdev_info(bp->dev, "PCI Slot Reset\n");
- if (test_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN, &bp->state)) {
- /* After DPC, the chip should return CRS when the vendor ID
- * config register is read until it is ready. On all chips,
- * this is not happening reliably so add a 5-second delay as a
- * workaround.
- */
- msleep(5000);
- }
+ /* After a PCIe hot reset, the chip should return CRS when the
+ * vendor ID config register is read until it is ready. On all
+ * chips, this is not happening reliably so add a 5-second delay
+ * as a workaround.
+ */
+ msleep(5000);
netdev_lock(netdev);
- if (pci_enable_device(pdev)) {
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+ if (PCI_POSSIBLE_ERROR(cmd)) {
dev_err(&pdev->dev,
- "Cannot re-enable PCI device after reset.\n");
- } else {
- pci_set_master(pdev);
- /* Upon fatal error, our device internal logic that latches to
- * BAR value is getting reset and will restore only upon
- * rewriting the BARs.
- *
- * As pci_restore_state() does not re-write the BARs if the
- * value is same as saved value earlier, driver needs to
- * write the BARs to 0 to force restore, in case of fatal error.
- */
- if (test_and_clear_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN,
- &bp->state))
- bnxt_clear_bars(pdev);
- pci_restore_state(pdev);
+ "PCI config space inaccessible after reset\n");
+ goto reset_exit;
+ }
- bnxt_inv_fw_health_reg(bp);
- bnxt_try_map_fw_health_reg(bp);
+ /* Upon PCIe error, our device internal logic that latches to
+ * BAR value is getting reset and will restore only upon
+ * rewriting the BARs.
+ *
+ * As pci_restore_state() does not re-write the BARs if the
+ * value is same as saved value earlier, driver needs to
+ * write the BARs to 0 to force restore.
+ */
+ pci_clear_master(pdev);
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+ cmd &= ~PCI_COMMAND_MEMORY;
+ pci_write_config_word(pdev, PCI_COMMAND, cmd);
- /* In some PCIe AER scenarios, firmware may take up to
- * 10 seconds to become ready in the worst case.
- */
- do {
- err = bnxt_try_recover_fw(bp);
- if (!err)
- break;
- retry++;
- } while (retry < BNXT_FW_SLOT_RESET_RETRY);
+ bnxt_clear_bars(pdev);
+ pci_restore_state(pdev);
- if (err) {
- dev_err(&pdev->dev, "Firmware not ready\n");
- goto reset_exit;
+ if (!pci_is_enabled(pdev) && pci_enable_device(pdev)) {
+ dev_err(&pdev->dev,
+ "Cannot re-enable PCI device after reset.\n");
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+ if (!PCI_POSSIBLE_ERROR(cmd)) {
+ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+ pci_write_config_word(pdev, PCI_COMMAND, cmd);
}
+ goto reset_exit;
+ }
+ pci_set_master(pdev);
- err = bnxt_hwrm_func_reset(bp);
+ bnxt_inv_fw_health_reg(bp);
+ bnxt_try_map_fw_health_reg(bp);
+
+ /* In some PCIe AER scenarios, firmware may take up to
+ * 10 seconds to become ready in the worst case.
+ */
+ do {
+ err = bnxt_try_recover_fw(bp);
if (!err)
- result = PCI_ERS_RESULT_RECOVERED;
+ break;
+ retry++;
+ } while (retry < BNXT_FW_SLOT_RESET_RETRY);
- /* IRQ will be initialized later in bnxt_io_resume */
- bnxt_ulp_irq_stop(bp);
- bnxt_clear_int_mode(bp);
+ if (err) {
+ dev_err(&pdev->dev, "Firmware not ready\n");
+ goto reset_exit;
}
+ err = bnxt_hwrm_func_reset(bp);
+ if (!err)
+ result = PCI_ERS_RESULT_RECOVERED;
+
+ /* IRQ will be initialized later in bnxt_io_resume */
+ bnxt_ulp_irq_stop(bp);
+ bnxt_clear_int_mode(bp);
+
reset_exit:
clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
bnxt_clear_reservations(bp, true);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 4dbcd08ef7c32..a939f4ed10079 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -2470,7 +2470,6 @@ struct bnxt {
#define BNXT_STATE_ABORT_ERR 5
#define BNXT_STATE_FW_FATAL_COND 6
#define BNXT_STATE_DRV_REGISTERED 7
-#define BNXT_STATE_PCI_CHANNEL_IO_FROZEN 8
#define BNXT_STATE_NAPI_DISABLED 9
#define BNXT_STATE_FW_ACTIVATE 11
#define BNXT_STATE_RECOVER 12
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 263/281] flow_dissector: avoid u16 truncation of hlen in bpf_flow_dissect()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (261 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 262/281] bnxt_en: Re-write the BARs following any type of PCIe errors Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 264/281] bareudp: set the inner protocol to the protocol of the packet Greg Kroah-Hartman
` (24 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@kernel.org>
[ Upstream commit f202578efc738b883cfa04889eb97328914265a7 ]
bpf_flow_dissect() sanitizes the offsets returned by the BPF program
with clamp_t(u16, ..., hlen).
If hlen is bigger than 65535, the upper bound is truncated before
the comparison. For instance, with hlen == 65536, both nhoff and
thoff are forced to zero, even if the program returned sane values.
This is the same class of bug as the one fixed in commit 99bda1ecbd56
("flow_dissector: avoid u16 truncation of skb->len when computing
thoff"). That fix does not cover the BPF path, because
__skb_flow_dissect() returns early when a BPF flow dissector
handles the packet.
struct bpf_flow_keys stores nhoff and thoff as u16, so cap hlen
to U16_MAX before clamping.
Found by sashiko while reviewing the commit above.
Fixes: d58e468b1112 ("flow_dissector: implements flow dissector BPF hook")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261007045616.445596-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/flow_dissector.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 27d8a01bc9230..1be6c739e3c71 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -1023,6 +1023,8 @@ u32 bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
result = bpf_prog_run_pin_on_cpu(prog, ctx);
+ /* bpf_flow_keys offsets are u16: do not let @hlen be truncated. */
+ hlen = min_t(int, hlen, U16_MAX);
flow_keys->nhoff = clamp_t(u16, flow_keys->nhoff, nhoff, hlen);
flow_keys->thoff = clamp_t(u16, flow_keys->thoff,
flow_keys->nhoff, hlen);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 264/281] bareudp: set the inner protocol to the protocol of the packet
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (262 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 263/281] flow_dissector: avoid u16 truncation of hlen in bpf_flow_dissect() Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 265/281] drm/imagination: Fix reference and vm_bo handling in remap() Greg Kroah-Hartman
` (23 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Haishuang Yan, Willem de Bruijn,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
[ Upstream commit c57b2e60d4bf29707c51b39ed3bacbcce2f3ba2e ]
bareudp_xmit_skb() sets the inner protocol of the skb to the configured
ethertype, and bareudp6_xmit_skb() does not set it at all. The inner
protocol is used by skb_udp_tunnel_segment() to segment the inner packet
when GSO has to be done in software, for instance when the lower device
does not offload the checksum.
With multiproto, an IPv4 device also carries IPv6, so the IPv6 header
is parsed as an IPv4 one. With IPv6 underlay, the inner protocol is
whatever the skb had before. In both cases segmentation fails and the
packets are dropped. With veth tx checksum offload disabled, iperf3 TCP
over bareudp gets about 10 Mbit/s with thousands of retransmits instead
of about 700 Mbit/s for IPv6 over IPv4 and for both families over IPv6,
while IPv4 over IPv4 works.
At this point skb->protocol is the protocol of the inner packet, which
bareudp_xmit() has already checked against the configuration, so use it
on both paths.
Fixes: 571912c69f0e ("net: UDP tunnel encapsulation module for tunnelling different protocols like MPLS, IP, NSH etc.")
Fixes: 4b5f67232d95 ("net: Special handling for IP & MPLS.")
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20261002153039.462663-1-yanhaishuang@cmss.chinamobile.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/bareudp.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c
index 5ef841c855269..2bfad8653be6a 100644
--- a/drivers/net/bareudp.c
+++ b/drivers/net/bareudp.c
@@ -355,7 +355,7 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (err)
goto free_dst;
- skb_set_inner_protocol(skb, bareudp->ethertype);
+ skb_set_inner_protocol(skb, skb->protocol);
udp_tunnel_xmit_skb(rt, sk, skb, saddr, info->key.u.ipv4.dst,
tos, ttl, df, sport, bareudp->port,
!net_eq(bareudp->net, dev_net(bareudp->dev)),
@@ -423,6 +423,7 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (err)
goto free_dst;
+ skb_set_inner_protocol(skb, skb->protocol);
daddr = info->key.u.ipv6.dst;
udp_tunnel6_xmit_skb(dst, sk, skb, dev,
&saddr, &daddr, prio, ttl,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 265/281] drm/imagination: Fix reference and vm_bo handling in remap()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (263 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 264/281] bareudp: set the inner protocol to the protocol of the packet Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 266/281] veth: fix peer NETDEV_XDP_ACT_NDO_XMIT after GRO is toggled while down Greg Kroah-Hartman
` (22 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gyeyoung Baek, Brajesh Gupta,
Alessio Belle, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gyeyoung Baek <gye976@gmail.com>
[ Upstream commit 196d4d10c1b33ae176685ff42a9994a5952b1d0f ]
When a map overlaps part of an existing mapping, pvr_vm_gpuva_remap()
splits the mapping into prev/next parts covering what the request did
not take, instead of creating something new. It gets two things wrong.
- A GEM reference is taken for each part but it's never needed and never
dropped, so it leaks one reference per split (remap-next-in-2m in
tests/imagination/pvr_vm_map.c):
CRITICAL: 33558528 bytes of shmem still held after close
- The parts still belong to the original object being split, but
pvr_vm_gpuva_remap() links them to ctx->gpuvm_bo, the new object's
vm_bo:
prev_va --obj--> BO_A BO_B <--obj-- vm_bo (ctx->gpuvm_bo)
\___________link___________/ (mismatch: BO_A != BO_B)
drm_gpuva_link() catches the mismatch:
WARNING: drivers/gpu/drm/drm_gpuvm.c:2108 at drm_gpuva_link+0x2ec/0x310
drm_WARN_ON(obj != vm_bo->obj)
Call trace:
drm_gpuva_link
pvr_vm_gpuva_remap
__drm_gpuvm_sm_map
pvr_vm_map
pvr_ioctl_vm_map
Link them to op->remap.unmap->va->vm_bo instead.
The locking of the GPUVA lists of the other objects touched by a split is
not addressed here; it is handled by switching the GPUVM to immediate
mode.
Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code")
Signed-off-by: Gyeyoung Baek <gye976@gmail.com>
Reviewed-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
Link: https://patch.msgid.link/20261001-pvr-fixes-a-v2-1-f58254e5dfb8@gmail.com
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/imagination/pvr_vm.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_vm.c b/drivers/gpu/drm/imagination/pvr_vm.c
index 55cc999f3708b..cbdd15ed74fdb 100644
--- a/drivers/gpu/drm/imagination/pvr_vm.c
+++ b/drivers/gpu/drm/imagination/pvr_vm.c
@@ -418,6 +418,8 @@ pvr_vm_gpuva_unmap(struct drm_gpuva_op *op, void *op_ctx)
static int
pvr_vm_gpuva_remap(struct drm_gpuva_op *op, void *op_ctx)
{
+ /* The split parts belong to the object of the mapping being split. */
+ struct drm_gpuvm_bo *vm_bo = op->remap.unmap->va->vm_bo;
struct pvr_vm_bind_op *ctx = op_ctx;
u64 va_start = 0, va_range = 0;
int err;
@@ -433,14 +435,12 @@ pvr_vm_gpuva_remap(struct drm_gpuva_op *op, void *op_ctx)
drm_gpuva_remap(&ctx->prev_va->base, &ctx->next_va->base, &op->remap);
if (op->remap.prev) {
- pvr_gem_object_get(gem_to_pvr_gem(ctx->prev_va->base.gem.obj));
- drm_gpuva_link(&ctx->prev_va->base, ctx->gpuvm_bo);
+ drm_gpuva_link(&ctx->prev_va->base, vm_bo);
ctx->prev_va = NULL;
}
if (op->remap.next) {
- pvr_gem_object_get(gem_to_pvr_gem(ctx->next_va->base.gem.obj));
- drm_gpuva_link(&ctx->next_va->base, ctx->gpuvm_bo);
+ drm_gpuva_link(&ctx->next_va->base, vm_bo);
ctx->next_va = NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 266/281] veth: fix peer NETDEV_XDP_ACT_NDO_XMIT after GRO is toggled while down
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (264 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 265/281] drm/imagination: Fix reference and vm_bo handling in remap() Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 267/281] net/mlx5e: Order ICOSQ cc update after CQ doorbell Greg Kroah-Hartman
` (21 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tianyi Gao,
Toke Høiland-Jørgensen, Jesper Dangaard Brouer,
Lorenzo Bianconi, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianyi Gao <tianyi@cloudflare.com>
[ Upstream commit 3f090039995f609a8e236f37980dee5712dded61 ]
A veth device advertises NETDEV_XDP_ACT_NDO_XMIT only if its peer has an
XDP program attached or GRO enabled, that is, only if the peer will have
NAPI to receive the frames.
veth_set_features() updates the peer's flag when GRO is toggled, but
returns early if the device is down, and veth_open() only refreshes the
flags of the device being opened. Toggling GRO while the device is down
therefore leaves the peer's flag stale after the device comes up.
If GRO was enabled while down, the device comes up with NAPI but the
peer does not advertise NDO_XMIT, and devmap rejects redirects to the
peer with -EOPNOTSUPP. If GRO was disabled while down, the device comes
up without NAPI but the peer still advertises NDO_XMIT, so redirects are
accepted and then dropped in veth_xdp_xmit() with -ENXIO.
Commit 7a6102aa6df0 ("veth: Update XDP feature set when bringing up
device") made veth_open() refresh the device's own flags. Refresh the
peer's flags there too. The peer's flag depends on this device's XDP
program and GRO setting, not on whether the peer is up, so it is
correct to set it even if the peer is down.
Fixes: 8267fc71abb2 ("veth: take into account peer device for NETDEV_XDP_ACT_NDO_XMIT xdp_features flag")
Signed-off-by: Tianyi Gao <tianyi@cloudflare.com>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Acked-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Link: https://patch.msgid.link/20261006173241.65945-2-tianyi@cloudflare.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/veth.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 2780b2dd073d1..4f145c5f686ef 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1414,6 +1414,7 @@ static int veth_open(struct net_device *dev)
}
veth_set_xdp_features(dev);
+ veth_set_xdp_features(peer);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 267/281] net/mlx5e: Order ICOSQ cc update after CQ doorbell
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (265 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 266/281] veth: fix peer NETDEV_XDP_ACT_NDO_XMIT after GRO is toggled while down Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 268/281] mlxsw: spectrum_flower: Fix port range register leak in tmplt_create() Greg Kroah-Hartman
` (20 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Li RongQing, Dragos Tatulea,
Tariq Toukan, Daniel Machon, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li RongQing <lirongqing@baidu.com>
[ Upstream commit b056ca4d3742d0769f91137bb1ce3215428398f7 ]
mlx5e_poll_ico_cq() requires sq->cc to be updated only after
mlx5_cqwq_update_db_record(), otherwise a CQ overrun may occur.
The current implementation updates sq->cc before the CQ doorbell
record, violating this ordering requirement.
Update the CQ doorbell record first and use dma_wmb() before updating
sq->cc. This ensures that the CQ space is released to the device
before the corresponding ICOSQ consumer index is updated by software.
Fixes: fd9b4be8002c ("net/mlx5e: RX, Support multiple outstanding UMR posts")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261006105820.257208-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 7967a27372981..c75b064b04166 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -908,10 +908,12 @@ int mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
} while (!last_wqe);
} while ((++i < MLX5E_TX_CQ_POLL_BUDGET) && (cqe = mlx5_cqwq_get_cqe(&cq->wq)));
- sq->cc = sqcc;
-
mlx5_cqwq_update_db_record(&cq->wq);
+ /* ensure cq space is freed before enabling more cqes */
+ dma_wmb();
+
+ sq->cc = sqcc;
return i;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 268/281] mlxsw: spectrum_flower: Fix port range register leak in tmplt_create()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (266 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 267/281] net/mlx5e: Order ICOSQ cc update after CQ doorbell Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 269/281] net/packet: call packet_parse_headers after virtio_net_hdr_to_skb Greg Kroah-Hartman
` (19 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wentao Liang, Ido Schimmel,
Petr Machata, Jacob Keller, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Machata <petrm@nvidia.com>
[ Upstream commit 7ea07afb230f1342ab0f9365edd0aae137f425d3 ]
mlxsw_sp_flower_tmplt_create() parses a flow_cls_offload template
into a stack-local struct mlxsw_sp_acl_rule_info purely to compute
rulei.values.elusage. Parsing can acquire port range registers via
mlxsw_sp_flower_parse_ports_range(), but since this rulei never goes
through mlxsw_sp_acl_rulei_destroy(), those registers were never
released, including through chain template deletion.
Factor out of mlxsw_sp_acl_rulei_destroy() the code to actually
release the necessary resources and call from
mlxsw_sp_flower_tmplt_create() to plug the leak.
The issue was found during a review of Wentao Liang's patch referenced
below.
Fixes: fe22f7410527 ("mlxsw: spectrum_flower: Add ability to match on port ranges")
Reported-by: Wentao Liang <vulab@iscas.ac.cn>
Closes: https://lore.kernel.org/netdev/20260917113236.2149095-1-vulab@iscas.ac.cn/
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://patch.msgid.link/95339cf970ce78e1a74aa86ffcc104ecf7c7762c.1791294384.git.petrm@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 2 ++
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | 10 ++++++++--
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c | 9 +++++++--
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index b03ff9e044f9e..10af08ce72efa 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -989,6 +989,8 @@ void mlxsw_sp_acl_ruleset_prio_get(struct mlxsw_sp_acl_ruleset *ruleset,
struct mlxsw_sp_acl_rule_info *
mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
struct mlxsw_afa_block *afa_block);
+void mlxsw_sp_acl_rulei_free(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_acl_rule_info *rulei);
void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_rule_info *rulei);
int mlxsw_sp_acl_rulei_commit(struct mlxsw_sp_acl_rule_info *rulei);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
index cb232accb296a..f7be4f3a15184 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
@@ -340,8 +340,8 @@ mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
return ERR_PTR(err);
}
-void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp *mlxsw_sp,
- struct mlxsw_sp_acl_rule_info *rulei)
+void mlxsw_sp_acl_rulei_free(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_acl_rule_info *rulei)
{
if (rulei->action_created)
mlxsw_afa_block_destroy(rulei->act_block);
@@ -351,6 +351,12 @@ void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp *mlxsw_sp,
if (rulei->dst_port_range_reg_valid)
mlxsw_sp_port_range_reg_put(mlxsw_sp,
rulei->dst_port_range_reg_index);
+}
+
+void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_acl_rule_info *rulei)
+{
+ mlxsw_sp_acl_rulei_free(mlxsw_sp, rulei);
kfree(rulei);
}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
index 353fd9ca89a68..5e4632cb792d5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
@@ -862,14 +862,19 @@ int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp,
memset(&rulei, 0, sizeof(rulei));
err = mlxsw_sp_flower_parse(mlxsw_sp, block, &rulei, f);
if (err)
- return err;
+ goto out;
+
ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block,
f->common.chain_index,
MLXSW_SP_ACL_PROFILE_FLOWER,
&rulei.values.elusage);
+ err = PTR_ERR_OR_ZERO(ruleset);
+
+out:
+ mlxsw_sp_acl_rulei_free(mlxsw_sp, &rulei);
/* keep the reference to the ruleset */
- return PTR_ERR_OR_ZERO(ruleset);
+ return err;
}
void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp,
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 269/281] net/packet: call packet_parse_headers after virtio_net_hdr_to_skb
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (267 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 268/281] mlxsw: spectrum_flower: Fix port range register leak in tmplt_create() Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 270/281] ptp: ocp: fix PCIe delay estimation calculation Greg Kroah-Hartman
` (18 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Junnan Zhang, Willem de Bruijn,
Michael S. Tsirkin, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn <willemb@google.com>
[ Upstream commit 513e23857a3a64fa73a1deb36a385eecd4ad7690 ]
SOCK_RAW packet sockets incorrectly drop VLAN-tagged GSO packets
without VIRTIO_NET_HDR_F_NEEDS_CSUM.
packet_parse_headers() sets skb->protocol to VLAN but advances
skb->network_header past the VLAN tags. virtio_net_hdr_to_skb()
then flow dissects these packets, which parses the network header as a
VLAN tag, and fails.
Call packet_parse_headers() after virtio_net_hdr_to_skb() instead.
This matches tun_get_user() and tap_get_user() and thus simplifies
overall complexity.
Commit 01fdecc0480d ("net: packet: fix wrong transport_header when
sending VLAN-tagged frame") fixed the same issue for the transport
header probe in packet_parse_headers(). That probe is now skipped if
virtio_net_hdr_to_skb() already set the transport header, avoiding a
redundant dissection.
Implementation details:
- Do not set skb->protocol to the RX wildcard ETH_P_ALL. SOCK_RAW then
derives it from the link layer header, as before. SOCK_DGRAM now
leaves it 0, or derives it from gso_type for GSO with NEEDS_CSUM.
- Keep virtio_net_hdr_set_proto() last, so that the link layer protocol
takes priority over gso_type.
Reported-by: Junnan Zhang <zhangjn_dev@163.com>
Closes: https://lore.kernel.org/netdev/20260821085722.24036-1-zhangjn_dev@163.com/
Fixes: dfed913e8b55 ("net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO")
Signed-off-by: Willem de Bruijn <willemb@google.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20261007175816.3138556-1-willemdebruijn.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/packet/af_packet.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 6ff16eef24f4f..52ae3d875e971 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1943,8 +1943,7 @@ static void packet_parse_headers(struct sk_buff *skb, struct socket *sock)
/* On TX skb->data is the L2 header; anchor it for all socket types. */
skb_reset_mac_header(skb);
- if ((!skb->protocol || skb->protocol == htons(ETH_P_ALL)) &&
- sock->type == SOCK_RAW)
+ if (!skb->protocol && sock->type == SOCK_RAW)
skb->protocol = dev_parse_header_protocol(skb);
skb_probe_transport_header(skb);
@@ -2614,7 +2613,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
struct page *page;
int err;
- skb->protocol = proto;
+ if (proto != htons(ETH_P_ALL))
+ skb->protocol = proto;
skb->dev = dev;
skb->priority = sockc->priority;
skb->mark = sockc->mark;
@@ -2678,8 +2678,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
if (unlikely(!skb->len))
return -EINVAL;
- packet_parse_headers(skb, sock);
-
return tp_len;
}
@@ -2919,9 +2917,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
tp_len = -EINVAL;
goto tpacket_error;
}
- virtio_net_hdr_set_proto(skb, &vnet_hdr);
}
+ packet_parse_headers(skb, po->sk.sk_socket);
+
+ if (has_vnet_hdr)
+ virtio_net_hdr_set_proto(skb, &vnet_hdr);
+
uarg = kmalloc(sizeof(*uarg), GFP_KERNEL);
if (unlikely(!uarg)) {
if (likely(len_sum > 0))
@@ -3122,7 +3124,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
goto out_free;
}
- skb->protocol = proto;
+ if (proto != htons(ETH_P_ALL))
+ skb->protocol = proto;
skb->dev = dev;
skb->priority = sockc.priority;
skb->mark = sockc.mark;
@@ -3131,16 +3134,18 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
if (unlikely(extra_len == 4))
skb->no_fcs = 1;
- packet_parse_headers(skb, sock);
-
if (vnet_hdr_sz) {
err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le());
if (err)
goto out_free;
len += vnet_hdr_sz;
- virtio_net_hdr_set_proto(skb, &vnet_hdr);
}
+ packet_parse_headers(skb, sock);
+
+ if (vnet_hdr_sz)
+ virtio_net_hdr_set_proto(skb, &vnet_hdr);
+
err = packet_xmit(po, skb);
if (unlikely(err != 0)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 270/281] ptp: ocp: fix PCIe delay estimation calculation
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (268 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 269/281] net/packet: call packet_parse_headers after virtio_net_hdr_to_skb Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 271/281] net: openvswitch: validate transport header presence in set_ipv6_addr Greg Kroah-Hartman
` (17 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vadim Fedorenko, Daniel Machon,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vadim Fedorenko <vadim.fedorenko@linux.dev>
[ Upstream commit f8c8bd159a9bf626dd4921b7746ff481fce8c758 ]
The commit in fixes introduced a high cap for delayas U64_MAX value
while ktime_t is actually s64. This is wrong cap as it becomes negative
value and any comparison to a real delay will fail to update delay
value. Use KTIME_MAX constant as correct max cap for PCIe delay.
The issue was hit in production (a negative value is observed):
# cat /sys/class/timecard/ocp0/ts_window_adjust
-3
Fixes: aa05fe67bcd64 ("ptp: ocp: Improve PCIe delay estimation")
Signed-off-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261007203359.417270-1-vadim.fedorenko@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ptp/ptp_ocp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
index 3d26ec1f7b9ec..a8cba2f64b98a 100644
--- a/drivers/ptp/ptp_ocp.c
+++ b/drivers/ptp/ptp_ocp.c
@@ -1825,7 +1825,7 @@ ptp_ocp_watchdog(struct timer_list *t)
static void
ptp_ocp_estimate_pci_timing(struct ptp_ocp *bp)
{
- ktime_t start, end, delay = U64_MAX;
+ ktime_t start, end, delay = KTIME_MAX;
u32 ctrl;
int i;
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 271/281] net: openvswitch: validate transport header presence in set_ipv6_addr
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (269 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 270/281] ptp: ocp: fix PCIe delay estimation calculation Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 272/281] vsock: Fix memory leak in vmci_transport_recv_dgram_cb() Greg Kroah-Hartman
` (16 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+4cc63fcfb3845e149969,
Fernando Fernandez Mancera, Ilya Maximets, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera <fmancera@suse.de>
[ Upstream commit 3c6a4b11330fe424557538a98fca9f0a4c5bf313 ]
When executing IPv6 address rewrite actions on IPv6 fragments,
set_ipv6_addr() calls update_ipv6_checksum(). If parse_ipv6hdr()
processes a non-first IPv6 fragment, it sets key->ip.proto to
NEXTHDR_FRAGMENT and returns early without calling
skb_set_transport_header().
update_ipv6_checksum() unconditionally evaluates skb_transport_offset()
on entry before checking l4_proto. Because skb->transport_header is
uninitialized, this triggers a warning under CONFIG_DEBUG_NET=y although
it is completely harmless.
Fix this by returning early in update_ipv6_checksum() if l4_proto is
NEXTHDR_FRAGMENT. This avoids reading the uninitialized transport offset
for fragments while preserving the debug warning for any other protocol
where the transport header is unexpectedly missing.
See the syzbot trace:
!skb_transport_header_was_set(skb)
WARNING: ./include/linux/skbuff.h:3075 at skb_transport_header include/linux/skbuff.h:3075 [inline], CPU#1: syz-executor463/5635
WARNING: ./include/linux/skbuff.h:3075 at skb_transport_offset include/linux/skbuff.h:3250 [inline], CPU#1: syz-executor463/5635
WARNING: ./include/linux/skbuff.h:3075 at update_ipv6_checksum net/openvswitch/actions.c:361 [inline], CPU#1: syz-executor463/5635
WARNING: ./include/linux/skbuff.h:3075 at set_ipv6_addr+0x462/0x660 net/openvswitch/actions.c:399, CPU#1: syz-executor463/5635
[...]
RIP: 0010:skb_transport_header include/linux/skbuff.h:3075 [inline]
RIP: 0010:skb_transport_offset include/linux/skbuff.h:3250 [inline]
RIP: 0010:update_ipv6_checksum net/openvswitch/actions.c:361 [inline]
RIP: 0010:set_ipv6_addr+0x462/0x660 net/openvswitch/actions.c:399
[...]
Call Trace:
<TASK>
set_ipv6 net/openvswitch/actions.c:531 [inline]
do_execute_actions+0x557e/0x8600 net/openvswitch/actions.c:1366
ovs_execute_actions+0xde/0x520 net/openvswitch/actions.c:1592
ovs_packet_cmd_execute+0xb4f/0xf10 net/openvswitch/datapath.c:705
genl_family_rcv_msg_doit+0x233/0x340 net/netlink/genetlink.c:1114
genl_rcv_msg+0x614/0x7a0 net/netlink/genetlink.c:1209
netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2572
genl_rcv+0x28/0x40 net/netlink/genetlink.c:1218
netlink_unicast+0x7bd/0x940 net/netlink/af_netlink.c:1361
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1916
sock_sendmsg_nosec+0x14e/0x190 net/socket.c:800
Reported-by: syzbot+4cc63fcfb3845e149969@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4cc63fcfb3845e149969
Fixes: 3fdbd1ce11e5 ("openvswitch: add ipv6 'set' action")
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Link: https://patch.msgid.link/20261008104135.4722-1-fmancera@suse.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/openvswitch/actions.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index dc5ff859f1145..27152bca8a8ce 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -358,7 +358,12 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
__be32 addr[4], const __be32 new_addr[4])
{
- int transport_len = skb->len - skb_transport_offset(skb);
+ int transport_len;
+
+ if (l4_proto == NEXTHDR_FRAGMENT)
+ return;
+
+ transport_len = skb->len - skb_transport_offset(skb);
if (l4_proto == NEXTHDR_TCP) {
if (likely(transport_len >= sizeof(struct tcphdr)))
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 272/281] vsock: Fix memory leak in vmci_transport_recv_dgram_cb()
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (270 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 271/281] net: openvswitch: validate transport header presence in set_ipv6_addr Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 273/281] drm/vc4: Disable the V3D interrupt across runtime suspend Greg Kroah-Hartman
` (15 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefano Garzarella, Ilia Gavrilov,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilia Gavrilov <Ilia.Gavrilov@infotecs.ru>
[ Upstream commit 7c24a4e87e219072e5e106f6791146cbf3b056b3 ]
During the closure of a datagram socket, the vmci_transport_recv_dgram_cb()
function may be called, which will add the packets
to the socket's backlog; then, after the receive queue is cleared,
the __release_sock() function will move the packet back from the socket's
backlog to the receive queue, which will lead to a memory leak.
sock_close
__sock_release
__vsock_release
// take ownership by user-space
lock_sock_nested
sock_set_flag(sk, SOCK_DEAD)
vmci_transport_release
vmci_dispatch_dgs
vmci_datagram_invoke_guest_handler
vmci_transport_recv_dgram_cb
sk_receive_skb
if (!sock_owned_by_user(sk))
[...]
(!) else if sk_add_backlog()
[...]
(!) skb_queue_purge(&sk->sk_receive_queue)
release_sock
__release_sock
// move all packets from the backlog
// to the receive queue
(!) sk_backlog_rcv
vsock_queue_rcv_skb
[...]
__sock_queue_rcv_skb
if (!sock_flag(sk, SOCK_DEAD))
// Since the socket is "dead", the function will not
// be called
sk->sk_data_ready(sk)
sock_release_ownership(sk);
sock_put
Add a receive queue cleanup in the socket destructor to fix this.
syzkaller report:
unreferenced object 0xffff8880117bfb80 (size 240):
comm "irq/56-vmw_vmci", pid 205, jiffies 4295064448 (age 73.992s)
hex dump (first 32 bytes):
78 dc 26 1e 80 88 ff ff 78 dc 26 1e 80 88 ff ff x.&.....x.&.....
00 00 00 00 00 00 00 00 c0 da 26 1e 80 88 ff ff ..........&.....
backtrace:
[<ffffffff82be8d97>] __alloc_skb+0x287/0x330 net/core/skbuff.c:505
[<ffffffffa114bcbd>] vmci_transport_recv_dgram_cb+0xbd/0x210 [vmw_vsock_vmci_transport]
[<ffffffffa05072c6>] vmci_datagram_invoke_guest_handler+0x366/0x450 [vmw_vmci]
[<ffffffffa050ad75>] vmci_dispatch_dgs+0x235/0x490 [vmw_vmci]
[<ffffffffa050b025>] vmci_interrupt+0x55/0x290 [vmw_vmci]
[<ffffffff8137ad2b>] irq_thread_fn+0x8b/0x1a0 kernel/irq/manage.c:1205
[<ffffffff8137c7ae>] irq_thread+0x28e/0x530 kernel/irq/manage.c:1314
[<ffffffff81253dd6>] kthread+0x2e6/0x3a0 kernel/kthread.c:376
[<ffffffff81004392>] ret_from_fork+0x22/0x30 arch/x86/entry/entry_64.S:295
Found by InfoTeCS on behalf of Linux Verification Center
(linuxtesting.org) with Syzkaller.
Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Ilia Gavrilov <Ilia.Gavrilov@infotecs.ru>
Link: https://patch.msgid.link/20261008144046.90853-1-Ilia.Gavrilov@infotecs.ru
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/vmw_vsock/af_vsock.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 4a1dfde8414f4..f271a095996c9 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1021,6 +1021,8 @@ static void vsock_sk_destruct(struct sock *sk)
{
struct vsock_sock *vsk = vsock_sk(sk);
+ /* Socket buffers may remain in the queue in VMCI datagram mode */
+ __skb_queue_purge(&sk->sk_receive_queue);
/* Flush MSG_ZEROCOPY leftovers. */
__skb_queue_purge(&sk->sk_error_queue);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 273/281] drm/vc4: Disable the V3D interrupt across runtime suspend
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (271 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 272/281] vsock: Fix memory leak in vmci_transport_recv_dgram_cb() Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 274/281] drm/vc4: Fix binner slot allocation failing on an idle GPU Greg Kroah-Hartman
` (14 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iago Toral Quiroga, Maíra Canal,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <mcanal@igalia.com>
[ Upstream commit 6abc8e4dcfbc1d26a94c0ac037dfb3716f686b1f ]
vc4_irq_disable() masks the V3D interrupt sources and then calls
synchronize_irq() before the V3D is powered down. However, by itself,
this is not enough to quiesce the interrupt handler.
synchronize_irq() waits for handlers that have already set
IRQD_IRQ_INPROGRESS, and for irqchips reporting IRQCHIP_STATE_ACTIVE.
A GIC interrupt chip is able to mark an interrupt active as soon as a
CPU acknowledges it, so there these checks cover the whole dispatch path.
On RPi 0-3, however, the interrupt controller is ARMCTRL, which has no
active state. A CPU that has read the hwirq out of the pending register
but has not yet reached handle_level_irq() stays invisible to
synchronize_irq().
During a power transition, vc4_irq() may therefore run after the power
domain is off, where every V3D register read will return 0xdeadbeef.
0xdeadbeef has FLDONE, FRDONE and OUTOMEM set. This problem doesn't
trigger NULL pointer dereference issues only because the functions
vc4_irq_finish_bin_job() and vc4_irq_finish_render_job() return early
when there is no job pointer, but OUTOMEM is still able to schedule
vc4_overflow_mem_work() after vc4_irq_disable() has already cancelled it.
Therefore, fix the spurious interrupts by disabling the interrupt line
across the PM transition. To preserve the enable/disable balance, move
vc4_irq_install() and request the IRQ line disabled before the first
runtime resume.
Fixes: 9b6f461582e6 ("drm/vc4: v3d: Stop disabling interrupts")
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Link: https://patch.msgid.link/20260925191318.541938-1-mcanal@igalia.com
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_irq.c | 18 +++---------------
drivers/gpu/drm/vc4/vc4_v3d.c | 13 +++++++------
2 files changed, 10 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
index 7877d493d80e6..98a8db7200917 100644
--- a/drivers/gpu/drm/vc4/vc4_irq.c
+++ b/drivers/gpu/drm/vc4/vc4_irq.c
@@ -276,7 +276,7 @@ vc4_irq_disable(struct drm_device *dev)
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
/* Finish any interrupt handler still in flight. */
- synchronize_irq(vc4->irq);
+ disable_irq(vc4->irq);
cancel_work_sync(&vc4->overflow_mem_work);
}
@@ -284,7 +284,6 @@ vc4_irq_disable(struct drm_device *dev)
int vc4_irq_install(struct drm_device *dev, int irq)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
- int ret;
if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
return -ENODEV;
@@ -298,19 +297,8 @@ int vc4_irq_install(struct drm_device *dev, int irq)
init_waitqueue_head(&vc4->job_wait_queue);
INIT_WORK(&vc4->overflow_mem_work, vc4_overflow_mem_work);
- /* Clear any pending interrupts someone might have left around
- * for us.
- */
- V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
-
- ret = devm_request_irq(dev->dev, irq, vc4_irq, 0,
- dev_name(dev->dev), dev);
- if (ret)
- return ret;
-
- vc4_irq_enable(dev);
-
- return 0;
+ return devm_request_irq(dev->dev, irq, vc4_irq, IRQF_NO_AUTOEN,
+ dev_name(dev->dev), dev);
}
void vc4_irq_uninstall(struct drm_device *dev)
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 0f0c090afa6e2..8ca0f4dde04bd 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -397,6 +397,7 @@ static int vc4_v3d_runtime_resume(struct device *dev)
vc4_v3d_init_hw(&vc4->base);
vc4_irq_enable(&vc4->base);
+ enable_irq(vc4->irq);
return 0;
}
@@ -453,6 +454,12 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
return ret;
vc4->irq = ret;
+ ret = vc4_irq_install(drm, vc4->irq);
+ if (ret) {
+ drm_err(drm, "Failed to install IRQ handler\n");
+ return ret;
+ }
+
ret = devm_pm_runtime_enable(dev);
if (ret)
return ret;
@@ -474,12 +481,6 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
V3D_WRITE(V3D_BPOA, 0);
V3D_WRITE(V3D_BPOS, 0);
- ret = vc4_irq_install(drm, vc4->irq);
- if (ret) {
- drm_err(drm, "Failed to install IRQ handler\n");
- goto err_put_runtime_pm;
- }
-
pm_runtime_use_autosuspend(dev);
pm_runtime_set_autosuspend_delay(dev, 40); /* a little over 2 frames. */
pm_runtime_put_autosuspend(dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 274/281] drm/vc4: Fix binner slot allocation failing on an idle GPU
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (272 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 273/281] drm/vc4: Disable the V3D interrupt across runtime suspend Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 275/281] sched_ext: Generate qseq from a per-task counter Greg Kroah-Hartman
` (13 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iago Toral Quiroga, Maíra Canal,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <mcanal@igalia.com>
[ Upstream commit cca01232d94adcb10f7c8c5bb8ce072b045fcb58 ]
A job's binner slots are returned to bin_alloc_used by vc4_complete_exec(),
which runs from the job_done workqueue, but the seqno
vc4_v3d_get_bin_slot() waits on is incremented earlier, in the function
vc4_irq_finish_render_job(). Therefore, a waiter can wake, retry, and still
find the pool full because the worker has not run. By then, the job might
have left the render_job_list, so no seqno remains to wait on and the
allocation fails returning -ENOMEM.
This scenario can be reproduced on a Raspberry Pi 3 by using a burst of
small jobs (e.g. Piglit's `quick_gl` suite), with userspace seeing a
rejected submit for a pool about to become free.
Note that the slots are held from validation until the render completes,
so the pool can also be exhausted by jobs still queued on bin_job_list,
leaving render_job_list empty and nothing to wait on.
Release the slots from the FRDONE handler and wait on the pool instead of
on one job's seqno. This bounds the wait to the actual resource. Also, by
claiming the slot inside the wait condition, another submit is unable to
take the slot between the wakeup and the retry. vc4_complete_exec() keeps
clearing the slots for jobs that never completed, and now wakes the
waiters too.
Note that the wait takes a deadline, since the two callers need different
ones. The submit path is a user task and can be interrupted, so it waits
without one. On the other hand, vc4_overflow_mem_work() runs on a worker
and never sees a signal, so it needs a deadline. During a reset,
vc4_irq_disable() masks V3D_DRIVER_IRQS before draining the worker, and
with those masked nothing can release a slot. This deadlocks: the worker
would wait for slots that only the reset can free, while the reset waits
in cancel_work_sync() for the worker.
Fixes: 553c942f8b2c ("drm/vc4: Allow using more than 256MB of CMA memory.")
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Link: https://patch.msgid.link/20260930182204.1877361-1-mcanal@igalia.com
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_drv.h | 2 +-
drivers/gpu/drm/vc4/vc4_gem.c | 8 +++++-
drivers/gpu/drm/vc4/vc4_irq.c | 6 +++-
drivers/gpu/drm/vc4/vc4_v3d.c | 44 ++++++++++++++----------------
drivers/gpu/drm/vc4/vc4_validate.c | 2 +-
5 files changed, 34 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 0f5958c1e6b60..b0e82c2dc1bae 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -1051,7 +1051,7 @@ void vc4_plane_async_set_fb(struct drm_plane *plane,
/* vc4_v3d.c */
extern struct platform_driver vc4_v3d_driver;
extern const struct of_device_id vc4_v3d_dt_match[];
-int vc4_v3d_get_bin_slot(struct vc4_dev *vc4);
+int vc4_v3d_get_bin_slot(struct vc4_dev *vc4, long timeout);
int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used);
void vc4_v3d_bin_bo_put(struct vc4_dev *vc4);
int vc4_v3d_pm_get(struct vc4_dev *vc4);
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index e231c906709c1..6ee4bd77d4331 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -877,11 +877,17 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
drm_gem_object_put(&bo->base.base);
}
- /* Free up the allocation of any bin slots we used. */
+ /* Free up the allocation of any bin slots we used. Jobs that ran to
+ * completion had their slots released in vc4_irq_finish_render_job().
+ * Only jobs that never completed still have slots to be released here.
+ */
spin_lock_irqsave(&vc4->job_lock, irqflags);
vc4->bin_alloc_used &= ~exec->bin_slots;
spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+ /* Let anyone waiting on the binner pool retry. */
+ wake_up_all(&vc4->job_wait_queue);
+
/* Release the reference on the binner BO if needed. */
if (exec->bin_bo_used)
vc4_v3d_bin_bo_put(vc4);
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
index 98a8db7200917..dc10d3a4d90f2 100644
--- a/drivers/gpu/drm/vc4/vc4_irq.c
+++ b/drivers/gpu/drm/vc4/vc4_irq.c
@@ -74,7 +74,7 @@ vc4_overflow_mem_work(struct work_struct *work)
bo = vc4->bin_bo;
- bin_bo_slot = vc4_v3d_get_bin_slot(vc4);
+ bin_bo_slot = vc4_v3d_get_bin_slot(vc4, msecs_to_jiffies(500));
if (bin_bo_slot < 0) {
drm_err(&vc4->base, "Couldn't allocate binner overflow mem\n");
goto complete;
@@ -165,6 +165,10 @@ vc4_irq_finish_render_job(struct drm_device *dev)
trace_vc4_rcl_end_irq(dev, exec->seqno);
vc4->finished_seqno++;
+
+ vc4->bin_alloc_used &= ~exec->bin_slots;
+ exec->bin_slots = 0;
+
list_move_tail(&exec->head, &vc4->job_done_list);
nextbin = vc4_first_bin_job(vc4);
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 8ca0f4dde04bd..6844e8f3948cf 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -173,46 +173,42 @@ static void vc4_v3d_init_hw(struct drm_device *dev)
V3D_WRITE(V3D_VPMBASE, 0);
}
-int vc4_v3d_get_bin_slot(struct vc4_dev *vc4)
+static int bin_slot_try_alloc(struct vc4_dev *vc4)
{
- struct drm_device *dev = &vc4->base;
- unsigned long irqflags;
int slot;
- uint64_t seqno = 0;
- struct vc4_exec_info *exec;
- if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
- return -ENODEV;
+ guard(spinlock_irqsave)(&vc4->job_lock);
-try_again:
- spin_lock_irqsave(&vc4->job_lock, irqflags);
slot = ffs(~vc4->bin_alloc_used);
if (slot != 0) {
/* Switch from ffs() bit index to a 0-based index. */
slot--;
vc4->bin_alloc_used |= BIT(slot);
- spin_unlock_irqrestore(&vc4->job_lock, irqflags);
- return slot;
+ } else {
+ slot = -ENOMEM;
}
- /* Couldn't find an open slot. Wait for render to complete
- * and try again.
- */
- exec = vc4_last_render_job(vc4);
- if (exec)
- seqno = exec->seqno;
- spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+ return slot;
+}
- if (seqno) {
- int ret = vc4_wait_for_seqno(dev, seqno, ~0ull, true);
+int vc4_v3d_get_bin_slot(struct vc4_dev *vc4, long timeout)
+{
+ int slot;
+ long ret;
- if (ret == 0)
- goto try_again;
+ if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4))
+ return -ENODEV;
+ /* If the pool is full, wait for a job to release its slots. */
+ ret = wait_event_interruptible_timeout(vc4->job_wait_queue,
+ (slot = bin_slot_try_alloc(vc4)) >= 0,
+ timeout);
+ if (ret < 0)
return ret;
- }
+ if (ret == 0)
+ return -ENOMEM;
- return -ENOMEM;
+ return slot;
}
/*
diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index d2a65c968b1f9..565227657b43b 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -402,7 +402,7 @@ validate_tile_binning_config(VALIDATE_ARGS)
return -EINVAL;
}
- bin_slot = vc4_v3d_get_bin_slot(vc4);
+ bin_slot = vc4_v3d_get_bin_slot(vc4, MAX_SCHEDULE_TIMEOUT);
if (bin_slot < 0) {
if (bin_slot != -EINTR && bin_slot != -ERESTARTSYS) {
drm_err(dev, "Failed to allocate binner memory: %d\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 291+ messages in thread* [PATCH 7.2 275/281] sched_ext: Generate qseq from a per-task counter
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (273 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 274/281] drm/vc4: Fix binner slot allocation failing on an idle GPU Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 276/281] sched_ext: Call ops.dequeue() when a task arrives on a remote local DSQ Greg Kroah-Hartman
` (12 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kuba Piecuch, Tejun Heo
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuba Piecuch <jpiecuch@google.com>
commit e6ac89b8b1c12e9104df45a14a26e2dfa96ded06 upstream.
finish_dispatch() uses the qseq embedded in p->scx.ops_state to tell
whether the QUEUED instance of a task it's about to claim is the one
scx_bpf_dsq_insert() saw. qseq is generated from rq->scx.ops_qseq, but
the counters of different rqs are independent, so if a task is dequeued
and re-enqueued on a different rq between scx_bpf_dsq_insert() and
finish_dispatch(), the new QUEUED instance can end up with the same
qseq as the old one:
CPU X CPU Z
----- -----
enqueue p on rq A, qseq = N
ops.dispatch()
scx_bpf_dsq_insert(p)
records qseq N
sched_setaffinity(p)
dequeue p from rq A
enqueue p on rq B, qseq = N
finish_dispatch(p, N)
qseq matches, p is claimed
The claim itself is still atomic so the core stays consistent, but an
insert issued for a previous QUEUED instance gets applied to a new one
which the BPF scheduler has just received through ops.enqueue(). This
breaks the guarantee that dispatches targeting a stale instance are
ignored.
Generate qseq from a per-task counter, p->scx.ops_qseq, instead so that
consecutive QUEUED instances of a task never share a qseq regardless of
which rq they're on. The counter is only updated in
scx_do_enqueue_task() with the task's rq locked, so no additional
synchronization is needed, and it fits in an existing hole in struct
sched_ext_entity on 64bit. Remove the now unused rq->scx.ops_qseq.
Never generate qseq 0. NONE and DISPATCHING don't carry a qseq, so
scx_bpf_dsq_insert() on a task in either state records 0. With a
per-task counter, every task's first QUEUED instance would otherwise get
qseq 0 and could be claimed by such an insert. Wrap the counter where
the QSEQ field wraps so that it can't reach a value that shifts to 0 on
32bit either.
Fixes: f0e1a0643a59 ("sched_ext: Implement BPF extensible scheduler class")
Cc: stable@vger.kernel.org # v6.12+
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Kuba Piecuch <jpiecuch@google.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
[ jpiecuch: 7.2.y lacks runnable_cpu in sched_ext_entity, so ops_qseq goes
after selected_cpu; adjust context in scx_rq and the dump_line() CPU line ]
Signed-off-by: Kuba Piecuch <jpiecuch@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/sched/ext.h | 1 +
kernel/sched/ext/ext.c | 15 ++++++++++-----
kernel/sched/ext/internal.h | 5 +++++
kernel/sched/sched.h | 1 -
4 files changed, 16 insertions(+), 6 deletions(-)
--- a/include/linux/sched/ext.h
+++ b/include/linux/sched/ext.h
@@ -198,6 +198,7 @@ struct sched_ext_entity {
s32 sticky_cpu;
s32 holding_cpu;
s32 selected_cpu;
+ u32 ops_qseq; /* protected by rq lock */
struct task_struct *kf_tasks[2]; /* see SCX_CALL_OP_TASK() */
struct list_head runnable_node; /* rq->scx.runnable_list */
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -1953,8 +1953,14 @@ static void do_enqueue_task(struct rq *r
if (unlikely(!SCX_HAS_OP(sch, enqueue)))
goto global;
- /* DSQ bypass didn't trigger, enqueue on the BPF scheduler */
- qseq = rq->scx.ops_qseq++ << SCX_OPSS_QSEQ_SHIFT;
+ /*
+ * DSQ bypass didn't trigger, enqueue on the BPF scheduler. Wrap the
+ * per-task qseq counter where the QSEQ field wraps and skip 0, which is
+ * what scx_bpf_dsq_insert() records for a task in NONE or DISPATCHING.
+ */
+ p->scx.ops_qseq = ((p->scx.ops_qseq + 1) &
+ (SCX_OPSS_QSEQ_MASK >> SCX_OPSS_QSEQ_SHIFT)) ?: 1;
+ qseq = (unsigned long)p->scx.ops_qseq << SCX_OPSS_QSEQ_SHIFT;
WARN_ON_ONCE(atomic_long_read(&p->scx.ops_state) != SCX_OPSS_NONE);
atomic_long_set(&p->scx.ops_state, SCX_OPSS_QUEUEING | qseq);
@@ -6690,10 +6696,9 @@ static void scx_dump_cpu(struct scx_sche
seq_buf_init(&ns, buf, avail);
dump_newline(&ns);
- dump_line(&ns, "CPU %-4d: nr_run=%u flags=0x%x cpu_rel=%d ops_qseq=%lu ksync=%lu",
+ dump_line(&ns, "CPU %-4d: nr_run=%u flags=0x%x cpu_rel=%d ksync=%lu",
cpu, rq->scx.nr_running, rq->scx.flags,
- rq->scx.cpu_released, rq->scx.ops_qseq,
- rq->scx.kick_sync);
+ rq->scx.cpu_released, rq->scx.kick_sync);
dump_line(&ns, " curr=%s[%d] class=%ps",
rq->curr->comm, rq->curr->pid,
rq->curr->sched_class);
--- a/kernel/sched/ext/internal.h
+++ b/kernel/sched/ext/internal.h
@@ -1508,6 +1508,11 @@ enum scx_ops_state {
* dequeue/requeue, the dispatcher can tell whether it still has a claim
* on the task being dispatched.
*
+ * QSEQ is generated from the per-task p->scx.ops_qseq counter so that
+ * it doesn't repeat across QUEUED instances of the same task even if
+ * the task moves between rqs. 0 is never used as a valid QSEQ since
+ * NONE and DISPATCHING map to this value.
+ *
* As some 32bit archs can't do 64bit store_release/load_acquire,
* p->scx.ops_state is atomic_long_t which leaves 30 bits for QSEQ on
* 32bit machines. The dispatch race window QSEQ protects is very narrow
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -795,7 +795,6 @@ struct scx_rq {
struct scx_dispatch_q local_dsq;
struct list_head runnable_list; /* runnable tasks on this rq */
struct list_head ddsp_deferred_locals; /* deferred ddsps from enq */
- unsigned long ops_qseq;
u64 extra_enq_flags; /* see move_task_to_local_dsq() */
u32 nr_running;
u32 cpuperf_target; /* [0, SCHED_CAPACITY_SCALE] */
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 276/281] sched_ext: Call ops.dequeue() when a task arrives on a remote local DSQ
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (274 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 275/281] sched_ext: Generate qseq from a per-task counter Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 277/281] drm/amd/display: Dont replace a sink mode that shares the native totals Greg Kroah-Hartman
` (11 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Andrea Righi, Kuba Piecuch,
Tejun Heo
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuba Piecuch <jpiecuch@google.com>
commit af701b8d3238b9eb7cd450b0491300452c700bf5 upstream.
When a task in the BPF scheduler's custody is moved to another CPU's
local DSQ, ops.dequeue() is only called once the task is picked for
execution, from set_next_task_scx() with SCX_DEQ_CORE_SCHED_EXEC, even
though no core-sched pick took place. It should instead be called
without flags when the task is inserted into the destination DSQ, as it
is for same-rq dispatches.
move_remote_task_to_local_dsq() sets p->scx.sticky_cpu across the
migration so that deactivate_task() on the source rq doesn't end custody.
Since commit b75aaea24c9f ("sched_ext: Properly mark SCX-internal
migrations via sticky_cpu"), enqueue_task_scx() only clears it after
inserting the task, so task_leave_custody() still sees the migration in
progress and skips the custody exit.
Clear p->scx.sticky_cpu as soon as enqueue_task_scx() has read it, as
was done before that commit. The source side is unaffected.
Fixes: ebf1ccff79c4 ("sched_ext: Fix ops.dequeue() semantics")
Cc: stable@vger.kernel.org # 7.1.x: 18d62044cda7: sched_ext: Preserve rq tracking across local DSQ dispatch
Cc: stable@vger.kernel.org # 7.1.x
Reviewed-by: Andrea Righi <arighi@nvidia.com>
Assisted-by: Claude:claude-opus-5.5
Signed-off-by: Kuba Piecuch <jpiecuch@google.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
(cherry picked from commit af701b8d3238b9eb7cd450b0491300452c700bf5)
[ jpiecuch: resolved context conflict, 7.2.y still names the function
do_enqueue_task() rather than scx_do_enqueue_task() ]
Signed-off-by: Kuba Piecuch <jpiecuch@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/sched/ext/ext.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -2051,6 +2051,13 @@ static void enqueue_task_scx(struct rq *
u64 enq_flags = core_enq_flags | rq->scx.extra_enq_flags;
/*
+ * An SCX-internal migration ends on arrival. Clear sticky_cpu so @p can
+ * leave custody when inserted into the destination DSQ.
+ */
+ if (sticky_cpu >= 0)
+ p->scx.sticky_cpu = -1;
+
+ /*
* SCX_RQ_IN_WAKEUP promises a task_woken_scx() call once this enqueue
* returns. Only the core's wakeup path delivers one. The flags stashed
* for a remote activation may carry the wakeup bit without it.
@@ -2088,9 +2095,6 @@ static void enqueue_task_scx(struct rq *
dl_server_start(&rq->ext_server);
do_enqueue_task(rq, p, enq_flags, sticky_cpu);
-
- if (sticky_cpu >= 0)
- p->scx.sticky_cpu = -1;
out:
rq->scx.flags &= ~SCX_RQ_IN_WAKEUP;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 277/281] drm/amd/display: Dont replace a sink mode that shares the native totals
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (275 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 276/281] sched_ext: Call ops.dequeue() when a task arrives on a remote local DSQ Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 278/281] io_uring/memmap: account the pages a compound region really uses Greg Kroah-Hartman
` (10 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Adrian Betschart, Dan Wheeler,
Roman Li, Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Betschart <adrian.betschart@cinemaone.ch>
commit 54c998c55fc9cbc391b350d67b86e0c2a0748f1a upstream.
decide_crtc_timing_for_drm_display_mode() copies the native mode's CRTC
timing into the requested mode when clock, htotal and vtotal match.
That is meant for the modes amdgpu inserts itself:
amdgpu_dm_create_common_mode() duplicates the native mode and changes
only hdisplay and vdisplay, so those are sent with the native timing
and scaled.
A sink can also offer a real mode with the same clock and totals as
its native mode. CTA-861 VIC 102 (4096x2160@60) and VIC 97
(3840x2160@60) both use 594 MHz and 4400x2250. With 3840x2160@60 as
the preferred mode, a 4096x2160@60 request goes out with the 3840x2160
timing and the framebuffer scaled into it (dst 3840x2025 at y=67),
while the AVI InfoFrame still carries VIC 102. A JVC projector then
reports 3840x2160 and shows a corrupted right edge. 4096x2160@24,
whose totals differ, is sent and displayed correctly.
Inserted modes keep the native sync positions; a real mode with its
own active width does not. Compare those too, so only inserted modes
are patched.
Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)")
Signed-off-by: Adrian Betschart <adrian.betschart@cinemaone.ch>
Assisted-by: Claude-Code:claude-opus-5-5
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Reviewed-by: Roman Li <roman.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 22f9a2da101c37f821cd00954f81dc598754f4d5)
Cc: stable@vger.kernel.org
[ Adrian: this tree keeps the function in amdgpu_dm.c; dropped the KUnit
test, its file does not exist here. ]
Signed-off-by: Adrian Betschart <adrian.betschart@cinemaone.ch>
Assisted-by: Claude-Code:claude-opus-5-5
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7260,10 +7260,15 @@ decide_crtc_timing_for_drm_display_mode(
const struct drm_display_mode *native_mode,
bool scale_enabled)
{
+ /* Inserted modes copy the native sync; a sink mode with equal totals may not */
if (scale_enabled || (
native_mode->clock == drm_mode->clock &&
native_mode->htotal == drm_mode->htotal &&
- native_mode->vtotal == drm_mode->vtotal)) {
+ native_mode->vtotal == drm_mode->vtotal &&
+ native_mode->hsync_start == drm_mode->hsync_start &&
+ native_mode->hsync_end == drm_mode->hsync_end &&
+ native_mode->vsync_start == drm_mode->vsync_start &&
+ native_mode->vsync_end == drm_mode->vsync_end)) {
if (native_mode->crtc_clock)
copy_crtc_timing_for_drm_display_mode(native_mode, drm_mode);
} else {
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 278/281] io_uring/memmap: account the pages a compound region really uses
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (276 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 277/281] drm/amd/display: Dont replace a sink mode that shares the native totals Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 279/281] io_uring: do not charge the SQ/CQ rings to RLIMIT_MEMLOCK Greg Kroah-Hartman
` (9 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ali Ahmet Memis, Jens Axboe,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memis <ali@iusegentoo.com>
[ Upstream commit f12f0234cc14886bcfd53ffb7c8df4216dad51f1 ]
io_mem_alloc_compound() allocates get_order(size) pages, which rounds a
region size that is not a power of two up to the next order. The pages
past the region are part of the same allocation and cannot be used for
anything else, but io_create_region() accounts reg->size >> PAGE_SHIFT,
so they are never charged against RLIMIT_MEMLOCK. For a ring with 4096
SQ entries and the default CQ size the region is 37 pages while the
allocation is 64.
Account the tail pages together with the region, and fall back to the
exact sized bulk allocation when they do not fit the limit, so a user
close to their limit still gets the region rather than an error.
io_free_region() gives the same amount back, the compound case being the
one that set IO_REGION_F_SINGLE_REF.
Counting how many 4096 entry rings an unprivileged user can create under
a given RLIMIT_MEMLOCK, before and after:
limit (pages) before after
256 2 2
300 2 2
350 3 2
400 3 3
512 5 4
Five rings under a 512 page limit really pin 640 pages.
Fixes: dfbbfbf19187 ("io_uring: introduce concept of memory regions")
Link: https://lore.kernel.org/all/87ik5ncj8d.fsf@mailhost.krisman.be/
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Link: https://patch.msgid.link/20260806180044.275543-1-ali@iusegentoo.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Stable-dep-of: b59cabf9b4ac ("io_uring: do not charge the SQ/CQ rings to RLIMIT_MEMLOCK")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/memmap.c | 37 ++++++++++++++++++++++++++++++-------
1 file changed, 30 insertions(+), 7 deletions(-)
--- a/io_uring/memmap.c
+++ b/io_uring/memmap.c
@@ -16,8 +16,10 @@
#include "zcrx.h"
static bool io_mem_alloc_compound(struct page **pages, int nr_pages,
- size_t size, gfp_t gfp)
+ size_t size, gfp_t gfp,
+ struct user_struct *user)
{
+ unsigned long nr_compound, extra;
struct page *page;
int i, order;
@@ -27,9 +29,22 @@ static bool io_mem_alloc_compound(struct
else if (order)
gfp |= __GFP_COMP;
+ /*
+ * get_order() rounds a non power of two size up, so the allocation
+ * can hold more pages than the region exposes. Account those too,
+ * and leave the compound allocation alone if they do not fit.
+ */
+ nr_compound = 1UL << order;
+ extra = nr_compound - nr_pages;
+ if (extra && user && __io_account_mem(user, extra))
+ return false;
+
page = alloc_pages(gfp, order);
- if (!page)
+ if (!page) {
+ if (extra && user)
+ __io_unaccount_mem(user, extra);
return false;
+ }
for (i = 0; i < nr_pages; i++)
pages[i] = page + i;
@@ -105,8 +120,15 @@ void io_free_region(struct user_struct *
}
if ((mr->flags & IO_REGION_F_VMAP) && mr->ptr)
vunmap(mr->ptr);
- if (mr->nr_pages && user)
- __io_unaccount_mem(user, mr->nr_pages);
+ if (mr->nr_pages && user) {
+ unsigned long nr_accounted = mr->nr_pages;
+
+ /* a compound region was accounted for the whole allocation */
+ if (mr->flags & IO_REGION_F_SINGLE_REF)
+ nr_accounted = 1UL << get_order(io_region_size(mr));
+
+ __io_unaccount_mem(user, nr_accounted);
+ }
memset(mr, 0, sizeof(*mr));
}
@@ -151,7 +173,8 @@ static int io_region_pin_pages(struct io
static int io_region_allocate_pages(struct io_mapped_region *mr,
struct io_uring_region_desc *reg,
- unsigned long mmap_offset)
+ unsigned long mmap_offset,
+ struct user_struct *user)
{
gfp_t gfp = GFP_KERNEL_ACCOUNT | __GFP_ZERO | __GFP_NOWARN;
size_t size = io_region_size(mr);
@@ -162,7 +185,7 @@ static int io_region_allocate_pages(stru
if (!pages)
return -ENOMEM;
- if (io_mem_alloc_compound(pages, mr->nr_pages, size, gfp)) {
+ if (io_mem_alloc_compound(pages, mr->nr_pages, size, gfp, user)) {
mr->flags |= IO_REGION_F_SINGLE_REF;
goto done;
}
@@ -217,7 +240,7 @@ int io_create_region(struct io_ring_ctx
if (reg->flags & IORING_MEM_REGION_TYPE_USER)
ret = io_region_pin_pages(mr, reg);
else
- ret = io_region_allocate_pages(mr, reg, mmap_offset);
+ ret = io_region_allocate_pages(mr, reg, mmap_offset, ctx->user);
if (ret)
goto out_free;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 279/281] io_uring: do not charge the SQ/CQ rings to RLIMIT_MEMLOCK
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (277 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 278/281] io_uring/memmap: account the pages a compound region really uses Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 280/281] io_uring/kbuf: dont charge provided buffer " Greg Kroah-Hartman
` (8 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hengyu Liang, Jens Axboe,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengyu Liang <hengyul@cs.unc.edu>
[ Upstream commit b59cabf9b4acb65f3f9968087ca0e18010d85076 ]
Commit 8078486e1d53 ("io_uring: use region api for SQ") and commit
81a4058e0cd0 ("io_uring: use region api for CQ") made io_uring_setup()
allocate the rings with io_create_region().
However, io_create_region() charges the memory to RLIMIT_MEMLOCK, and
the rings had been exempt from that limit since commit 26bfa89e25f4
("io_uring: place ring SQ/CQ arrays under memcg memory limits"). As of
now, a user without CAP_IPC_LOCK gets ENOMEM from io_uring_setup() when
their rings exceed the limit, which is 8 MiB by default. PostgreSQL
developers have already hit this in their io_uring tests [1].
The issue can be reproduced with a simple liburing program, run as an
unprivileged user:
#include <liburing.h>
#include <stdio.h>
int main(void)
{
static struct io_uring ring[64];
int i;
for (i = 0; i < 64; i++)
if (io_uring_queue_init(4096, &ring[i], 0) < 0)
break;
printf("%d rings\n", i);
return 0;
}
Before those commits (v6.13), it prints "64 rings". After those commits
(v6.14), it prints "21 rings".
This patch makes io_create_region() take the user to charge, and passes
no user for the SQ/CQ rings.
Link: https://www.postgresql.org/message-id/flat/667f7dcf-404b-4898-a426-57ca6e0617f6@gmail.com [1]
Fixes: 8078486e1d53 ("io_uring: use region api for SQ")
Fixes: 81a4058e0cd0 ("io_uring: use region api for CQ")
Cc: stable@vger.kernel.org
Signed-off-by: Hengyu Liang <hengyul@cs.unc.edu>
Link: https://lore.kernel.org/io-uring/20261006125732.3425762-1-hengyul@cs.unc.edu/
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/io_uring.c | 10 ++++++----
io_uring/kbuf.c | 2 +-
io_uring/memmap.c | 10 +++++-----
io_uring/memmap.h | 2 +-
io_uring/register.c | 12 +++++++-----
io_uring/zcrx.c | 2 +-
6 files changed, 21 insertions(+), 17 deletions(-)
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -2077,8 +2077,9 @@ int io_submit_sqes(struct io_ring_ctx *c
static void io_rings_free(struct io_ring_ctx *ctx)
{
- io_free_region(ctx->user, &ctx->sq_region);
- io_free_region(ctx->user, &ctx->ring_region);
+ /* ring memory is not charged to RLIMIT_MEMLOCK, hence no user */
+ io_free_region(NULL, &ctx->sq_region);
+ io_free_region(NULL, &ctx->ring_region);
ctx->rings = NULL;
RCU_INIT_POINTER(ctx->rings_rcu, NULL);
ctx->sq_sqes = NULL;
@@ -2742,7 +2743,8 @@ static __cold int io_allocate_scq_urings
rd.user_addr = p->cq_off.user_addr;
rd.flags |= IORING_MEM_REGION_TYPE_USER;
}
- ret = io_create_region(ctx, &ctx->ring_region, &rd, IORING_OFF_CQ_RING);
+ /* ring memory is not charged to RLIMIT_MEMLOCK, hence no user */
+ ret = io_create_region(NULL, &ctx->ring_region, &rd, IORING_OFF_CQ_RING);
if (ret)
return ret;
ctx->rings = rings = io_region_get_ptr(&ctx->ring_region);
@@ -2756,7 +2758,7 @@ static __cold int io_allocate_scq_urings
rd.user_addr = p->sq_off.user_addr;
rd.flags |= IORING_MEM_REGION_TYPE_USER;
}
- ret = io_create_region(ctx, &ctx->sq_region, &rd, IORING_OFF_SQES);
+ ret = io_create_region(NULL, &ctx->sq_region, &rd, IORING_OFF_SQES);
if (ret) {
io_rings_free(ctx);
return ret;
--- a/io_uring/kbuf.c
+++ b/io_uring/kbuf.c
@@ -675,7 +675,7 @@ int io_register_pbuf_ring(struct io_ring
rd.user_addr = reg.ring_addr;
rd.flags |= IORING_MEM_REGION_TYPE_USER;
}
- ret = io_create_region(ctx, &bl->region, &rd, mmap_offset);
+ ret = io_create_region(ctx->user, &bl->region, &rd, mmap_offset);
if (ret)
goto fail;
br = io_region_get_ptr(&bl->region);
--- a/io_uring/memmap.c
+++ b/io_uring/memmap.c
@@ -204,7 +204,7 @@ done:
return 0;
}
-int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
+int io_create_region(struct user_struct *user, struct io_mapped_region *mr,
struct io_uring_region_desc *reg,
unsigned long mmap_offset)
{
@@ -230,8 +230,8 @@ int io_create_region(struct io_ring_ctx
return -EOVERFLOW;
nr_pages = reg->size >> PAGE_SHIFT;
- if (ctx->user) {
- ret = __io_account_mem(ctx->user, nr_pages);
+ if (user) {
+ ret = __io_account_mem(user, nr_pages);
if (ret)
return ret;
}
@@ -240,7 +240,7 @@ int io_create_region(struct io_ring_ctx
if (reg->flags & IORING_MEM_REGION_TYPE_USER)
ret = io_region_pin_pages(mr, reg);
else
- ret = io_region_allocate_pages(mr, reg, mmap_offset, ctx->user);
+ ret = io_region_allocate_pages(mr, reg, mmap_offset, user);
if (ret)
goto out_free;
@@ -249,7 +249,7 @@ int io_create_region(struct io_ring_ctx
goto out_free;
return 0;
out_free:
- io_free_region(ctx->user, mr);
+ io_free_region(user, mr);
return ret;
}
--- a/io_uring/memmap.h
+++ b/io_uring/memmap.h
@@ -18,7 +18,7 @@ unsigned long io_uring_get_unmapped_area
int io_uring_mmap(struct file *file, struct vm_area_struct *vma);
void io_free_region(struct user_struct *user, struct io_mapped_region *mr);
-int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
+int io_create_region(struct user_struct *user, struct io_mapped_region *mr,
struct io_uring_region_desc *reg,
unsigned long mmap_offset);
--- a/io_uring/register.c
+++ b/io_uring/register.c
@@ -480,8 +480,9 @@ struct io_ring_ctx_rings {
static void io_register_free_rings(struct io_ring_ctx *ctx,
struct io_ring_ctx_rings *r)
{
- io_free_region(ctx->user, &r->sq_region);
- io_free_region(ctx->user, &r->ring_region);
+ /* ring memory is not charged to RLIMIT_MEMLOCK, hence no user */
+ io_free_region(NULL, &r->sq_region);
+ io_free_region(NULL, &r->ring_region);
}
#define swap_old(ctx, o, n, field) \
@@ -529,7 +530,7 @@ static int io_register_resize_rings(stru
rd.user_addr = p->cq_off.user_addr;
rd.flags |= IORING_MEM_REGION_TYPE_USER;
}
- ret = io_create_region(ctx, &n.ring_region, &rd, IORING_OFF_CQ_RING);
+ ret = io_create_region(NULL, &n.ring_region, &rd, IORING_OFF_CQ_RING);
if (ret)
return ret;
@@ -559,7 +560,7 @@ static int io_register_resize_rings(stru
rd.user_addr = p->sq_off.user_addr;
rd.flags |= IORING_MEM_REGION_TYPE_USER;
}
- ret = io_create_region(ctx, &n.sq_region, &rd, IORING_OFF_SQES);
+ ret = io_create_region(NULL, &n.sq_region, &rd, IORING_OFF_SQES);
if (ret) {
io_register_free_rings(ctx, &n);
return ret;
@@ -730,7 +731,8 @@ static int io_register_mem_region(struct
!(ctx->flags & IORING_SETUP_R_DISABLED))
return -EINVAL;
- ret = io_create_region(ctx, ®ion, &rd, IORING_MAP_OFF_PARAM_REGION);
+ ret = io_create_region(ctx->user, ®ion, &rd,
+ IORING_MAP_OFF_PARAM_REGION);
if (ret)
return ret;
if (copy_to_user(rd_uptr, &rd, sizeof(rd))) {
--- a/io_uring/zcrx.c
+++ b/io_uring/zcrx.c
@@ -398,7 +398,7 @@ static int io_allocate_rbuf_ring(struct
mmap_offset = IORING_MAP_OFF_ZCRX_REGION;
mmap_offset += (u64)id << IORING_OFF_ZCRX_SHIFT;
- ret = io_create_region(ctx, &ifq->rq_region, rd, mmap_offset);
+ ret = io_create_region(ctx->user, &ifq->rq_region, rd, mmap_offset);
if (ret < 0)
return ret;
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 280/281] io_uring/kbuf: dont charge provided buffer rings to RLIMIT_MEMLOCK
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (278 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 279/281] io_uring: do not charge the SQ/CQ rings to RLIMIT_MEMLOCK Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 11:39 ` [PATCH 7.2 281/281] mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge Greg Kroah-Hartman
` (7 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hengyu Liang, Jens Axboe,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <axboe@kernel.dk>
[ Upstream commit cde56daf4b93f474dc256dbcc5205035223ae6f5 ]
Just like with the SQ and CQ rings, the provided buffer rings were also
not charged against the memlock limit prior to the below mentioned
commit. Restore that behavior.
Fixes: ef62de3c4ad5 ("io_uring/kbuf: use region api for pbuf rings")
Reported-by: Hengyu Liang <hengyul@cs.unc.edu>
Cc: stable@vger.kernel.org
Tested-by: Hengyu Liang <hengyul@cs.unc.edu>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Depends on <20261012153857.1014795-1-sashal@kernel.org>
io_uring/kbuf.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/io_uring/kbuf.c
+++ b/io_uring/kbuf.c
@@ -458,7 +458,7 @@ static int io_remove_buffers_legacy(stru
static void io_put_bl(struct io_ring_ctx *ctx, struct io_buffer_list *bl)
{
if (bl->flags & IOBL_BUF_RING)
- io_free_region(ctx->user, &bl->region);
+ io_free_region(NULL, &bl->region);
else
io_remove_buffers_legacy(ctx, bl, -1U);
@@ -675,7 +675,7 @@ int io_register_pbuf_ring(struct io_ring
rd.user_addr = reg.ring_addr;
rd.flags |= IORING_MEM_REGION_TYPE_USER;
}
- ret = io_create_region(ctx->user, &bl->region, &rd, mmap_offset);
+ ret = io_create_region(NULL, &bl->region, &rd, mmap_offset);
if (ret)
goto fail;
br = io_region_get_ptr(&bl->region);
@@ -708,7 +708,7 @@ int io_register_pbuf_ring(struct io_ring
if (!ret)
return 0;
fail:
- io_free_region(ctx->user, &bl->region);
+ io_free_region(NULL, &bl->region);
kfree(bl);
return ret;
}
^ permalink raw reply [flat|nested] 291+ messages in thread* [PATCH 7.2 281/281] mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (279 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 280/281] io_uring/kbuf: dont charge provided buffer " Greg Kroah-Hartman
@ 2026-10-13 11:39 ` Greg Kroah-Hartman
2026-10-13 13:23 ` [PATCH 7.2 000/281] 7.2.11-rc1 review Pavel Machek
` (6 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-13 11:39 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Andrew Morton,
Pedro Falcato, Kiryl Shutsemau (Meta), Jose A. Perez de Azpillaga,
Anirudh Srinivasan, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Brian Geffon, Minchan Kim, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
[ Upstream commit 838bb60dc21553e32df90f2f3bac5b905376e7aa ]
Patch series "mm/mremap: fix two issues with MREMAP_DONTUNMAP", v2.
The MREMAP_DONTUNMAP feature is highly unusual in that it permits mremap()
operations that keep the original VMA in place.
Historically this has led to a lot of bugs where non-obvious interactions
occur between existing mremap() operations and the original VMA.
Commit 397432cab17b ("mm/mremap: account mm->locked_vm correctly for
MREMAP_DONTUNMAP") fixed an accidentally introduced bug around
mm->locked_vm accounting, but this wasn't the only issue.
And thus history repeats itself, as it turns out that mm->locked_vm
accounting is broken by MREMAP_DONTUNMAP yet again by two further cases,
and has been broken ever since the feature was introduced.
Both relate to the fact that VMA_LOCKED_BIT is cleared on the source VMA
(it has to be as all page tables are moved):
1. If an unfaulted VMA_LOCKONFAULT_BIT anonymous VMA self-merges it
clears the VMA_LOCKED_BIT flag and permanently leaks mm->locked_vm
pages.
2. If a partial mremap() is performed on a locked VMA there is a leak equal
to the number of pages not copied.
(Both for MREMAP_DONTUNMAP operations only)
Both issues can be fixed by treating the source range as distinct from the
destination range, which is the definition of what MREMAP_DONTUNMAP does
so is appropriate.
In case 1, simply disallow the self-merge, keeping adjacent source and
destination VMAs distinct.
In case 2, split the source range ahead of time if the VMA is mlock()'d,
so accounting is always correct.
Both changes were tested locally and confirmed to fix the issues.
For the purposes of a backport, the fixes are kept distinct, a follow-up
series can add self-tests.
This patch (of 2):
The MREMAP_DONTUNMAP feature is highly unusual in that it permits mremap()
operations that keep the original VMA in place.
Historically this has led to a lot of bugs where non-obvious interactions
occur between existing mremap() operations and the original VMA.
Fix another of these - self-merge.
Self-merge occurs when a VMA is moved in front of or behind itself and the
attributes of the VMA permit such a merge.
Practically this can only happen for unfaulted anonymous VMAs due to the
page offset equality requirement for merge:
|------------|
| |
| v
|...........||-----------||...........|
| || unfaulted || |
|...........||-----------||...........|
^ |
| |
|------------|
This becomes problematic if the VMA is configured by the user to
mlock-on-fault, i.e. the VMA_LOCKED_BIT, VMA_LOCKONFAULT_BIT VMA flags are
set.
MREMAP_DONTUNMAP clears mlock flags for the source VMA and maintains them
for the destination VMA.
Self-merge makes this impossible (there is only one VMA) and incorrectly
clears the destination VMA's mlock flags.
This causes a leak in mm->locked_vm as clearing this flag does not
decrement the counter and the VMA no longer has VMA_LOCKED_BIT set so it
is not decremented on unmap.
Resolve this by simply disallowing a self-merge in this case - the source
and destination VMAs are kept distinct and then are able to have distinct
mlock() flags.
Update dontunmap_complete() to make the now-redundant self-merge check a
VM_WARN_ON_ONCE() instead to guard against future regressions.
Also update the VMA userland tests to reflect the change.
Link: https://lore.kernel.org/20260930-fix-dontunmap-partial-self-merge-v2-0-f388985a0f0a@kernel.org
Link: https://lore.kernel.org/20260930-fix-dontunmap-partial-self-merge-v2-1-f388985a0f0a@kernel.org
Fixes: e346b3813067 ("mm/mremap: add MREMAP_DONTUNMAP to mremap()")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Tested-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: Brian Geffon <bgeffon@google.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: <stable@vger.kernel.org>
[ sashal: Adapted can_self_merge logic to the inverse faulted_in_anon_vma flag. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
mm/mremap.c | 8 ++++++--
mm/vma.c | 17 ++++++++++++++++-
mm/vma.h | 2 +-
tools/testing/vma/tests/vma.c | 4 ++--
4 files changed, 25 insertions(+), 6 deletions(-)
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -1295,7 +1295,8 @@ static int copy_vma_and_data(struct vma_
PAGETABLE_MOVE(pmc, NULL, NULL, vrm->addr, vrm->new_addr, vrm->old_len);
new_vma = copy_vma(&vma, vrm->new_addr, vrm->new_len, new_pgoff,
- &pmc.need_rmap_locks);
+ &pmc.need_rmap_locks,
+ vrm->flags & MREMAP_DONTUNMAP);
if (!new_vma) {
vrm_uncharge(vrm);
*new_vma_ptr = NULL;
@@ -1355,6 +1356,9 @@ static void dontunmap_complete(struct vm
unsigned long old_start = vma->vm_start;
unsigned long old_end = vma->vm_end;
+ /* Self-merge is disallowed. */
+ VM_WARN_ON_ONCE(new_vma == vma);
+
/* We always clear VM_LOCKED[ONFAULT] on the old VMA. */
vm_flags_clear(vma, VM_LOCKED_MASK);
@@ -1362,7 +1366,7 @@ static void dontunmap_complete(struct vm
* anon_vma links of the old vma is no longer needed after its page
* table has been moved.
*/
- if (new_vma != vma && start == old_start && end == old_end) {
+ if (start == old_start && end == old_end) {
const pgoff_t pgoff_unfaulted = vma->vm_start >> PAGE_SHIFT;
unlink_anon_vmas(vma);
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -1863,7 +1863,7 @@ static int vma_link(struct mm_struct *mm
*/
struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
unsigned long addr, unsigned long len, pgoff_t pgoff,
- bool *need_rmap_locks)
+ bool *need_rmap_locks, bool keep_source)
{
struct vm_area_struct *vma = *vmap;
unsigned long vma_start = vma->vm_start;
@@ -1896,6 +1896,21 @@ struct vm_area_struct *copy_vma(struct v
vmg.pgoff = pgoff;
vmg.next = vma_iter_next_rewind(&vmi, NULL);
+
+ /*
+ * If the original VMA is kept (MREMAP_DONTUNMAP), the source and
+ * destination VMA must be treated distinctly.
+ *
+ * A merge violates this, so in this case disallow a self-merge.
+ */
+ if (!faulted_in_anon_vma && keep_source) {
+ if (vmg.prev == vma)
+ vmg.prev = NULL;
+ if (vmg.next == vma)
+ vmg.next = NULL;
+ faulted_in_anon_vma = true;
+ }
+
new_vma = vma_merge_copied_range(&vmg);
if (new_vma) {
--- a/mm/vma.h
+++ b/mm/vma.h
@@ -449,7 +449,7 @@ void unlink_file_vma_batch_add(struct un
struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
unsigned long addr, unsigned long len, pgoff_t pgoff,
- bool *need_rmap_locks);
+ bool *need_rmap_locks, bool keep_source);
struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma);
--- a/tools/testing/vma/tests/vma.c
+++ b/tools/testing/vma/tests/vma.c
@@ -38,7 +38,7 @@ static bool test_copy_vma(void)
/* Move backwards and do not merge. */
vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, vma_flags);
- vma_new = copy_vma(&vma, 0, 0x2000, 0, &need_locks);
+ vma_new = copy_vma(&vma, 0, 0x2000, 0, &need_locks, false);
ASSERT_NE(vma_new, vma);
ASSERT_EQ(vma_new->vm_start, 0);
ASSERT_EQ(vma_new->vm_end, 0x2000);
@@ -51,7 +51,7 @@ static bool test_copy_vma(void)
vma = alloc_and_link_vma(&mm, 0, 0x2000, 0, vma_flags);
vma_next = alloc_and_link_vma(&mm, 0x6000, 0x8000, 6, vma_flags);
- vma_new = copy_vma(&vma, 0x4000, 0x2000, 4, &need_locks);
+ vma_new = copy_vma(&vma, 0x4000, 0x2000, 4, &need_locks, false);
vma_assert_attached(vma_new);
ASSERT_EQ(vma_new, vma_next);
^ permalink raw reply [flat|nested] 291+ messages in thread* Re: [PATCH 7.2 000/281] 7.2.11-rc1 review
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (280 preceding siblings ...)
2026-10-13 11:39 ` [PATCH 7.2 281/281] mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge Greg Kroah-Hartman
@ 2026-10-13 13:23 ` Pavel Machek
2026-10-13 16:30 ` Ronald Warsow
` (5 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Pavel Machek @ 2026-10-13 13:23 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
[-- Attachment #1: Type: text/plain, Size: 52321 bytes --]
Hi!
> This is the start of the stable review cycle for the 7.2.11 release.
> There are 281 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 15 Oct 2026 11:28:22 +0000.
> Anything received after that time might be too late.
There's build failure on risc-v:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/jobs/17139155257
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/pipelines/2942353460
Best regards,
Pavel
arch/riscv/kernel/cpufeature.c: In function 'riscv_clear_hypervisor_csr':
400
13:14:38
arch/riscv/kernel/cpufeature.c:1189:43: error: 'RISCV_ISA_EXT_H' undeclared (first use in this function); did you mean 'RISCV_ISA_EXT_h'?
401
13:14:38
1189 | if (!riscv_has_extension_unlikely(RISCV_ISA_EXT_H))
402
13:14:38
| ^~~~~~~~~~~~~~~
403
13:14:38
| RISCV_ISA_EXT_h
404
13:14:38
arch/riscv/kernel/cpufeature.c:1189:43: note: each undeclared identifier is reported only once for each function it appears in
405
13:14:38
CC io_uring/kbuf.o
406
13:14:38
make[4]: *** [scripts/Makefile.build:289: arch/riscv/kernel/cpufeature.o] Error 1
407
13:14:38
make[3]: *** [scripts/Makefile.build:550: arch/riscv/kernel] Error 2
408
13:14:38
CC ipc/sem.o
409
13:14:38
make[3]: *** Waiting for unfinished jobs....
410
13:14:38
CC kernel/printk/printk.o
411
13:14:39
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v7.x/stable-review/patch-7.2.11-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-7.2.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
>
> -------------
> Pseudo-Shortlog of commits:
>
> Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Linux 7.2.11-rc1
>
> Lorenzo Stoakes (ARM) <ljs@kernel.org>
> mm/mremap: fix locked_vm leak from MREMAP_DONTUNMAP self-merge
>
> Jens Axboe <axboe@kernel.dk>
> io_uring/kbuf: don't charge provided buffer rings to RLIMIT_MEMLOCK
>
> Hengyu Liang <hengyul@cs.unc.edu>
> io_uring: do not charge the SQ/CQ rings to RLIMIT_MEMLOCK
>
> Ali Ahmet Memis <ali@iusegentoo.com>
> io_uring/memmap: account the pages a compound region really uses
>
> Adrian Betschart <adrian.betschart@cinemaone.ch>
> drm/amd/display: Don't replace a sink mode that shares the native totals
>
> Kuba Piecuch <jpiecuch@google.com>
> sched_ext: Call ops.dequeue() when a task arrives on a remote local DSQ
>
> Kuba Piecuch <jpiecuch@google.com>
> sched_ext: Generate qseq from a per-task counter
>
> Maíra Canal <mcanal@igalia.com>
> drm/vc4: Fix binner slot allocation failing on an idle GPU
>
> Maíra Canal <mcanal@igalia.com>
> drm/vc4: Disable the V3D interrupt across runtime suspend
>
> Ilia Gavrilov <Ilia.Gavrilov@infotecs.ru>
> vsock: Fix memory leak in vmci_transport_recv_dgram_cb()
>
> Fernando Fernandez Mancera <fmancera@suse.de>
> net: openvswitch: validate transport header presence in set_ipv6_addr
>
> Vadim Fedorenko <vadim.fedorenko@linux.dev>
> ptp: ocp: fix PCIe delay estimation calculation
>
> Willem de Bruijn <willemb@google.com>
> net/packet: call packet_parse_headers after virtio_net_hdr_to_skb
>
> Petr Machata <petrm@nvidia.com>
> mlxsw: spectrum_flower: Fix port range register leak in tmplt_create()
>
> Li RongQing <lirongqing@baidu.com>
> net/mlx5e: Order ICOSQ cc update after CQ doorbell
>
> Tianyi Gao <tianyi@cloudflare.com>
> veth: fix peer NETDEV_XDP_ACT_NDO_XMIT after GRO is toggled while down
>
> Gyeyoung Baek <gye976@gmail.com>
> drm/imagination: Fix reference and vm_bo handling in remap()
>
> Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
> bareudp: set the inner protocol to the protocol of the packet
>
> Eric Dumazet <edumazet@kernel.org>
> flow_dissector: avoid u16 truncation of hlen in bpf_flow_dissect()
>
> Pavan Chebbi <pavan.chebbi@broadcom.com>
> bnxt_en: Re-write the BARs following any type of PCIe errors
>
> Michael Chan <michael.chan@broadcom.com>
> bnxt_en: Fix driver init in kdump kernel
>
> Michael Chan <michael.chan@broadcom.com>
> bnxt_en: Add bnxt_clear_bars() helper
>
> Zongmin Zhou <zhouzongmin@kylinos.cn>
> riscv: ptrace: Zero-initialize regset buffers before copyin
>
> Leo Yu-Chi Liang <leo.liang@sifive.com>
> riscv: fix NR_CPUS range leaking 64-bit default onto 32-bit builds
>
> Richard Fitzgerald <rf@opensource.cirrus.com>
> ASoC: sdw_utils: Switch CS35L56/57/62/63 to use OT25 DAI
>
> Stefan Binding <sbinding@opensource.cirrus.com>
> ASoC: sdw_utils: Add codec info for CS35L62
>
> Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
> pfcp: make sure the SEID is linear before reading it
>
> Justin Chen <justin.chen@broadcom.com>
> net: bcmgenet: if UMAC was suspended in SW_RESET, restore it to SW_RESET
>
> Or Har-Toov <ohartoov@nvidia.com>
> Revert "net/mlx5: E-Switch, preserve max tx speed on vport state modification"
>
> Victor Nogueira <victor@mojatatu.com>
> net/sched: cls_route: reject change with no routing attribute
>
> Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
> devlink: fix devlink_rel reference leak when notify work is pending
>
> Quentin Freimanis <quentin@q-lab.dev>
> net: sparx5: start the TOD counters on non-PTP lan969x variants
>
> Eric Dumazet <edumazet@kernel.org>
> net: always dissect GSO packets in __virtio_net_hdr_to_skb()
>
> Eric Dumazet <edumazet@kernel.org>
> flow_dissector: avoid u16 truncation of skb->len when computing thoff
>
> Waiman Long <longman@redhat.com>
> cgroup/cpuset: Call is_in_v2_mode() after acquiring cpuset_mutex in cpuset_handle_hotplug()
>
> Han Gao <gaohan@iscas.ac.cn>
> spi: sg2044-nor: Honor SPI clock limits
>
> Han Gao <gaohan@iscas.ac.cn>
> spi: sg2044-nor: Return transfer errors
>
> Marek Szyprowski <m.szyprowski@samsung.com>
> ASoC: samsung: i2s: enable op_clk in probe to balance runtime PM
>
> Alvin Šipraga <alvin.sipraga@analog.com>
> ASoC: adau1372: fix invalid default state of output ASRC and DAC muxes
>
> Alvin Šipraga <alvin.sipraga@analog.com>
> ASoC: adau1372: allow sleepy powerdown GPIOs
>
> Yingying Tang <yingying.tang@oss.qualcomm.com>
> Revert "wifi: ath12k: add panic handler"
>
> Mallesh Koujalagi <mallesh.koujalagi@intel.com>
> drm/xe/sysctrl: Fix mailbox header handling
>
> Devin Wittmayer <lucid_duck@justthetip.ca>
> wifi: mt76: mt792x: pick the SAR table layout from the table itself
>
> Junjie Cao <junjie.cao@intel.com>
> wifi: mt76: mt792x: treat 0xff ACPI SAR entries as no limit
>
> Devin Wittmayer <lucid_duck@justthetip.ca>
> wifi: mt76: mt7925: don't put the band auto marker in TGID
>
> Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
> wifi: mt76: mt7915: disable rx napi when removing device
>
> Tao Gong <gongtao0607@gmail.com>
> wifi: mt76: mt7996: fix struct mt7996_mcu_wed_rro_ba_delete_event layout
>
> Aaron Ma <aaron.ma@canonical.com>
> wifi: mt76: mt7925: restore the legacy BSS after MLO teardown
>
> Felix Fietkau <nbd@nbd.name>
> wifi: mt76: use ALTX queue for packets to disassociated stations
>
> Felix Fietkau <nbd@nbd.name>
> wifi: mt76: account non-AQL frames per peer rather than per link
>
> Felix Fietkau <nbd@nbd.name>
> wifi: mt76: add PS buffering support for HW-managed TIM drivers
>
> Felix Fietkau <nbd@nbd.name>
> wifi: mac80211: add ieee80211_txq_aql_pending()
>
> Felix Fietkau <nbd@nbd.name>
> wifi: mac80211: add AQL support for multicast packets
>
> Felix Fietkau <nbd@nbd.name>
> wifi: mt76: mt7996: take over connection monitoring
>
> Pengpeng Hou <hppiscas@163.com>
> scsi: ufs: mediatek: Handle mPHY power-on failures
>
> Jakub Kicinski <kuba@kernel.org>
> Revert "net: stmmac: propagate PTP addend and system time programming errors"
>
> Aurelien Jarno <aurelien@aurel32.net>
> riscv: vector: Fix output operands in context save
>
> Troy Mitchell <troy.mitchell@linux.dev>
> riscv: vector: Fix data pointer constraints in context save/restore
>
> Leto Liu (刘涛) <Leto.Liu@airoha.com>
> net: airoha: Add retry mechanism to airoha_qdma_set_trtcm_param()
>
> Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> net: stmmac: Disable S-Tag processing on dwmac4
>
> Ovidiu Panait <ovidiu.panait.rb@renesas.com>
> net: stmmac: Do not advertise S-VLAN stripping when it is disabled
>
> Or Har-Toov <ohartoov@nvidia.com>
> net/mlx5: Lag, split aggregate speed into oper and max helpers
>
> Jakub Kicinski <kuba@kernel.org>
> net: make dev_xdp_sb_prog_count() see programs attached through a link
>
> Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
> drm/xe: Do not emit Wa_16010904313 twice
>
> Alan Previn <alan.previn.teres.alexis@intel.com>
> drm/xe/mmio: Fix xe_mmio_wait32() to honor delay/sleep maximums
>
> Filipe Manana <fdmanana@suse.com>
> btrfs: fix lost error return value in btrfs_listxattr()
>
> Filipe Manana <fdmanana@suse.com>
> btrfs: fix xattr replace when multiple xattrs are packed in the same item
>
> Yang Xiuwei <yangxiuwei@kylinos.cn>
> btrfs: don't stash io_uring encoded data across -EAGAIN
>
> Yang Xiuwei <yangxiuwei@kylinos.cn>
> btrfs: unlock inode and extent in caller when io_uring read extent fails
>
> Yang Xiuwei <yangxiuwei@kylinos.cn>
> btrfs: free iov when btrfs_uring_read_extent() fails
>
> Yang Xiuwei <yangxiuwei@kylinos.cn>
> btrfs: always return -EIOCBQUEUED after btrfs_uring_read_extent_endio
>
> Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
> zloop: zero out only the unread tail of short reads
>
> Haibo Chen <haibo.chen@nxp.com>
> spi: spi-nxp-fspi: exit stop mode before waiting for DLL lock
>
> Fuad Tabba <fuad.tabba@linux.dev>
> arm64/boot: Don't set PMUv3p9 FGT2 bits without PMUv3
>
> Sang-Hoon Choi <csh0052@gmail.com>
> nvmet: use the local P2P device on metadata allocation failure
>
> Guixin Liu <kanie@linux.alibaba.com>
> nvmet: return Invalid Field for invalid NSIDs feature 82h
>
> Bryan Fraschetti <bryan.fraschetti@canonical.com>
> ice: Restore Ordered MMIO Writes for Tx Doorbells
>
> Jakub Kicinski <kuba@kernel.org>
> bonding: fix the program leak when XDP is replaced
>
> Mahantesh Salimath <mahantesh@nvidia.com>
> tee: optee: ffa: support shared memory offsets on large-page kernels
>
> Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
> net: stmmac: propagate PTP addend and system time programming errors
>
> Felix Fietkau <nbd@nbd.name>
> wifi: mt76: mt7996: program a link again if the driver holds it
>
> Sang-Hoon Choi <csh0052@gmail.com>
> cxgb4/ch_ktls: disable softirqs around tid_list erases
>
> Shashank Mohan Jain <jain.sm@gmail.com>
> lib/dim: fix 32-bit overflow in dim_calc_stats() rates
>
> Omar Ramadan <omar@blockcast.net>
> amt: send the relay's General Query directly from the receive path
>
> Jamal Hadi Salim <jhs@mojatatu.com>
> net/sched: em_text: reject unterminated algo before autoload
>
> Maíra Canal <mcanal@igalia.com>
> drm/vc4: Use kvmalloc_objs() for the BO cache size list
>
> Maíra Canal <mcanal@igalia.com>
> drm/vc4: Free the BO cache size list on teardown
>
> Myeonghun Pak <mhun512@gmail.com>
> drm/aspeed: Balance the display clock enable on teardown
>
> Sang-Hoon Choi <csh0052@gmail.com>
> gpio: exar: initialize the ID before registering its cleanup
>
> Oleg Keri <okerixx@gmail.com>
> drm/dp: don't mark the AUX backlight enabled when enabling failed
>
> Waiman Long <longman@redhat.com>
> cgroup/cpuset: Don't access cpuset_cgrp_subsys.root in is_in_v2_mode()
>
> Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> drm/bridge: Fix unlocked list access in drm_bridge_attach()
>
> Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
> drm/bridge: Fix unlocked list_del in drm_bridge_add()
>
> Sai Teja Aluvala <aluvala.sai.teja@intel.com>
> Bluetooth: btintel_pcie: Add shared HW reset for clean start
>
> Ravindra <ravindra@intel.com>
> Bluetooth: btintel_pcie: fix TX descriptor bounds check
>
> Naomi Chu <naomi.chu@mediatek.com>
> scsi: ufs: core: Hold a clock reference across the probe
>
> Christian Brauner <brauner@kernel.org>
> fs: don't let a migrating task hide its reference from do_umount()
>
> Christian Brauner <brauner@kernel.org>
> mount: refuse MOVE_MOUNT_SET_GROUP on an unbindable mount
>
> Peng Fan <peng.fan@nxp.com>
> iommu/dma: skip swiotlb bounce for DMA_ATTR_MMIO in iommu_dma_map_phys
>
> Vincent Jardin <vjardin@free.fr>
> arm64: dts: lx2160a: fix the iic5 spi3 pinmux offset and value
>
> Vincent Jardin <vjardin@free.fr>
> arm64: dts: lx2160a: fix IIC1 pinmux submask rejected by pinctrl-single
>
> Vincent Jardin <vjardin@free.fr>
> arm64: dts: lx2160a: fix incorrect pinmux
>
> Taniya Das <taniya.das@oss.qualcomm.com>
> clk: qcom: gpucc-kaanapali: Mark the GPU CX GDSC as votable
>
> Taniya Das <taniya.das@oss.qualcomm.com>
> clk: qcom: gpucc-glymur: Mark the GPU CX GDSC as votable
>
> Luca Weiss <luca.weiss@fairphone.com>
> clk: qcom: gcc-kaanapali: Fix always-enabling PCIE_RSCC clocks
>
> Luca Weiss <luca.weiss@fairphone.com>
> clk: qcom: gcc-eliza: Fix always-enabling PCIE_RSCC clocks
>
> Darrick J. Wong <djwong@kernel.org>
> xfs: fix exchange-range-to-eof file size exchange
>
> Norbert Szetei <norbert@doyensec.com>
> xfs: stop exchanging reflink flags when exchanging mappings
>
> Christian Brauner <brauner@kernel.org>
> namespace: keep the lock on a mount that a propagated copy is moved beneath
>
> Christian Brauner <brauner@kernel.org>
> namespace: handle mount locking for automounts correctly
>
> Christian Brauner <brauner@kernel.org>
> namespace: never expire a locked mount
>
> Christian Brauner <brauner@kernel.org>
> nullfs: don't update the access time
>
> Christian Brauner <brauner@kernel.org>
> namespace: refuse an automount below a mount that is in no namespace
>
> Christian Brauner <brauner@kernel.org>
> fcntl: refuse F_SET_RW_HINT on an immutable inode
>
> Christian Brauner <brauner@kernel.org>
> namei: don't reveal overmounted entries in refwalk
>
> Christian Brauner <brauner@kernel.org>
> namespace: unhash a dentry before detaching the mounts on it
>
> Christian Brauner <brauner@kernel.org>
> namespace: don't let a pseudo dentry become the root of a mount
>
> Christian Brauner <brauner@kernel.org>
> unshare: don't drop active namespace references that were never taken
>
> Christian Brauner <brauner@kernel.org>
> dcache: don't put a mountpoint on a dentry that's being removed
>
> Christian Brauner <brauner@kernel.org>
> namespace: check the mounts before reading their parents in pivot_root()
>
> Christian Brauner <brauner@kernel.org>
> namespace: remove the fsnotify marks of a mount namespace in process context
>
> Christian Brauner <brauner@kernel.org>
> namespace: don't reconfigure internal superblocks via remount and umount
>
> Christian Brauner <brauner@kernel.org>
> namespace: look at the topmost mount for a mount namespace file
>
> Christian Brauner <brauner@kernel.org>
> namespace: keep covered mounts covered in OPEN_TREE_NAMESPACE
>
> Christian Brauner <brauner@kernel.org>
> namespace: check a recursive bind mount for mount namespace loops
>
> Christian Brauner <brauner@kernel.org>
> namespace: check a submount for references right before unmounting it
>
> Christian Brauner <brauner@kernel.org>
> namespace: queue a mount only once for mount notifications
>
> Christian Brauner <brauner@kernel.org>
> namespace: check the target before walking it in do_mount_setattr()
>
> Christian Brauner <brauner@kernel.org>
> fs: refuse fspick() on internal superblocks
>
> Christian Brauner <brauner@kernel.org>
> namespace: don't copy an unmounted mount tree
>
> Christian Brauner <brauner@kernel.org>
> namespace: don't inherit MNT_UMOUNT in clone_mnt()
>
> Christian Brauner <brauner@kernel.org>
> statmount: read the parent of an unmounted mount under mount_lock
>
> Christian Brauner <brauner@kernel.org>
> namespace: reset the old parent's ->overmount in mnt_change_mountpoint()
>
> Christian Brauner <brauner@kernel.org>
> fs: don't silently unmount busy mounts
>
> Christian Brauner <brauner@kernel.org>
> mount: keep a copied mount unbindable
>
> Leo Li <sunpeng.li@amd.com>
> drm/amd/display: disable self-refresh on tearing flips
>
> Leo Li <sunpeng.li@amd.com>
> drm/amd/display: Fix direct scanout alpha on some DRM_FORMATs
>
> Jesse Zhang <Jesse.Zhang@amd.com>
> drm/amdgpu/userq: return the memdup_user() error for the user MQD
>
> Jesse Zhang <Jesse.Zhang@amd.com>
> drm/amdgpu/userq: only accept doorbell BOs as queue doorbell
>
> Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
> drm/amdgpu: copy debugfs register data outside the GRBM/SRBM locks
>
> Alex Deucher <alexander.deucher@amd.com>
> drm/amdgpu: make Mac FB workaround generic
>
> Vitaly Prosyak <vitaly.prosyak@amd.com>
> drm/amdgpu: serialize vblank counter reads against GPU reset
>
> Haojie Li <lihaojie@kylinos.cn>
> drm/amdkfd: fix dma_buf reference leak in get_dmabuf_info
>
> Saleel Kudchadker <Saleel.Kudchadker@amd.com>
> drm/amdkfd: align SDMA doorbell base for shader doorbell writes
>
> Felix Gu <ustc.gu@gmail.com>
> drm/bridge: th1520-dw-hdmi: Fix remove() callback
>
> Felix Gu <ustc.gu@gmail.com>
> drm/bridge: th1520-dw-hdmi: Fix error check on dw_hdmi_probe() return value
>
> Thomas Hellström <thomas.hellstrom@linux.intel.com>
> drm/xe: Fix stale pinned_link entry when fb-pin performs the final unpin
>
> Thomas Hellström <thomas.hellstrom@linux.intel.com>
> drm/xe: Fix shrinker accounting double-subtraction on nested external pins
>
> Fan Wu <fanwu01@zju.edu.cn>
> drm/xe/i2c: cancel the client work on remove
>
> Zack Rusin <zack.rusin@broadcom.com>
> drm/vmwgfx: validate pitch coming from userspace
>
> Wentao Liang <vulab@iscas.ac.cn>
> drm/vc4: Fix firmware reference leak in vc4_drm_bind()
>
> Fan Wu <fanwu01@zju.edu.cn>
> drm/vc4: drain the hangcheck timer and works on V3D unbind
>
> Osama Abdelkader <osama.abdelkader@gmail.com>
> drm/panthor: validate userspace queue count against initialized firmware slot count
>
> Gyeyoung Baek <gye976@gmail.com>
> drm/imagination: Size page table preallocation by device address
>
> Krzysztof Karas <krzysztof.karas@intel.com>
> drm/i915/gt: Unmask interrupts only when ACTIVE is true
>
> Krzysztof Karas <krzysztof.karas@intel.com>
> drm/i915/gem: Prevent overstepping exec array boundary
>
> Sajal Gupta <sajal2005gupta@gmail.com>
> drm/gud: don't keep a connector without a CRTC as connector_state
>
> Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
> drm/fb-helper: defer setup when fbdev_probe() fails, not just on -EAGAIN
>
> Palla Raghunath <raghunathpalla.0209@gmail.com>
> Bluetooth: RFCOMM: Fix NULL tty_dev dereference in rfcomm_dev_shutdown
>
> Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
> Bluetooth: RFCOMM: connect the session socket without rfcomm_mutex
>
> Maxim Skokov <skokovmaksimevg@gmail.com>
> Bluetooth: RFCOMM: free the skb when the DLC has no owner
>
> Aldo Ariel Panzardo <qwe.aldo@gmail.com>
> Bluetooth: SCO: serialise sco_conn lifetime against sco_recv_scodata()
>
> Iaroslav Voitovych <yaroslav.voytovych@gmail.com>
> Bluetooth: MGMT: Fix status of pending commands flushed on power off
>
> Chengfeng Ye <nicoyip.dev@gmail.com>
> Bluetooth: ISO: Serialize concurrent connect calls
>
> Chengfeng Ye <nicoyip.dev@gmail.com>
> Bluetooth: ISO: Reject concurrent BIS listener setup
>
> Chengfeng Ye <nicoyip.dev@gmail.com>
> Bluetooth: hci_sync: Fix command skb lifetime during scan setup
>
> Chengfeng Ye <nicoyip.dev@gmail.com>
> Bluetooth: hci_sock: Serialize dead-device detachment
>
> Runyu Xiao <runyu.xiao@seu.edu.cn>
> Bluetooth: btintel_pcie: use managed IRQ teardown
>
> Chen Pei <cp0613@linux.alibaba.com>
> riscv: ptrace: reject CFI regset access when extensions are absent
>
> Wei-Jie Hung <imbigking12@gmail.com>
> riscv: patch: fix handling of bpf-jit execmem addresses
>
> Shao Mingyin <shao.mingyin@zte.com.cn>
> riscv: lib: Fix ZBB strnlen wrap-around regression on huge counts
>
> Zongmin Zhou <zhouzongmin@kylinos.cn>
> riscv: hwprobe: use _BITULL() rather than BIT() in MIPS vendor uapi header
>
> Ziyi Guo <guoziyi114@gmail.com>
> riscv: futex: untag the user pointer before the atomic access
>
> Karl Mehltretter <kmehltretter@gmail.com>
> riscv: fix load_unaligned_zeropad() fixup for RV32
>
> Zongmin Zhou <zhouzongmin@kylinos.cn>
> riscv: errata: select RISCV_ALTERNATIVE_EARLY for THEAD GHOSTWRITE
>
> Ziyi Guo <guoziyi114@gmail.com>
> riscv: entry: gate shadow call stack reload on sstatus.SPP, not tp
>
> Stanley Jhu <stanleyjhu@google.com>
> scsi: ufs: core: Decouple CQ sweep from request iterator in MCQ
>
> Stanley Jhu <stanleyjhu@google.com>
> scsi: ufs: core: Avoid unsafe MMIO reads in ufshcd_mcq_compl_all_cqes_lock()
>
> Runyu Xiao <runyu.xiao@seu.edu.cn>
> scsi: qedi: Initialize callback state before registration
>
> Ahmed Abdelhaleem Ahmed <ahmedhal@gmail.com>
> scsi: ch: Do not keep references to data transfer element devices
>
> Shawn Lin <shawn.lin@rock-chips.com>
> pmdomain: rockchip: propagate subdomain add errors
>
> Shawn Lin <shawn.lin@rock-chips.com>
> pmdomain: rockchip: fix clock leak on domain probe failure
>
> Shawn Lin <shawn.lin@rock-chips.com>
> pmdomain: rockchip: don't ignore clock lookup errors on attach
>
> Ming Qian <ming.qian@oss.nxp.com>
> pmdomain: imx8m-blk-ctrl: Serialize power on/off across sibling domains
>
> Ridham Khurana <khurana.ridham222@gmail.com>
> regulator: tps6594-regulator: Fix n_linear_ranges for TPS65224 BUCK2-4
>
> Alexey Charkov <alchark@flipper.net>
> regulator: of: fill in supply names in of_regulator_bulk_get_all()
>
> Abhishek Ojha <Abhishek.ojha@savoirfairelinux.com>
> regulator: ltc3676: don't read the write-only HRST and CLIRQ registers
>
> Alexey Charkov <alchark@flipper.net>
> power: sequencing: pcie-m2: Fix leaking array from of_regulator_bulk_get_all()
>
> Shao-Fu Chen <shf.chen@mediatek.com>
> optee: register TEE devices only once fully initialized
>
> Denis V. Lunev <den@openvz.org>
> openvswitch: fix soft lockup in the netlink flow dump
>
> Karl Bonde Torp <k.torp@samsung.com>
> nvme: fix swapped ZRASF zone state values for full and read only
>
> Weiming Shi <bestswngs@gmail.com>
> net: team: free skb when broadcast has no txable port
>
> Weiming Shi <bestswngs@gmail.com>
> net: team: stop reusing skb after queue override
>
> Suraj Gupta <suraj.gupta2@amd.com>
> net: xilinx: axienet: Free outstanding DMA buffers on dmaengine stop
>
> Fredrik Nyberg <fredrik.nyberg@volvocars.com>
> net: usb: ax88179_178a: fix rx frame length for non-last packets
>
> Daniel Machon <daniel.machon@microchip.com>
> net: sparx5: free the matchall entry on destroy
>
> Josef Bacik <josef@toxicpanda.com>
> net: skbuff: don't leave stale bytes in skb_copy_and_csum_bits()
>
> Sebastien Royen <sebastien.royen@armadeus.com>
> net: dsa: microchip: fix KSZ8765 fiber detection
>
> Zixuan Chai <petalzu987@gmail.com>
> net: bridge: avoid recursive multicast port cleanup
>
> Chengfeng Ye <nicoyip.dev@gmail.com>
> net/smc: protect clcsock lifetime in smc_getname
>
> Quchaosheng <quchaosheng000406@163.com>
> net/packet: guard the ll header push in packet_rcv_spkt()
>
> Guangshuo Li <lgs201920130244@gmail.com>
> mmc: sdhci-sprd: disable runtime PM on remove
>
> Yibo Tan <lhfff@tju.edu.cn>
> mmc: mtk-sd: Cancel request timeout work on remove
>
> Guangshuo Li <lgs201920130244@gmail.com>
> mmc: cavium-thunderx: destroy slot platform devices on remove
>
> Guangshuo Li <lgs201920130244@gmail.com>
> mmc: cavium-octeon: destroy slot platform devices on remove
>
> Mikulas Patocka <mpatocka@redhat.com>
> dm: fix reading free memory in do_resume
>
> Ma Xinmeng <1564938642@qq.com>
> dm-snap: reject the transient exception store for snapshot-merge
>
> Ben Cressey <ben@cressey.dev>
> dm-integrity: fix buffer overflow in inline mode with large tag size
>
> Ben Cressey <ben@cressey.dev>
> dm-crypt: reject the lmk IV mode with AEAD ciphers
>
> Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
> mm: don't schedule deferred kernel page table freeing while booting
>
> Lorenzo Stoakes (ARM) <ljs@kernel.org>
> mm/mremap: fix locked_vm leak by splitting VMA for MREMAP_DONTUNMAP
>
> Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
> memstick: rtsx_usb_ms: complete requests after eject instead of dropping them
>
> Raj Ojha <rajojha047@gmail.com>
> memstick: core: wait for request completion before freeing card
>
> 성병찬 <tjdqudcks0424@naver.com>
> KEYS: Fix add_key() race with keyring restriction
>
> Karl Mehltretter <kmehltretter@gmail.com>
> keys: finalize persistent keyring timeout after link attempt
>
> Daehyeon Ko <4ncienth@gmail.com>
> ip6_gre: remove obsolete ERSPAN PMTU update
>
> Natasha Klaus <natalie.klaus@runtimeverification.com>
> io_uring/net: populate CONNECT filter fields for 24-byte sockaddr_in6
>
> Eugene Gvozdetsky <gvozdet@gmail.com>
> io_uring/register: don't exempt disabled rings from task restrictions
>
> Tristan Madani <tristan@talencesecurity.com>
> ice: fix metadata_dst refcount handling on representor teardown
>
> Xuanqiang Luo <luoxuanqiang@kylinos.cn>
> ice: fix use-after-free in dynamic port cleanup
>
> Mingming Cao <mmc@linux.ibm.com>
> ibmveth: fix TX LTB and filter unwind on open-fail
>
> Mingming Cao <mmc@linux.ibm.com>
> ibmveth: h_free logical LAN on open-fail after register
>
> Joshua Washington <joshwash@google.com>
> gve: fix XSK buffer leak on error descriptor
>
> Joshua Washington <joshwash@google.com>
> gve: fix XSK buffer leak when rings are stopped
>
> Joshua Washington <joshwash@google.com>
> gve: fix napi_disable deadlock when attempting to disable XSK pools
>
> Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
> iavf: send MAC change request synchronously
>
> Ridham Khurana <khurana.ridham222@gmail.com>
> gpio: xilinx: fix runtime PM leak on request error path
>
> Fan Wu <fanwu01@zju.edu.cn>
> gpio: mpsse: fix race when arming the IRQ poll worker
>
> Eric Biggers <ebiggers@kernel.org>
> fsverity: RCU-delay the freeing of struct fsverity_info
>
> Vishal Badole <Vishal.Badole@amd.com>
> EDAC/amd64: Mask UMC chip select to the four implemented selects
>
> Tony Nguyen <anthony.l.nguyen@intel.com>
> e1000e: add system to disable K1 list
>
> Carlos Llamas <cmllamas@google.com>
> selftests/mm: cleanup -Wformat issues in hugetlb-mmap
>
> Hui Peng <benquike@gmail.com>
> sctp: copy zeroed stats to user in sctp_getsockopt_pr_streamstatus() when !streamoute
>
> Stephen Smalley <stephen.smalley.work@gmail.com>
> selinux: preserve NATIVE_LABELS on already-initialized sb in set_mnt_opts
>
> Christian Göttsche <cgzones@googlemail.com>
> selinux: fix data race on AVC latest_notif
>
> Yong-Xuan Wang <yongxuan.wang@sifive.com>
> RISC-V: Clear HSTATUS.HU on CPU initialization
>
> Johannes Berg <johannes.berg@intel.com>
> Revert "wifi: libertas: reject short monitor TX frames"
>
> Chengfeng Ye <nicoyip.dev@gmail.com>
> tipc: hold a reference to nodes found by link name
>
> Yuqi Xu <xuyuqiabc@gmail.com>
> tipc: destroy topsrv workqueues before closing connections
>
> Daehyeon Ko <4ncienth@gmail.com>
> tcp: reject net_iov in zerocopy receive mapping hints
>
> Marek Szyprowski <m.szyprowski@samsung.com>
> swiotlb: fix default_swiotlb_limit() for non-growable default pool
>
> Sabrina Dubroca <sd@queasysnail.net>
> strparser: make sure __strp_recv isn't running before tearing down the parser
>
> Georgiy Osokin <g.osokin@auroraos.dev>
> tee: shm: reject zero-sized allocations in tee_dyn_shm_alloc_helper()
>
> Josef Bacik <josef@toxicpanda.com>
> xen/netfront: don't leak the skb when xennet_fill_frags() fails
>
> Borislav Petkov (AMD) <bp@alien8.de>
> x86/CPU/AMD: Fix AMD TLBI Erratum #1718
>
> Pavankumar Kondeti <pavan.kondeti@oss.qualcomm.com>
> workqueue: Fix NULL current_pwq deref in chained work check
>
> Jason A. Donenfeld <Jason@zx2c4.com>
> wireguard: noise: reject response consumption after intermediate initiation
>
> Ramses de Norre <ramses@well-founded.dev>
> wireguard: queueing: preserve tstamp_type when encapsulating packet
>
> Lu Huang <huanglu@kylinos.cn>
> wifi: mt76: mt7996: fix uninitialized buf read in mt7996_variant_fem_init()
>
> Cristian Papa <pcristian292@gmail.com>
> wifi: mt76: mt7603: initialize global station WCID
>
> Michele Dionisio <michele.dionisio@gmail.com>
> wifi: brcmfmac: fix P2P device removal race in brcmf_detach()
>
> Daehyeon Ko <4ncienth@gmail.com>
> vsock/virtio: account only unread bytes in read_skb()
>
> Ji-Ze Hong (Peter Hong) <peter_hong@fintek.com.tw>
> usb: f81604: fix struct f81604_int_data size mismatch
>
> Palla Raghunath <raghunathpalla.0209@gmail.com>
> dm ioctl: don't let data_start run past the buffer
>
> Daehyeon Ko <4ncienth@gmail.com>
> cipso: adjust cached option offsets when removing CIPSO
>
> Waiman Long <longman@redhat.com>
> cgroup/cpuset: Handle cpu hotplug race in guarantee_active_cpus()
>
> Oliver Hartkopp <socketcan@hartkopp.net>
> can: fix unique skb identifier regression under RPS
>
> zjamg <ndaugoing@gmail.com>
> can: dev: init_can_skb(): restore skb header initialization
>
> Wentao Liang <vulab@iscas.ac.cn>
> btrfs: scrub: fix local_root reference leak in scrub_print_warning_inode()
>
> Hengyu Liang <hengyul@cs.unc.edu>
> ata: libata-scsi: do not lose CHECK CONDITION for failed ATAPI commands
>
> Michael Garland <minimelkav@gmail.com>
> ASoC: amd: yc: Add DMI quirk for Acer Aspire Go 15 (AG15-21P)
>
> Karl Mehltretter <kmehltretter@gmail.com>
> arm64: irq: exclude the softirq stack switch from KCOV
>
> Mohamed Yassine Jebabli <med.jebabli@gmail.com>
> ALSA: hda/tas2781: Accept V1 calibration data without CRC
>
> Harin Lee <me@harin.net>
> ALSA: ctxfi: Fix memory leakage when clearing DAO input mappers
>
> Krzysztof Furman <krisfur@proton.me>
> Input: xpad - add support for Corsair Novablade Pro
>
> Bihaan Sen <stevewholikesthings@gmail.com>
> Input: xpad - add support for 8BitDo Pro 2 Wired Controller for Xbox
>
> Haotian Zhang <vulab@iscas.ac.cn>
> Input: ati_remote2 - fix type confusion in device attribute handlers
>
> Daehyeon Ko <4ncienth@gmail.com>
> ipv6: do not warn on route notification size race
>
> Daehyeon Ko <4ncienth@gmail.com>
> ipv4: do not warn on route notification size race
>
> Daehyeon Ko <4ncienth@gmail.com>
> ipv4: stop route notification sizing when nexthop group shrinks
>
> Daehyeon Ko <4ncienth@gmail.com>
> ipv4: stop exception dump when nexthop group shrinks
>
> Daehyeon Ko <4ncienth@gmail.com>
> ipv4: stop PMTU walk when nexthop group shrinks
>
> Alice Ryhl <aliceryhl@google.com>
> rust_binder: reschedule node refcount update on thread exit
>
> Michael S. Tsirkin <mst@redhat.com>
> ipv4: validate checksum_start before completing checksum
>
> Ido Schimmel <idosch@nvidia.com>
> ipv6: udp: Create exceptions before socket matching
>
> Ido Schimmel <idosch@nvidia.com>
> ipv4: udp: Create exceptions before socket matching
>
> Ido Schimmel <idosch@nvidia.com>
> ipv6: Fix redirect exception creation for UDP/RAW sockets
>
> Jerome Tollet <jtollet@cisco.com>
> net/mlx5e: Prevent stale XSK buffer release on MPWQE refill retry
>
> Jerome Tollet <jtollet@cisco.com>
> net/mlx5e: Prevent stale XSK buffer release on refill retry
>
> Matthew Wilcox (Oracle) <willy@infradead.org>
> fs: Free any excess xarray nodes in clear_inode()
>
> Eric Dumazet <edumazet@kernel.org>
> bnxt_en: fix DMA mapping length for padded small packets
>
>
> -------------
>
> Diffstat:
>
> Documentation/networking/strparser.rst | 2 +-
> Makefile | 4 +-
> arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 19 +-
> arch/arm64/include/asm/el2_setup.h | 5 +-
> arch/arm64/kernel/Makefile | 3 +
> arch/riscv/Kconfig | 5 +-
> arch/riscv/Kconfig.errata | 1 +
> arch/riscv/include/asm/cpufeature.h | 2 +
> arch/riscv/include/asm/futex.h | 2 +
> arch/riscv/include/asm/scs.h | 17 +-
> arch/riscv/include/asm/vector.h | 8 +-
> arch/riscv/include/uapi/asm/vendor/mips.h | 4 +-
> arch/riscv/kernel/cpufeature.c | 12 +
> arch/riscv/kernel/entry.S | 2 +-
> arch/riscv/kernel/patch.c | 2 +-
> arch/riscv/kernel/ptrace.c | 8 +
> arch/riscv/kernel/setup.c | 2 +
> arch/riscv/kernel/smpboot.c | 2 +
> arch/riscv/kernel/suspend.c | 2 +
> arch/riscv/lib/strnlen.S | 20 +-
> arch/riscv/mm/extable.c | 4 +-
> arch/um/drivers/vector_transports.c | 1 +
> arch/x86/include/asm/cpufeatures.h | 3 +
> arch/x86/include/asm/tlb.h | 6 +
> arch/x86/kernel/cpu/amd.c | 4 +
> drivers/android/binder/node.rs | 20 +-
> drivers/android/binder/node/wrapper.rs | 34 ++-
> drivers/ata/libata-scsi.c | 13 +-
> drivers/block/zloop.c | 31 ++-
> drivers/bluetooth/btintel_pcie.c | 17 +-
> drivers/clk/qcom/gcc-eliza.c | 6 +-
> drivers/clk/qcom/gcc-kaanapali.c | 6 +-
> drivers/clk/qcom/gpucc-glymur.c | 2 +-
> drivers/clk/qcom/gpucc-kaanapali.c | 2 +-
> drivers/edac/amd64_edac.c | 4 +-
> drivers/gpio/gpio-exar.c | 2 +-
> drivers/gpio/gpio-mpsse.c | 24 +-
> drivers/gpio/gpio-xilinx.c | 9 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 8 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 77 ++++---
> drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 17 +-
> drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 5 +
> drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 13 +-
> drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 9 +-
> .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 32 ++-
> drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 7 +
> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 26 ++-
> .../drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 20 +-
> drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 5 +-
> drivers/gpu/drm/bridge/th1520-dw-hdmi.c | 8 +-
> drivers/gpu/drm/display/drm_dp_helper.c | 4 +-
> drivers/gpu/drm/drm_bridge.c | 8 +-
> drivers/gpu/drm/drm_fb_helper.c | 6 +-
> drivers/gpu/drm/gud/gud_pipe.c | 1 +
> drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +-
> drivers/gpu/drm/i915/gt/intel_rps.c | 3 +-
> drivers/gpu/drm/imagination/pvr_mmu.c | 25 +-
> drivers/gpu/drm/imagination/pvr_vm.c | 8 +-
> drivers/gpu/drm/panthor/panthor_sched.c | 3 +
> drivers/gpu/drm/vc4/vc4_bo.c | 5 +-
> drivers/gpu/drm/vc4/vc4_drv.c | 5 +-
> drivers/gpu/drm/vc4/vc4_drv.h | 2 +-
> drivers/gpu/drm/vc4/vc4_gem.c | 8 +-
> drivers/gpu/drm/vc4/vc4_irq.c | 24 +-
> drivers/gpu/drm/vc4/vc4_v3d.c | 65 +++---
> drivers/gpu/drm/vc4/vc4_validate.c | 2 +-
> drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c | 26 ++-
> drivers/gpu/drm/xe/display/xe_fb_pin.c | 6 +-
> drivers/gpu/drm/xe/xe_bo.c | 139 ++++++++---
> drivers/gpu/drm/xe/xe_bo.h | 2 +
> drivers/gpu/drm/xe/xe_i2c.c | 5 +-
> drivers/gpu/drm/xe/xe_lrc.c | 38 +--
> drivers/gpu/drm/xe/xe_mmio.c | 5 +-
> drivers/gpu/drm/xe/xe_sysctrl_mailbox.c | 16 +-
> drivers/input/joystick/xpad.c | 4 +
> drivers/input/misc/ati_remote2.c | 12 +-
> drivers/iommu/dma-iommu.c | 4 +-
> drivers/md/dm-crypt.c | 7 +-
> drivers/md/dm-integrity.c | 4 +-
> drivers/md/dm-ioctl.c | 14 +-
> drivers/md/dm-snap.c | 14 ++
> drivers/memstick/core/memstick.c | 8 +-
> drivers/memstick/host/rtsx_usb_ms.c | 31 +--
> drivers/mmc/host/cavium-octeon.c | 5 +-
> drivers/mmc/host/cavium-thunderx.c | 5 +-
> drivers/mmc/host/mtk-sd.c | 1 +
> drivers/mmc/host/sdhci-sprd.c | 4 +
> drivers/net/amt.c | 48 ++--
> drivers/net/bareudp.c | 3 +-
> drivers/net/bonding/bond_main.c | 8 +-
> drivers/net/can/dev/skb.c | 4 +
> drivers/net/can/usb/f81604.c | 2 +-
> drivers/net/can/vxcan.c | 3 +
> drivers/net/dsa/microchip/ksz_common.h | 2 +-
> drivers/net/ethernet/airoha/airoha_eth.c | 32 ++-
> drivers/net/ethernet/airoha/airoha_eth.h | 2 +
> drivers/net/ethernet/broadcom/bnxt/bnxt.c | 199 ++++++++++------
> drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 -
> drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 11 +
> .../chelsio/inline_crypto/ch_ktls/chcr_ktls.c | 4 +-
> drivers/net/ethernet/google/gve/gve_main.c | 8 +-
> drivers/net/ethernet/google/gve/gve_rx_dqo.c | 13 +-
> drivers/net/ethernet/ibm/ibmveth.c | 22 +-
> drivers/net/ethernet/intel/e1000e/netdev.c | 7 +
> drivers/net/ethernet/intel/iavf/iavf.h | 11 +-
> drivers/net/ethernet/intel/iavf/iavf_main.c | 85 +++++--
> drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 99 +++++++-
> drivers/net/ethernet/intel/ice/devlink/port.c | 2 +-
> drivers/net/ethernet/intel/ice/ice_eswitch.c | 2 +-
> drivers/net/ethernet/intel/ice/ice_txrx.c | 4 +-
> .../net/ethernet/mellanox/mlx5/core/en/xsk/rx.c | 2 +
> drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 13 +-
> .../ethernet/mellanox/mlx5/core/esw/adj_vport.c | 20 --
> drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c | 79 +++++--
> drivers/net/ethernet/mellanox/mlx5/core/vport.c | 24 --
> drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 2 +
> drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | 10 +-
> .../net/ethernet/mellanox/mlxsw/spectrum_flower.c | 9 +-
> drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 28 ++-
> .../ethernet/microchip/sparx5/sparx5_tc_matchall.c | 1 +
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 15 +-
> drivers/net/ethernet/xilinx/xilinx_axienet.h | 7 +-
> drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 53 ++++-
> drivers/net/pfcp.c | 7 +
> drivers/net/team/team_core.c | 16 +-
> drivers/net/team/team_mode_broadcast.c | 2 +
> drivers/net/tun.c | 23 +-
> drivers/net/usb/ax88179_178a.c | 6 +-
> drivers/net/veth.c | 1 +
> drivers/net/virtio_net.c | 2 +
> drivers/net/wireguard/noise.c | 7 +-
> drivers/net/wireguard/queueing.h | 2 +
> drivers/net/wireless/ath/ath12k/core.c | 33 +--
> drivers/net/wireless/ath/ath12k/core.h | 3 -
> drivers/net/wireless/ath/ath12k/hif.h | 9 -
> drivers/net/wireless/ath/ath12k/pci.c | 8 -
> .../wireless/broadcom/brcm80211/brcmfmac/core.c | 27 ++-
> drivers/net/wireless/marvell/libertas/tx.c | 7 -
> drivers/net/wireless/mediatek/mt76/mt76.h | 10 +
> drivers/net/wireless/mediatek/mt76/mt7603/init.c | 1 +
> .../net/wireless/mediatek/mt76/mt76_connac_mcu.h | 1 +
> drivers/net/wireless/mediatek/mt76/mt7915/init.c | 6 +
> drivers/net/wireless/mediatek/mt76/mt7915/main.c | 2 +
> drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 3 +-
> drivers/net/wireless/mediatek/mt76/mt7925/main.c | 12 +
> .../net/wireless/mediatek/mt76/mt792x_acpi_sar.c | 134 +++++++----
> .../net/wireless/mediatek/mt76/mt792x_acpi_sar.h | 2 +
> drivers/net/wireless/mediatek/mt76/mt7996/init.c | 3 +-
> drivers/net/wireless/mediatek/mt76/mt7996/main.c | 10 +-
> drivers/net/wireless/mediatek/mt76/mt7996/mcu.h | 3 +
> drivers/net/wireless/mediatek/mt76/tx.c | 89 +++++++-
> drivers/net/xen-netfront.c | 4 +-
> drivers/nvme/target/core.c | 2 +-
> drivers/nvme/target/pr.c | 4 +
> drivers/pmdomain/imx/imx8m-blk-ctrl.c | 15 ++
> drivers/pmdomain/rockchip/pm-domains.c | 20 +-
> drivers/power/sequencing/pwrseq-pcie-m2.c | 2 +
> drivers/ptp/ptp_ocp.c | 2 +-
> drivers/regulator/ltc3676.c | 15 +-
> drivers/regulator/of_regulator.c | 24 +-
> drivers/regulator/tps6594-regulator.c | 6 +-
> drivers/scsi/ch.c | 29 +--
> drivers/scsi/qedi/qedi_main.c | 3 +-
> drivers/spi/spi-nxp-fspi.c | 22 +-
> drivers/spi/spi-sg2044-nor.c | 60 ++++-
> drivers/tee/optee/ffa_abi.c | 38 ++-
> drivers/tee/optee/optee_msg.h | 4 +-
> drivers/tee/optee/smc_abi.c | 17 +-
> drivers/tee/tee_shm.c | 4 +
> drivers/ufs/core/ufs-mcq.c | 30 +--
> drivers/ufs/core/ufshcd.c | 53 +++--
> drivers/ufs/host/ufs-mediatek.c | 18 +-
> fs/btrfs/inode.c | 7 +-
> fs/btrfs/ioctl.c | 31 +--
> fs/btrfs/scrub.c | 4 +-
> fs/btrfs/xattr.c | 15 +-
> fs/dcache.c | 4 +-
> fs/fcntl.c | 3 +
> fs/fs_context.c | 4 +
> fs/inode.c | 23 +-
> fs/mount.h | 6 +-
> fs/namei.c | 29 +++
> fs/namespace.c | 254 ++++++++++++++++-----
> fs/nullfs.c | 4 +-
> fs/pnode.c | 108 +++++++--
> fs/verity/fsverity_private.h | 15 +-
> fs/verity/open.c | 13 +-
> fs/xfs/libxfs/xfs_exchmaps.c | 103 ++-------
> fs/xfs/libxfs/xfs_log_format.h | 4 +-
> fs/xfs/xfs_bmap_util.c | 15 +-
> fs/xfs/xfs_exchrange.c | 51 +++--
> include/linux/can/core.h | 3 +-
> include/linux/can/skb.h | 4 +-
> include/linux/io_uring_types.h | 2 +
> include/linux/mount.h | 2 +-
> include/linux/nsproxy.h | 1 +
> include/linux/nvme.h | 4 +-
> include/linux/sched/ext.h | 1 +
> include/linux/virtio_net.h | 64 +++---
> include/net/amt.h | 4 -
> include/net/bluetooth/rfcomm.h | 1 +
> include/net/can.h | 2 +
> include/net/cfg80211.h | 1 +
> include/net/ip.h | 7 +
> include/net/mac80211.h | 14 +-
> include/net/strparser.h | 10 +-
> io_uring/io_uring.c | 13 +-
> io_uring/kbuf.c | 6 +-
> io_uring/memmap.c | 47 +++-
> io_uring/memmap.h | 2 +-
> io_uring/net.c | 4 +-
> io_uring/register.c | 21 +-
> io_uring/zcrx.c | 2 +-
> kernel/cgroup/cpuset.c | 40 +++-
> kernel/dma/swiotlb.c | 6 +-
> kernel/fork.c | 3 +-
> kernel/nsproxy.c | 2 +-
> kernel/sched/ext/ext.c | 25 +-
> kernel/sched/ext/internal.h | 5 +
> kernel/sched/sched.h | 1 -
> kernel/workqueue.c | 2 +-
> lib/dim/dim.c | 10 +-
> mm/mremap.c | 70 ++++--
> mm/pgtable-generic.c | 20 +-
> mm/vma.c | 21 +-
> mm/vma.h | 7 +-
> net/bluetooth/hci_core.c | 4 +
> net/bluetooth/hci_sock.c | 2 +
> net/bluetooth/hci_sync.c | 10 +-
> net/bluetooth/iso.c | 52 ++++-
> net/bluetooth/mgmt.c | 2 +-
> net/bluetooth/rfcomm/core.c | 134 +++++++----
> net/bluetooth/rfcomm/sock.c | 5 +-
> net/bluetooth/rfcomm/tty.c | 2 +-
> net/bluetooth/sco.c | 87 +++++--
> net/bridge/br_multicast.c | 23 +-
> net/bridge/netfilter/nf_conntrack_bridge.c | 10 +-
> net/can/af_can.c | 47 +++-
> net/can/gw.c | 3 +
> net/can/isotp.c | 16 +-
> net/can/raw.c | 10 +-
> net/core/dev.c | 11 +-
> net/core/flow_dissector.c | 11 +-
> net/core/skbuff.c | 6 +-
> net/devlink/core.c | 10 +-
> net/ipv4/cipso_ipv4.c | 8 +
> net/ipv4/fib_semantics.c | 3 +
> net/ipv4/fib_trie.c | 2 -
> net/ipv4/ip_output.c | 10 +-
> net/ipv4/route.c | 5 +
> net/ipv4/tcp.c | 2 +
> net/ipv4/udp.c | 11 +
> net/ipv6/ip6_gre.c | 7 -
> net/ipv6/route.c | 4 +-
> net/ipv6/udp.c | 13 ++
> net/mac80211/debugfs.c | 13 +-
> net/mac80211/ieee80211_i.h | 2 +
> net/mac80211/main.c | 1 +
> net/mac80211/sta_info.c | 17 +-
> net/mac80211/sta_info.h | 3 +-
> net/mac80211/status.c | 5 +-
> net/mac80211/tx.c | 70 ++++--
> net/netfilter/nfnetlink_queue.c | 7 +
> net/netfilter/xt_CHECKSUM.c | 6 +-
> net/openvswitch/actions.c | 7 +-
> net/openvswitch/datapath.c | 8 +
> net/packet/af_packet.c | 28 ++-
> net/sched/cls_route.c | 6 +
> net/sched/em_text.c | 3 +
> net/sctp/socket.c | 6 +-
> net/smc/af_smc.c | 7 +-
> net/strparser/strparser.c | 6 +-
> net/tipc/node.c | 10 +-
> net/tipc/topsrv.c | 80 +++++--
> net/vmw_vsock/af_vsock.c | 2 +
> net/vmw_vsock/virtio_transport_common.c | 4 +-
> net/xfrm/xfrm_output.c | 16 +-
> security/keys/key.c | 6 +-
> security/keys/persistent.c | 55 +++--
> security/selinux/avc.c | 5 +-
> security/selinux/hooks.c | 9 +-
> sound/hda/codecs/side-codecs/tas2781_hda.c | 18 +-
> sound/pci/ctxfi/ctdaio.c | 6 +-
> sound/soc/amd/yc/acp6x-mach.c | 7 +
> sound/soc/codecs/adau1372.c | 18 +-
> sound/soc/samsung/i2s.c | 8 +
> sound/soc/sdw_utils/soc_sdw_utils.c | 35 ++-
> tools/testing/selftests/mm/hugetlb-mmap.c | 4 +-
> tools/testing/vma/tests/vma.c | 4 +-
> 289 files changed, 3322 insertions(+), 1484 deletions(-)
>
>
--
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 291+ messages in thread* Re: [PATCH 7.2 000/281] 7.2.11-rc1 review
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (281 preceding siblings ...)
2026-10-13 13:23 ` [PATCH 7.2 000/281] 7.2.11-rc1 review Pavel Machek
@ 2026-10-13 16:30 ` Ronald Warsow
2026-10-13 17:03 ` Miguel Ojeda
` (4 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Ronald Warsow @ 2026-10-13 16:30 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
conor, hargar, broonie, achill, sr
Hi
kernel build / boot test on x86_64 (Intel).
No regressions here.
Thanks
Tested-by: Ronald Warsow <rwarsow@gmx.de>
^ permalink raw reply [flat|nested] 291+ messages in thread* Re: [PATCH 7.2 000/281] 7.2.11-rc1 review
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (282 preceding siblings ...)
2026-10-13 16:30 ` Ronald Warsow
@ 2026-10-13 17:03 ` Miguel Ojeda
2026-10-13 19:47 ` Florian Fainelli
` (3 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Miguel Ojeda @ 2026-10-13 17:03 UTC (permalink / raw)
To: gregkh
Cc: achill, akpm, broonie, conor, f.fainelli, hargar, jonathanh,
linux-kernel, linux, lkft-triage, patches, patches, pavel,
rwarsow, shuah, sr, stable, sudipm.mukherjee, torvalds,
Miguel Ojeda
On Tue, 13 Oct 2026 13:35:16 +0200 Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
>
> This is the start of the stable review cycle for the 7.2.11 release.
> There are 281 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 15 Oct 2026 11:28:22 +0000.
> Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64, arm64; built-tested for loongarch64
and arm32:
Tested-by: Miguel Ojeda <ojeda@kernel.org>
riscv64 fails (as mentioned in the patch).
Thanks!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 291+ messages in thread* Re: [PATCH 7.2 000/281] 7.2.11-rc1 review
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (283 preceding siblings ...)
2026-10-13 17:03 ` Miguel Ojeda
@ 2026-10-13 19:47 ` Florian Fainelli
2026-10-13 21:23 ` Peter Schneider
` (2 subsequent siblings)
287 siblings, 0 replies; 291+ messages in thread
From: Florian Fainelli @ 2026-10-13 19:47 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, sudipm.mukherjee, rwarsow, conor,
hargar, broonie, achill, sr
On 10/13/26 04:35, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 7.2.11 release.
> There are 281 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 15 Oct 2026 11:28:22 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v7.x/stable-review/patch-7.2.11-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-7.2.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on
BMIPS_GENERIC:
Tested-by: Florian Fainelli <florian.fainelli@broadcom.com>
--
Florian
^ permalink raw reply [flat|nested] 291+ messages in thread* Re: [PATCH 7.2 000/281] 7.2.11-rc1 review
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (284 preceding siblings ...)
2026-10-13 19:47 ` Florian Fainelli
@ 2026-10-13 21:23 ` Peter Schneider
2026-10-13 22:22 ` Shuah Khan
2026-10-13 22:27 ` Justin Forbes
287 siblings, 0 replies; 291+ messages in thread
From: Peter Schneider @ 2026-10-13 21:23 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
rwarsow, conor, hargar, broonie, achill, sr
Am 13.10.2026 um 13:35 schrieb Greg Kroah-Hartman:
> This is the start of the stable review cycle for the 7.2.11 release.
> There are 281 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697v2 server. No dmesg oddities or regressions found.
Tested-by: Peter Schneider <pschneider1968@googlemail.com>
Beste Grüße,
Peter Schneider
--
Climb the mountain not to plant your flag, but to embrace the challenge,
enjoy the air and behold the view. Climb it so you can see the world,
not so the world can see you. -- David McCullough Jr.
OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244
Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc
https://keys.mailvelope.com/pks/lookup?op=get&search=pschneider1968@googlemail.com
https://keys.mailvelope.com/pks/lookup?op=get&search=pschneider1968@gmail.com
^ permalink raw reply [flat|nested] 291+ messages in thread* Re: [PATCH 7.2 000/281] 7.2.11-rc1 review
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (285 preceding siblings ...)
2026-10-13 21:23 ` Peter Schneider
@ 2026-10-13 22:22 ` Shuah Khan
2026-10-13 22:27 ` Justin Forbes
287 siblings, 0 replies; 291+ messages in thread
From: Shuah Khan @ 2026-10-13 22:22 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
rwarsow, conor, hargar, broonie, achill, sr, Shuah Khan
On 10/13/26 05:35, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 7.2.11 release.
> There are 281 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 15 Oct 2026 11:28:22 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v7.x/stable-review/patch-7.2.11-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-7.2.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
>
Compiled and booted on my test system. No dmesg regressions.
Tested-by: Shuah Khan <skhan@linuxfoundation.org>
thanks,
-- Shuah
^ permalink raw reply [flat|nested] 291+ messages in thread* Re: [PATCH 7.2 000/281] 7.2.11-rc1 review
2026-10-13 11:35 [PATCH 7.2 000/281] 7.2.11-rc1 review Greg Kroah-Hartman
` (286 preceding siblings ...)
2026-10-13 22:22 ` Shuah Khan
@ 2026-10-13 22:27 ` Justin Forbes
287 siblings, 0 replies; 291+ messages in thread
From: Justin Forbes @ 2026-10-13 22:27 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
On Tue, Oct 13, 2026 at 01:35:16PM +0200, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 7.2.11 release.
> There are 281 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 15 Oct 2026 11:28:22 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v7.x/stable-review/patch-7.2.11-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-7.2.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
Tested rc1 against the Fedora build system (aarch64, ppc64le, s390x,
x86_64), and boot tested x86_64. No regressions noted.
Tested-by: Justin M. Forbes <jforbes@fedoraproject.org>
^ permalink raw reply [flat|nested] 291+ messages in thread