--- /dev/null
+From feb6a428abd6148be60e7e5789455671b7111e0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+ struct atmtcp_control {
+ struct atmtcp_hdr hdr; /* must be first */
+ ...
+ atm_kptr_t vcc; /* both directions */
+ ...
+ } __ATM_API_ALIGN;
+
+ typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+ 1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+ 2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS: 00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x19b/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c | 17 ++++++++++++++---
+ include/linux/atmdev.h | 1 +
+ net/atm/common.c | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index ff558908897f3..9c83fb29b2f1b 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+ return NULL;
+ }
+
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++ struct atmtcp_hdr *hdr;
++
++ if (skb->len < sizeof(struct atmtcp_hdr))
++ return -EINVAL;
++
++ hdr = (struct atmtcp_hdr *)skb->data;
++ if (hdr->length == ATMTCP_HDR_MAGIC)
++ return -EINVAL;
++
++ return 0;
++}
+
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ struct sk_buff *new_skb;
+ int result = 0;
+
+- if (skb->len < sizeof(struct atmtcp_hdr))
+- goto done;
+-
+ dev = vcc->dev_data;
+ hdr = (struct atmtcp_hdr *) skb->data;
+ if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+ .close = atmtcp_c_close,
++ .pre_send = atmtcp_c_pre_send,
+ .send = atmtcp_c_send
+ };
+
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index bc24d19ec2b37..8cbb992f6293c 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+ int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+ void __user *arg);
+ #endif
++ int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+ int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+ void (*phy_put)(struct atm_dev *dev,unsigned char value,
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 930eb302cd10f..38ed7b985f655 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+
+ skb->dev = NULL; /* for paths shared with net_device interfaces */
+ if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+- atm_return_tx(vcc, skb);
+- kfree_skb(skb);
+ error = -EFAULT;
+- goto out;
++ goto free_skb;
+ }
+ if (eff != size)
+ memset(skb->data + size, 0, eff-size);
++
++ if (vcc->dev->ops->pre_send) {
++ error = vcc->dev->ops->pre_send(vcc, skb);
++ if (error)
++ goto free_skb;
++ }
++
+ error = vcc->dev->ops->send(vcc, skb);
+ error = error ? error : size;
+ out:
+ release_sock(sk);
+ return error;
++free_skb:
++ atm_return_tx(vcc, skb);
++ kfree_skb(skb);
++ goto out;
+ }
+
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+--
+2.50.1
+
--- /dev/null
+From c32f5b807b15b29b9216e66837ae79ead6b3d1ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 7f26c1aab9a06..c6dbb4aebfbc1 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3811,7 +3811,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+ if (!conn)
+ continue;
+
+- conn->sent -= count;
++ /* Check if there is really enough packets outstanding before
++ * attempting to decrease the sent counter otherwise it could
++ * underflow..
++ */
++ if (conn->sent >= count) {
++ conn->sent -= count;
++ } else {
++ bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++ conn, conn->sent, count);
++ conn->sent = 0;
++ }
+
+ switch (conn->type) {
+ case ACL_LINK:
+--
+2.50.1
+
--- /dev/null
+From 46f2e902822a9af3b36ff11a7d7ec6f19e059c7f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+ BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+ Call trace:
+ kasan_check_range+0xe8/0x190
+ __asan_loadN+0x1c/0x28
+ memcmp+0x98/0xd0
+ efivarfs_d_compare+0x68/0xd8
+ __d_lookup_rcu_op_compare+0x178/0x218
+ __d_lookup_rcu+0x1f8/0x228
+ d_alloc_parallel+0x150/0x648
+ lookup_open.isra.0+0x5f0/0x8d0
+ open_last_lookups+0x264/0x828
+ path_openat+0x130/0x3f8
+ do_filp_open+0x114/0x248
+ do_sys_openat2+0x340/0x3c0
+ __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+ T1 T2
+ lookup_open
+ ->lookup
+ simple_lookup
+ d_add
+ // invalid dentry is added to hash list
+
+ lookup_open
+ d_alloc_parallel
+ __d_lookup_rcu
+ __d_lookup_rcu_op_compare
+ hlist_bl_for_each_entry_rcu
+ // invalid dentry can be retrieved
+ ->d_compare
+ efivarfs_d_compare
+ // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 99d002438008b..124db520b2bd6 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -47,6 +47,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+ int guid = len - EFI_VARIABLE_GUID_LEN;
+
++ /* Parallel lookups may produce a temporary invalid filename */
++ if (guid <= 0)
++ return 1;
++
+ if (name->len != len)
+ return 1;
+
+--
+2.50.1
+
--- /dev/null
+From 3fe83a12405c50dbc0093f021716355383bb1239 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index b7f992103da3c..af1e96e0209fc 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1095,7 +1095,7 @@ get_stats (struct net_device *dev)
+ dev->stats.rx_bytes += dr32(OctetRcvOk);
+ dev->stats.tx_bytes += dr32(OctetXmtOk);
+
+- dev->stats.multicast = dr32(McstFramesRcvdOk);
++ dev->stats.multicast += dr32(McstFramesRcvdOk);
+ dev->stats.collisions += dr32(SingleColFrames)
+ + dr32(MultiColFrames);
+
+--
+2.50.1
+
--- /dev/null
+From 8c68cde06a0e806946122a7dc33ae099c05b6902 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 7c4479adbf325..fbaed08600f0f 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2452,12 +2452,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+ !netif_is_l3_master(dev_out))
+ return ERR_PTR(-EINVAL);
+
+- if (ipv4_is_lbcast(fl4->daddr))
++ if (ipv4_is_lbcast(fl4->daddr)) {
+ type = RTN_BROADCAST;
+- else if (ipv4_is_multicast(fl4->daddr))
++
++ /* reset fi to prevent gateway resolution */
++ fi = NULL;
++ } else if (ipv4_is_multicast(fl4->daddr)) {
+ type = RTN_MULTICAST;
+- else if (ipv4_is_zeronet(fl4->daddr))
++ } else if (ipv4_is_zeronet(fl4->daddr)) {
+ return ERR_PTR(-EINVAL);
++ }
+
+ if (dev_out->flags & IFF_LOOPBACK)
+ flags |= RTCF_LOCAL;
+--
+2.50.1
+
--- /dev/null
+From d0049c813edf1f7090ac77f2be2f1367ac0478bc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@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/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index c9d5d8d93994d..7899a7230299d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -346,7 +346,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ if (err)
+ return err;
+ }
+- priv->dcbx.xoff = xoff;
+
+ /* Apply the settings */
+ if (update_buffer) {
+@@ -355,6 +354,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ return err;
+ }
+
++ priv->dcbx.xoff = xoff;
++
+ if (update_prio2buffer)
+ err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+
+--
+2.50.1
+
--- /dev/null
+From 68c45b5d4899aecf1373f6c532344d8b8818d056 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+index 80af7a5ac6046..a23e3d810f3e4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -63,11 +63,23 @@ struct mlx5e_port_buffer {
+ struct mlx5e_bufferx_reg buffer[MLX5E_MAX_BUFFER];
+ };
+
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ u32 change, unsigned int mtu,
+ struct ieee_pfc *pfc,
+ u32 *buffer_size,
+ u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++ u32 change, unsigned int mtu,
++ void *pfc,
++ u32 *buffer_size,
++ u8 *prio2buffer)
++{
++ return 0;
++}
++#endif
+
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+ struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index c3ff1fc577a7c..cef60bc2589cc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -42,6 +42,7 @@
+ #include "eswitch.h"
+ #include "en.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2874,9 +2875,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ struct mlx5e_params *params = &priv->channels.params;
+ struct net_device *netdev = priv->netdev;
+ struct mlx5_core_dev *mdev = priv->mdev;
+- u16 mtu;
++ u16 mtu, prev_mtu;
+ int err;
+
++ mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+ err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+ if (err)
+ return err;
+@@ -2886,6 +2889,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+ __func__, mtu, params->sw_mtu);
+
++ if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++ err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++ NULL, NULL, NULL);
++ if (err) {
++ netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++ __func__, mtu, err, prev_mtu);
++
++ mlx5e_set_mtu(mdev, params, prev_mtu);
++ return err;
++ }
++ }
++
+ params->sw_mtu = mtu;
+ return 0;
+ }
+--
+2.50.1
+
--- /dev/null
+From e771bc39e892fe3eb9efb178f4613876b5e946d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@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_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index cef60bc2589cc..cc93c503984a1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -141,6 +141,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+ if (port_state == VPORT_STATE_UP) {
+ netdev_info(priv->netdev, "Link up\n");
+ netif_carrier_on(priv->netdev);
++ mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++ NULL, NULL, NULL);
+ } else {
+ netdev_info(priv->netdev, "Link down\n");
+ netif_carrier_off(priv->netdev);
+--
+2.50.1
+
--- /dev/null
+From 44900a377bd65e613869bfc5da8caff4955d6a4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index a5583d706b9f2..e30bbe1933ec8 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -199,10 +199,6 @@ static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
+ }
+
+ writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+- /* Enable MTL RX overflow */
+- value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+- writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+
+ static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
+--
+2.50.1
+
--- /dev/null
+From 365ebd7126b79065e7b9416343e990f854237b68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index d89cf802d9aa7..8067641561a4f 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+ }
+
+- switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++ switch (inst_no_rt & ~KVM_MASK_RB) {
+ case KVM_INST_MTSRIN:
+ if (features & KVM_MAGIC_FEAT_SR) {
+ u32 inst_rb = _inst & KVM_MASK_RB;
+ kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+ }
+ break;
+-#endif
+ }
++#endif
+
+- switch (_inst) {
+ #ifdef CONFIG_BOOKE
++ switch (_inst) {
+ case KVM_INST_WRTEEI_0:
+ kvm_patch_ins_wrteei_0(inst);
+ break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ case KVM_INST_WRTEEI_1:
+ kvm_patch_ins_wrtee(inst, 0, 1);
+ break;
+-#endif
+ }
++#endif
+ }
+
+ extern u32 kvm_template_start[];
+--
+2.50.1
+
--- /dev/null
+From 76e8d36a4f53030ffd449407fbcc0fe23253bfa8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+ sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+ sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+ sctp_get_port net/sctp/socket.c:8523 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+ x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+ sctp_get_port net/sctp/socket.c:8515 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index d594b949ae82f..a9cfe4d62df83 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -499,7 +499,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+ addr->v6.sin6_family = AF_INET6;
+ addr->v6.sin6_port = 0;
++ addr->v6.sin6_flowinfo = 0;
+ addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++ addr->v6.sin6_scope_id = 0;
+ }
+
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+--
+2.50.1
+
nfs-fold-nfs_page_group_lock_subrequests-into-nfs_lock_and_join_requests.patch
nfs-fix-a-race-when-updating-an-existing-write.patch
vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
--- /dev/null
+From 18026b07fcd6b2a9975264ddab50cd935daea54a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+ struct atmtcp_control {
+ struct atmtcp_hdr hdr; /* must be first */
+ ...
+ atm_kptr_t vcc; /* both directions */
+ ...
+ } __ATM_API_ALIGN;
+
+ typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+ 1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+ 2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS: 00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x19b/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c | 17 ++++++++++++++---
+ include/linux/atmdev.h | 1 +
+ net/atm/common.c | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index ff558908897f3..9c83fb29b2f1b 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+ return NULL;
+ }
+
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++ struct atmtcp_hdr *hdr;
++
++ if (skb->len < sizeof(struct atmtcp_hdr))
++ return -EINVAL;
++
++ hdr = (struct atmtcp_hdr *)skb->data;
++ if (hdr->length == ATMTCP_HDR_MAGIC)
++ return -EINVAL;
++
++ return 0;
++}
+
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ struct sk_buff *new_skb;
+ int result = 0;
+
+- if (skb->len < sizeof(struct atmtcp_hdr))
+- goto done;
+-
+ dev = vcc->dev_data;
+ hdr = (struct atmtcp_hdr *) skb->data;
+ if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+ .close = atmtcp_c_close,
++ .pre_send = atmtcp_c_pre_send,
+ .send = atmtcp_c_send
+ };
+
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8..70807c679f1ab 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+ int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+ void __user *arg);
+ #endif
++ int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+ int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 930eb302cd10f..38ed7b985f655 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+
+ skb->dev = NULL; /* for paths shared with net_device interfaces */
+ if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+- atm_return_tx(vcc, skb);
+- kfree_skb(skb);
+ error = -EFAULT;
+- goto out;
++ goto free_skb;
+ }
+ if (eff != size)
+ memset(skb->data + size, 0, eff-size);
++
++ if (vcc->dev->ops->pre_send) {
++ error = vcc->dev->ops->pre_send(vcc, skb);
++ if (error)
++ goto free_skb;
++ }
++
+ error = vcc->dev->ops->send(vcc, skb);
+ error = error ? error : size;
+ out:
+ release_sock(sk);
+ return error;
++free_skb:
++ atm_return_tx(vcc, skb);
++ kfree_skb(skb);
++ goto out;
+ }
+
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+--
+2.50.1
+
--- /dev/null
+From c886599c79dfcda729ed09a3aa8a25175ac577f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 84b07b27b3cf4..cfdaaecf78600 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3919,7 +3919,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+ if (!conn)
+ continue;
+
+- conn->sent -= count;
++ /* Check if there is really enough packets outstanding before
++ * attempting to decrease the sent counter otherwise it could
++ * underflow..
++ */
++ if (conn->sent >= count) {
++ conn->sent -= count;
++ } else {
++ bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++ conn, conn->sent, count);
++ conn->sent = 0;
++ }
+
+ switch (conn->type) {
+ case ACL_LINK:
+--
+2.50.1
+
--- /dev/null
+From 04e740b4dfd074a755299a16dc8394497e284442 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+ BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+ Call trace:
+ kasan_check_range+0xe8/0x190
+ __asan_loadN+0x1c/0x28
+ memcmp+0x98/0xd0
+ efivarfs_d_compare+0x68/0xd8
+ __d_lookup_rcu_op_compare+0x178/0x218
+ __d_lookup_rcu+0x1f8/0x228
+ d_alloc_parallel+0x150/0x648
+ lookup_open.isra.0+0x5f0/0x8d0
+ open_last_lookups+0x264/0x828
+ path_openat+0x130/0x3f8
+ do_filp_open+0x114/0x248
+ do_sys_openat2+0x340/0x3c0
+ __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+ T1 T2
+ lookup_open
+ ->lookup
+ simple_lookup
+ d_add
+ // invalid dentry is added to hash list
+
+ lookup_open
+ d_alloc_parallel
+ __d_lookup_rcu
+ __d_lookup_rcu_op_compare
+ hlist_bl_for_each_entry_rcu
+ // invalid dentry can be retrieved
+ ->d_compare
+ efivarfs_d_compare
+ // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 99d002438008b..124db520b2bd6 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -47,6 +47,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+ int guid = len - EFI_VARIABLE_GUID_LEN;
+
++ /* Parallel lookups may produce a temporary invalid filename */
++ if (guid <= 0)
++ return 1;
++
+ if (name->len != len)
+ return 1;
+
+--
+2.50.1
+
--- /dev/null
+From 631de0a7006b7a2bf147157adf4e531c3087fca6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index 09a275eb44487..81395852b4d43 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1095,7 +1095,7 @@ get_stats (struct net_device *dev)
+ dev->stats.rx_bytes += dr32(OctetRcvOk);
+ dev->stats.tx_bytes += dr32(OctetXmtOk);
+
+- dev->stats.multicast = dr32(McstFramesRcvdOk);
++ dev->stats.multicast += dr32(McstFramesRcvdOk);
+ dev->stats.collisions += dr32(SingleColFrames)
+ + dr32(MultiColFrames);
+
+--
+2.50.1
+
--- /dev/null
+From 6666f564e6dc3bc10eb0247005b47faff923759a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index df4cbf9ba288f..b24de1c67d0c2 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2552,12 +2552,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+ !netif_is_l3_master(dev_out))
+ return ERR_PTR(-EINVAL);
+
+- if (ipv4_is_lbcast(fl4->daddr))
++ if (ipv4_is_lbcast(fl4->daddr)) {
+ type = RTN_BROADCAST;
+- else if (ipv4_is_multicast(fl4->daddr))
++
++ /* reset fi to prevent gateway resolution */
++ fi = NULL;
++ } else if (ipv4_is_multicast(fl4->daddr)) {
+ type = RTN_MULTICAST;
+- else if (ipv4_is_zeronet(fl4->daddr))
++ } else if (ipv4_is_zeronet(fl4->daddr)) {
+ return ERR_PTR(-EINVAL);
++ }
+
+ if (dev_out->flags & IFF_LOOPBACK)
+ flags |= RTCF_LOCAL;
+--
+2.50.1
+
--- /dev/null
+From ef84cd46f5974a389e2183063b47367c3de2d8b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@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/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index c9d5d8d93994d..7899a7230299d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -346,7 +346,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ if (err)
+ return err;
+ }
+- priv->dcbx.xoff = xoff;
+
+ /* Apply the settings */
+ if (update_buffer) {
+@@ -355,6 +354,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ return err;
+ }
+
++ priv->dcbx.xoff = xoff;
++
+ if (update_prio2buffer)
+ err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+
+--
+2.50.1
+
--- /dev/null
+From 7d673e811f13804fda8f0874d49487abf56a521e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+index 80af7a5ac6046..a23e3d810f3e4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -63,11 +63,23 @@ struct mlx5e_port_buffer {
+ struct mlx5e_bufferx_reg buffer[MLX5E_MAX_BUFFER];
+ };
+
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ u32 change, unsigned int mtu,
+ struct ieee_pfc *pfc,
+ u32 *buffer_size,
+ u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++ u32 change, unsigned int mtu,
++ void *pfc,
++ u32 *buffer_size,
++ u8 *prio2buffer)
++{
++ return 0;
++}
++#endif
+
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+ struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 321441e6ad328..bb7e3c80ad74e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -42,6 +42,7 @@
+ #include "eswitch.h"
+ #include "en.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2242,9 +2243,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ struct mlx5e_params *params = &priv->channels.params;
+ struct net_device *netdev = priv->netdev;
+ struct mlx5_core_dev *mdev = priv->mdev;
+- u16 mtu;
++ u16 mtu, prev_mtu;
+ int err;
+
++ mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+ err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+ if (err)
+ return err;
+@@ -2254,6 +2257,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+ __func__, mtu, params->sw_mtu);
+
++ if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++ err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++ NULL, NULL, NULL);
++ if (err) {
++ netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++ __func__, mtu, err, prev_mtu);
++
++ mlx5e_set_mtu(mdev, params, prev_mtu);
++ return err;
++ }
++ }
++
+ params->sw_mtu = mtu;
+ return 0;
+ }
+--
+2.50.1
+
--- /dev/null
+From 41ed1b2b238aa0c45ab2d6ca606542ec374a75cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@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_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index bb7e3c80ad74e..cfbc569edfb5f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -104,6 +104,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+ if (up) {
+ netdev_info(priv->netdev, "Link up\n");
+ netif_carrier_on(priv->netdev);
++ mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++ NULL, NULL, NULL);
+ } else {
+ netdev_info(priv->netdev, "Link down\n");
+ netif_carrier_off(priv->netdev);
+--
+2.50.1
+
--- /dev/null
+From 17dcb63450422550503507a8ba929ee9fd226c1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 5e98355f422b3..3e4318d5dcdf5 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -199,10 +199,6 @@ static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
+ }
+
+ writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+- /* Enable MTL RX overflow */
+- value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+- writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+
+ static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
+--
+2.50.1
+
--- /dev/null
+From 1ef13ace52d87b240f4952102c94c0173a41e31c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:55:43 +0200
+Subject: phy: mscc: Fix when PTP clock is register and unregister
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]
+
+It looks like that every time when the interface was set down and up the
+driver was creating a new ptp clock. On top of this the function
+ptp_clock_unregister was never called.
+Therefore fix this by calling ptp_clock_register and initialize the
+mii_ts struct inside the probe function and call ptp_clock_unregister when
+driver is removed.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h | 4 ++++
+ drivers/net/phy/mscc/mscc_main.c | 4 +---
+ drivers/net/phy/mscc/mscc_ptp.c | 34 ++++++++++++++++++++------------
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index 878298304430c..fcfbff691b3c6 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -474,6 +474,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -488,6 +489,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
+ {
+ return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+ return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index 03aa85ec60dfc..982e73adf2bcf 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2326,9 +2326,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+- struct vsc8531_private *priv = phydev->priv;
+-
+- skb_queue_purge(&priv->rx_skbs_list);
++ vsc8584_ptp_deinit(phydev);
+ }
+
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index f77bfbee5f20b..e30e6ba9da2f4 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1294,7 +1294,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+- struct vsc8531_private *vsc8531 = phydev->priv;
+ static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+ static const u8 ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+ u32 val;
+@@ -1511,17 +1510,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+
+ vsc85xx_ts_eth_cmp1_sig(phydev);
+
+- vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+- vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+- vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+- vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
+- phydev->mii_ts = &vsc8531->mii_ts;
+-
+- memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+-
+- vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+- &phydev->mdio.dev);
+- return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++ return 0;
+ }
+
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1548,6 +1537,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+ return 0;
+ }
+
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++ struct vsc8531_private *vsc8531 = phydev->priv;
++
++ if (vsc8531->ptp->ptp_clock) {
++ ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++ skb_queue_purge(&vsc8531->rx_skbs_list);
++ }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+ struct vsc8531_private *priv = phydev->priv;
+@@ -1605,7 +1604,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+
+ vsc8531->ptp->phydev = phydev;
+
+- return 0;
++ vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++ vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++ vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++ vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
++ phydev->mii_ts = &vsc8531->mii_ts;
++
++ memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
++ vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++ &phydev->mdio.dev);
++ return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+--
+2.50.1
+
--- /dev/null
+From bbb8d2abdf55950847e3450f7463eea454664e61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 6568823cf3063..5d9d38834507d 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+ }
+
+- switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++ switch (inst_no_rt & ~KVM_MASK_RB) {
+ case KVM_INST_MTSRIN:
+ if (features & KVM_MAGIC_FEAT_SR) {
+ u32 inst_rb = _inst & KVM_MASK_RB;
+ kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+ }
+ break;
+-#endif
+ }
++#endif
+
+- switch (_inst) {
+ #ifdef CONFIG_BOOKE
++ switch (_inst) {
+ case KVM_INST_WRTEEI_0:
+ kvm_patch_ins_wrteei_0(inst);
+ break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ case KVM_INST_WRTEEI_1:
+ kvm_patch_ins_wrtee(inst, 0, 1);
+ break;
+-#endif
+ }
++#endif
+ }
+
+ extern u32 kvm_template_start[];
+--
+2.50.1
+
--- /dev/null
+From 7168fc6bd436b474e4170fc54d6a3d426c42399c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+ sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+ sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+ sctp_get_port net/sctp/socket.c:8523 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+ x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+ sctp_get_port net/sctp/socket.c:8515 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 470dbdc27d584..107255d92037f 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -547,7 +547,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+ addr->v6.sin6_family = AF_INET6;
+ addr->v6.sin6_port = 0;
++ addr->v6.sin6_flowinfo = 0;
+ addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++ addr->v6.sin6_scope_id = 0;
+ }
+
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+--
+2.50.1
+
nfs-fold-nfs_page_group_lock_subrequests-into-nfs_lock_and_join_requests.patch
nfs-fix-a-race-when-updating-an-existing-write.patch
vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
--- /dev/null
+From 51d4666edc74dbd1eee81b83126369380eaa2160 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+ struct atmtcp_control {
+ struct atmtcp_hdr hdr; /* must be first */
+ ...
+ atm_kptr_t vcc; /* both directions */
+ ...
+ } __ATM_API_ALIGN;
+
+ typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+ 1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+ 2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS: 00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x19b/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c | 17 ++++++++++++++---
+ include/linux/atmdev.h | 1 +
+ net/atm/common.c | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index afc1af542c3b5..c6915c5effbd7 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+ return NULL;
+ }
+
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++ struct atmtcp_hdr *hdr;
++
++ if (skb->len < sizeof(struct atmtcp_hdr))
++ return -EINVAL;
++
++ hdr = (struct atmtcp_hdr *)skb->data;
++ if (hdr->length == ATMTCP_HDR_MAGIC)
++ return -EINVAL;
++
++ return 0;
++}
+
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ struct sk_buff *new_skb;
+ int result = 0;
+
+- if (skb->len < sizeof(struct atmtcp_hdr))
+- goto done;
+-
+ dev = vcc->dev_data;
+ hdr = (struct atmtcp_hdr *) skb->data;
+ if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static struct atmdev_ops atmtcp_v_dev_ops = {
+
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+ .close = atmtcp_c_close,
++ .pre_send = atmtcp_c_pre_send,
+ .send = atmtcp_c_send
+ };
+
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index bc24d19ec2b37..8cbb992f6293c 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+ int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+ void __user *arg);
+ #endif
++ int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+ int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+ void (*phy_put)(struct atm_dev *dev,unsigned char value,
+diff --git a/net/atm/common.c b/net/atm/common.c
+index a51994aba34c4..59b61886629e6 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+
+ skb->dev = NULL; /* for paths shared with net_device interfaces */
+ if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+- atm_return_tx(vcc, skb);
+- kfree_skb(skb);
+ error = -EFAULT;
+- goto out;
++ goto free_skb;
+ }
+ if (eff != size)
+ memset(skb->data + size, 0, eff-size);
++
++ if (vcc->dev->ops->pre_send) {
++ error = vcc->dev->ops->pre_send(vcc, skb);
++ if (error)
++ goto free_skb;
++ }
++
+ error = vcc->dev->ops->send(vcc, skb);
+ error = error ? error : size;
+ out:
+ release_sock(sk);
+ return error;
++free_skb:
++ atm_return_tx(vcc, skb);
++ kfree_skb(skb);
++ goto out;
+ }
+
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+--
+2.50.1
+
--- /dev/null
+From 7a268e98cab1fe76fe4d1519de97acdff4fb12e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 33b025a52b83a..4e8911501255d 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3681,7 +3681,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+ if (!conn)
+ continue;
+
+- conn->sent -= count;
++ /* Check if there is really enough packets outstanding before
++ * attempting to decrease the sent counter otherwise it could
++ * underflow..
++ */
++ if (conn->sent >= count) {
++ conn->sent -= count;
++ } else {
++ bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++ conn, conn->sent, count);
++ conn->sent = 0;
++ }
+
+ switch (conn->type) {
+ case ACL_LINK:
+--
+2.50.1
+
--- /dev/null
+From dd55ca1d46c176720dfa0e02a0e3f1961613e275 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+ BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+ Call trace:
+ kasan_check_range+0xe8/0x190
+ __asan_loadN+0x1c/0x28
+ memcmp+0x98/0xd0
+ efivarfs_d_compare+0x68/0xd8
+ __d_lookup_rcu_op_compare+0x178/0x218
+ __d_lookup_rcu+0x1f8/0x228
+ d_alloc_parallel+0x150/0x648
+ lookup_open.isra.0+0x5f0/0x8d0
+ open_last_lookups+0x264/0x828
+ path_openat+0x130/0x3f8
+ do_filp_open+0x114/0x248
+ do_sys_openat2+0x340/0x3c0
+ __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+ T1 T2
+ lookup_open
+ ->lookup
+ simple_lookup
+ d_add
+ // invalid dentry is added to hash list
+
+ lookup_open
+ d_alloc_parallel
+ __d_lookup_rcu
+ __d_lookup_rcu_op_compare
+ hlist_bl_for_each_entry_rcu
+ // invalid dentry can be retrieved
+ ->d_compare
+ efivarfs_d_compare
+ // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index d12a21b2dd9d0..0f3d3d96599b8 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -46,6 +46,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+ int guid = len - EFI_VARIABLE_GUID_LEN;
+
++ /* Parallel lookups may produce a temporary invalid filename */
++ if (guid <= 0)
++ return 1;
++
+ if (name->len != len)
+ return 1;
+
+--
+2.50.1
+
--- /dev/null
+From 7461361c85f5aeecb6c604601f57b40cb416c6ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2020 08:23:10 +0200
+Subject: net/atm: remove the atmdev_ops {get, set}sockopt methods
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit a06d30ae7af492497ffbca6abf1621d508b8fcaa ]
+
+All implementations of these two methods are dummies that always
+return -EINVAL.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: ec79003c5f9d ("atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/eni.c | 17 -----------------
+ drivers/atm/firestream.c | 2 --
+ drivers/atm/fore200e.c | 27 ---------------------------
+ drivers/atm/horizon.c | 40 ----------------------------------------
+ drivers/atm/iphase.c | 16 ----------------
+ drivers/atm/lanai.c | 2 --
+ drivers/atm/solos-pci.c | 2 --
+ drivers/atm/zatm.c | 16 ----------------
+ include/linux/atmdev.h | 9 ---------
+ net/atm/common.c | 14 ++------------
+ 10 files changed, 2 insertions(+), 143 deletions(-)
+
+diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
+index 4816db0553ef8..0f082bd626543 100644
+--- a/drivers/atm/eni.c
++++ b/drivers/atm/eni.c
+@@ -2035,21 +2035,6 @@ static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
+ return dev->phy->ioctl(dev,cmd,arg);
+ }
+
+-
+-static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,
+- void __user *optval,int optlen)
+-{
+- return -EINVAL;
+-}
+-
+-
+-static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
+- void __user *optval,unsigned int optlen)
+-{
+- return -EINVAL;
+-}
+-
+-
+ static int eni_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+ enum enq_res res;
+@@ -2223,8 +2208,6 @@ static const struct atmdev_ops ops = {
+ .open = eni_open,
+ .close = eni_close,
+ .ioctl = eni_ioctl,
+- .getsockopt = eni_getsockopt,
+- .setsockopt = eni_setsockopt,
+ .send = eni_send,
+ .phy_put = eni_phy_put,
+ .phy_get = eni_phy_get,
+diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
+index 8995c39330fac..c7c3aeecd1c61 100644
+--- a/drivers/atm/firestream.c
++++ b/drivers/atm/firestream.c
+@@ -1278,8 +1278,6 @@ static const struct atmdev_ops ops = {
+ .send = fs_send,
+ .owner = THIS_MODULE,
+ /* ioctl: fs_ioctl, */
+- /* getsockopt: fs_getsockopt, */
+- /* setsockopt: fs_setsockopt, */
+ /* change_qos: fs_change_qos, */
+
+ /* For now implement these internally here... */
+diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
+index 8fbd36eb89410..a36f555cc0403 100644
+--- a/drivers/atm/fore200e.c
++++ b/drivers/atm/fore200e.c
+@@ -1710,31 +1710,6 @@ fore200e_getstats(struct fore200e* fore200e)
+ return 0;
+ }
+
+-
+-static int
+-fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
+-{
+- /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
+-
+- DPRINTK(2, "getsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
+- vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
+-
+- return -EINVAL;
+-}
+-
+-
+-static int
+-fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen)
+-{
+- /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
+-
+- DPRINTK(2, "setsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
+- vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
+-
+- return -EINVAL;
+-}
+-
+-
+ #if 0 /* currently unused */
+ static int
+ fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
+@@ -3026,8 +3001,6 @@ static const struct atmdev_ops fore200e_ops = {
+ .open = fore200e_open,
+ .close = fore200e_close,
+ .ioctl = fore200e_ioctl,
+- .getsockopt = fore200e_getsockopt,
+- .setsockopt = fore200e_setsockopt,
+ .send = fore200e_send,
+ .change_qos = fore200e_change_qos,
+ .proc_read = fore200e_proc_read,
+diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
+index e5da51f907a25..4f2951cbe69c0 100644
+--- a/drivers/atm/horizon.c
++++ b/drivers/atm/horizon.c
+@@ -2527,46 +2527,6 @@ static void hrz_close (struct atm_vcc * atm_vcc) {
+ clear_bit(ATM_VF_ADDR,&atm_vcc->flags);
+ }
+
+-#if 0
+-static int hrz_getsockopt (struct atm_vcc * atm_vcc, int level, int optname,
+- void *optval, int optlen) {
+- hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
+- PRINTD (DBG_FLOW|DBG_VCC, "hrz_getsockopt");
+- switch (level) {
+- case SOL_SOCKET:
+- switch (optname) {
+-// case SO_BCTXOPT:
+-// break;
+-// case SO_BCRXOPT:
+-// break;
+- default:
+- return -ENOPROTOOPT;
+- };
+- break;
+- }
+- return -EINVAL;
+-}
+-
+-static int hrz_setsockopt (struct atm_vcc * atm_vcc, int level, int optname,
+- void *optval, unsigned int optlen) {
+- hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
+- PRINTD (DBG_FLOW|DBG_VCC, "hrz_setsockopt");
+- switch (level) {
+- case SOL_SOCKET:
+- switch (optname) {
+-// case SO_BCTXOPT:
+-// break;
+-// case SO_BCRXOPT:
+-// break;
+- default:
+- return -ENOPROTOOPT;
+- };
+- break;
+- }
+- return -EINVAL;
+-}
+-#endif
+-
+ #if 0
+ static int hrz_ioctl (struct atm_dev * atm_dev, unsigned int cmd, void *arg) {
+ hrz_dev * dev = HRZ_DEV(atm_dev);
+diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
+index bfc889367d5e3..cc90f550ab75a 100644
+--- a/drivers/atm/iphase.c
++++ b/drivers/atm/iphase.c
+@@ -2882,20 +2882,6 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
+ return 0;
+ }
+
+-static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,
+- void __user *optval, int optlen)
+-{
+- IF_EVENT(printk(">ia_getsockopt\n");)
+- return -EINVAL;
+-}
+-
+-static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,
+- void __user *optval, unsigned int optlen)
+-{
+- IF_EVENT(printk(">ia_setsockopt\n");)
+- return -EINVAL;
+-}
+-
+ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
+ IADEV *iadev;
+ struct dle *wr_ptr;
+@@ -3166,8 +3152,6 @@ static const struct atmdev_ops ops = {
+ .open = ia_open,
+ .close = ia_close,
+ .ioctl = ia_ioctl,
+- .getsockopt = ia_getsockopt,
+- .setsockopt = ia_setsockopt,
+ .send = ia_send,
+ .phy_put = ia_phy_put,
+ .phy_get = ia_phy_get,
+diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
+index c6b38112bcf4f..2ed832e1dafa2 100644
+--- a/drivers/atm/lanai.c
++++ b/drivers/atm/lanai.c
+@@ -2540,8 +2540,6 @@ static const struct atmdev_ops ops = {
+ .dev_close = lanai_dev_close,
+ .open = lanai_open,
+ .close = lanai_close,
+- .getsockopt = NULL,
+- .setsockopt = NULL,
+ .send = lanai_send,
+ .phy_put = NULL,
+ .phy_get = NULL,
+diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
+index 9f2148daf8ad1..669466d010efa 100644
+--- a/drivers/atm/solos-pci.c
++++ b/drivers/atm/solos-pci.c
+@@ -1179,8 +1179,6 @@ static const struct atmdev_ops fpga_ops = {
+ .open = popen,
+ .close = pclose,
+ .ioctl = NULL,
+- .getsockopt = NULL,
+- .setsockopt = NULL,
+ .send = psend,
+ .send_oam = NULL,
+ .phy_put = NULL,
+diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
+index 165eebe06e39e..ee059c77e3bbc 100644
+--- a/drivers/atm/zatm.c
++++ b/drivers/atm/zatm.c
+@@ -1515,20 +1515,6 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
+ }
+ }
+
+-
+-static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
+- void __user *optval,int optlen)
+-{
+- return -EINVAL;
+-}
+-
+-
+-static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
+- void __user *optval,unsigned int optlen)
+-{
+- return -EINVAL;
+-}
+-
+ static int zatm_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+ int error;
+@@ -1582,8 +1568,6 @@ static const struct atmdev_ops ops = {
+ .open = zatm_open,
+ .close = zatm_close,
+ .ioctl = zatm_ioctl,
+- .getsockopt = zatm_getsockopt,
+- .setsockopt = zatm_setsockopt,
+ .send = zatm_send,
+ .phy_put = zatm_phy_put,
+ .phy_get = zatm_phy_get,
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 19c0f91c38bdd..bc24d19ec2b37 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -176,11 +176,6 @@ struct atm_dev {
+ #define ATM_OF_IMMED 1 /* Attempt immediate delivery */
+ #define ATM_OF_INRATE 2 /* Attempt in-rate delivery */
+
+-
+-/*
+- * ioctl, getsockopt, and setsockopt are optional and can be set to NULL.
+- */
+-
+ struct atmdev_ops { /* only send is required */
+ void (*dev_close)(struct atm_dev *dev);
+ int (*open)(struct atm_vcc *vcc);
+@@ -190,10 +185,6 @@ struct atmdev_ops { /* only send is required */
+ int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+ void __user *arg);
+ #endif
+- int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
+- void __user *optval,int optlen);
+- int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
+- void __user *optval,unsigned int optlen);
+ int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+ int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+ void (*phy_put)(struct atm_dev *dev,unsigned char value,
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 1e07a5fc53d05..a51994aba34c4 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -783,13 +783,8 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
+ vcc->atm_options &= ~ATM_ATMOPT_CLP;
+ return 0;
+ default:
+- if (level == SOL_SOCKET)
+- return -EINVAL;
+- break;
+- }
+- if (!vcc->dev || !vcc->dev->ops->setsockopt)
+ return -EINVAL;
+- return vcc->dev->ops->setsockopt(vcc, level, optname, optval, optlen);
++ }
+ }
+
+ int vcc_getsockopt(struct socket *sock, int level, int optname,
+@@ -827,13 +822,8 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
+ return copy_to_user(optval, &pvc, sizeof(pvc)) ? -EFAULT : 0;
+ }
+ default:
+- if (level == SOL_SOCKET)
+- return -EINVAL;
+- break;
+- }
+- if (!vcc->dev || !vcc->dev->ops->getsockopt)
+ return -EINVAL;
+- return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len);
++ }
+ }
+
+ int register_atmdevice_notifier(struct notifier_block *nb)
+--
+2.50.1
+
--- /dev/null
+From 06520857bf70423ebff4cdebeb35674058ac1fb4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index 8d57fb5072054..b4a8d4f12087a 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1102,7 +1102,7 @@ get_stats (struct net_device *dev)
+ dev->stats.rx_bytes += dr32(OctetRcvOk);
+ dev->stats.tx_bytes += dr32(OctetXmtOk);
+
+- dev->stats.multicast = dr32(McstFramesRcvdOk);
++ dev->stats.multicast += dr32(McstFramesRcvdOk);
+ dev->stats.collisions += dr32(SingleColFrames)
+ + dr32(MultiColFrames);
+
+--
+2.50.1
+
--- /dev/null
+From a49d39fa6c97f5a783636b87167f3e41b4de394d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 80612f73ff531..eb83ce4b845ab 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2365,12 +2365,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+ !netif_is_l3_master(dev_out))
+ return ERR_PTR(-EINVAL);
+
+- if (ipv4_is_lbcast(fl4->daddr))
++ if (ipv4_is_lbcast(fl4->daddr)) {
+ type = RTN_BROADCAST;
+- else if (ipv4_is_multicast(fl4->daddr))
++
++ /* reset fi to prevent gateway resolution */
++ fi = NULL;
++ } else if (ipv4_is_multicast(fl4->daddr)) {
+ type = RTN_MULTICAST;
+- else if (ipv4_is_zeronet(fl4->daddr))
++ } else if (ipv4_is_zeronet(fl4->daddr)) {
+ return ERR_PTR(-EINVAL);
++ }
+
+ if (dev_out->flags & IFF_LOOPBACK)
+ flags |= RTCF_LOCAL;
+--
+2.50.1
+
--- /dev/null
+From e63cb1028414bc22af506551acb649eb673c6905 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@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/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index 99c7cdd0404a5..44d3d6826f696 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -341,7 +341,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ if (err)
+ return err;
+ }
+- priv->dcbx.xoff = xoff;
+
+ /* Apply the settings */
+ if (update_buffer) {
+@@ -350,6 +349,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ return err;
+ }
+
++ priv->dcbx.xoff = xoff;
++
+ if (update_prio2buffer)
+ err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+
+--
+2.50.1
+
--- /dev/null
+From 65cfd30f453ae6071cfe271ed37a23cd7977e32c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+index 34f55b81a0deb..7b852b87a609f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -64,11 +64,23 @@ struct mlx5e_port_buffer {
+ struct mlx5e_bufferx_reg buffer[MLX5E_MAX_BUFFER];
+ };
+
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ u32 change, unsigned int mtu,
+ struct ieee_pfc *pfc,
+ u32 *buffer_size,
+ u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++ u32 change, unsigned int mtu,
++ void *pfc,
++ u32 *buffer_size,
++ u8 *prio2buffer)
++{
++ return 0;
++}
++#endif
+
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+ struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index b3ba996004f1d..41bd16cc9d0f6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -42,6 +42,7 @@
+ #include "eswitch.h"
+ #include "en.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2894,9 +2895,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ struct mlx5e_params *params = &priv->channels.params;
+ struct net_device *netdev = priv->netdev;
+ struct mlx5_core_dev *mdev = priv->mdev;
+- u16 mtu;
++ u16 mtu, prev_mtu;
+ int err;
+
++ mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+ err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+ if (err)
+ return err;
+@@ -2906,6 +2909,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+ __func__, mtu, params->sw_mtu);
+
++ if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++ err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++ NULL, NULL, NULL);
++ if (err) {
++ netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++ __func__, mtu, err, prev_mtu);
++
++ mlx5e_set_mtu(mdev, params, prev_mtu);
++ return err;
++ }
++ }
++
+ params->sw_mtu = mtu;
+ return 0;
+ }
+--
+2.50.1
+
--- /dev/null
+From 7844bc7fe4896ad0ff5821e80fedee7bcd0283ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@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_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 41bd16cc9d0f6..b8d0b68befcb9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -141,6 +141,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+ if (port_state == VPORT_STATE_UP) {
+ netdev_info(priv->netdev, "Link up\n");
+ netif_carrier_on(priv->netdev);
++ mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++ NULL, NULL, NULL);
+ } else {
+ netdev_info(priv->netdev, "Link down\n");
+ netif_carrier_off(priv->netdev);
+--
+2.50.1
+
--- /dev/null
+From f73fa5730fb89860c7baa5bbce8a80473ce135af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 07ef0ac725b3e..93d1b78c9d4ec 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -206,10 +206,6 @@ static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
+ }
+
+ writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+- /* Enable MTL RX overflow */
+- value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+- writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+
+ static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
+--
+2.50.1
+
--- /dev/null
+From b86acca59e57fb40f6a55f13d567274c0365991d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index d89cf802d9aa7..8067641561a4f 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+ }
+
+- switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++ switch (inst_no_rt & ~KVM_MASK_RB) {
+ case KVM_INST_MTSRIN:
+ if (features & KVM_MAGIC_FEAT_SR) {
+ u32 inst_rb = _inst & KVM_MASK_RB;
+ kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+ }
+ break;
+-#endif
+ }
++#endif
+
+- switch (_inst) {
+ #ifdef CONFIG_BOOKE
++ switch (_inst) {
+ case KVM_INST_WRTEEI_0:
+ kvm_patch_ins_wrteei_0(inst);
+ break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ case KVM_INST_WRTEEI_1:
+ kvm_patch_ins_wrtee(inst, 0, 1);
+ break;
+-#endif
+ }
++#endif
+ }
+
+ extern u32 kvm_template_start[];
+--
+2.50.1
+
--- /dev/null
+From b5a913dcc708835316413c9194bbfde05fb0432b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+ sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+ sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+ sctp_get_port net/sctp/socket.c:8523 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+ x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+ sctp_get_port net/sctp/socket.c:8515 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index fae6157e837aa..33981ea102814 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -499,7 +499,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+ addr->v6.sin6_family = AF_INET6;
+ addr->v6.sin6_port = 0;
++ addr->v6.sin6_flowinfo = 0;
+ addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++ addr->v6.sin6_scope_id = 0;
+ }
+
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+--
+2.50.1
+
ftrace-fix-potential-warning-in-trace_printk_seq-dur.patch
scsi-core-sysfs-correct-sysfs-attributes-access-righ.patch
vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+net-atm-remove-the-atmdev_ops-get-set-sockopt-method.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
--- /dev/null
+From 515045984d0b06fbcb39d0089cf5190e6279f06c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+ struct atmtcp_control {
+ struct atmtcp_hdr hdr; /* must be first */
+ ...
+ atm_kptr_t vcc; /* both directions */
+ ...
+ } __ATM_API_ALIGN;
+
+ typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+ 1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+ 2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS: 00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x19b/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c | 17 ++++++++++++++---
+ include/linux/atmdev.h | 1 +
+ net/atm/common.c | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index ff558908897f3..9c83fb29b2f1b 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+ return NULL;
+ }
+
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++ struct atmtcp_hdr *hdr;
++
++ if (skb->len < sizeof(struct atmtcp_hdr))
++ return -EINVAL;
++
++ hdr = (struct atmtcp_hdr *)skb->data;
++ if (hdr->length == ATMTCP_HDR_MAGIC)
++ return -EINVAL;
++
++ return 0;
++}
+
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ struct sk_buff *new_skb;
+ int result = 0;
+
+- if (skb->len < sizeof(struct atmtcp_hdr))
+- goto done;
+-
+ dev = vcc->dev_data;
+ hdr = (struct atmtcp_hdr *) skb->data;
+ if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+ .close = atmtcp_c_close,
++ .pre_send = atmtcp_c_pre_send,
+ .send = atmtcp_c_send
+ };
+
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8..70807c679f1ab 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+ int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+ void __user *arg);
+ #endif
++ int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+ int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 9cc82acbc7358..48bb3f66a3f2a 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+
+ skb->dev = NULL; /* for paths shared with net_device interfaces */
+ if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+- atm_return_tx(vcc, skb);
+- kfree_skb(skb);
+ error = -EFAULT;
+- goto out;
++ goto free_skb;
+ }
+ if (eff != size)
+ memset(skb->data + size, 0, eff-size);
++
++ if (vcc->dev->ops->pre_send) {
++ error = vcc->dev->ops->pre_send(vcc, skb);
++ if (error)
++ goto free_skb;
++ }
++
+ error = vcc->dev->ops->send(vcc, skb);
+ error = error ? error : size;
+ out:
+ release_sock(sk);
+ return error;
++free_skb:
++ atm_return_tx(vcc, skb);
++ kfree_skb(skb);
++ goto out;
+ }
+
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+--
+2.50.1
+
--- /dev/null
+From 49aad117a9b12de69a4f32f21f5202e99a1e52d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index ff013e1d82a85..3d81afcccff8b 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4409,7 +4409,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+ if (!conn)
+ continue;
+
+- conn->sent -= count;
++ /* Check if there is really enough packets outstanding before
++ * attempting to decrease the sent counter otherwise it could
++ * underflow..
++ */
++ if (conn->sent >= count) {
++ conn->sent -= count;
++ } else {
++ bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++ conn, conn->sent, count);
++ conn->sent = 0;
++ }
+
+ switch (conn->type) {
+ case ACL_LINK:
+--
+2.50.1
+
--- /dev/null
+From ed821df74519a971266af7d76764f0e17a57c358 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:27 +0200
+Subject: Bluetooth: hci_event: Mark connection as closed during suspend
+ disconnect
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit b7fafbc499b5ee164018eb0eefe9027f5a6aaad2 ]
+
+When suspending, the disconnect command for an active Bluetooth
+connection could be issued, but the corresponding
+`HCI_EV_DISCONN_COMPLETE` event might not be received before the system
+completes the suspend process. This can lead to an inconsistent state.
+
+On resume, the controller may auto-accept reconnections from the same
+device (due to suspend event filters), but these new connections are
+rejected by the kernel which still has connection objects from before
+suspend. Resulting in errors like:
+```
+kernel: Bluetooth: hci0: ACL packet for unknown connection handle 1
+kernel: Bluetooth: hci0: Ignoring HCI_Connection_Complete for existing
+connection
+```
+
+This is a btmon snippet that shows the issue:
+```
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+ Handle: 1 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+ Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+ Disconnect (0x01|0x0006) ncmd 2
+ Status: Success (0x00)
+[...]
+// Host suspends with the event filter set for the device
+// On resume, the device tries to reconnect with a new handle
+
+> HCI Event: Connect Complete (0x03) plen 11
+ Status: Success (0x00)
+ Handle: 2
+ Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+
+// Kernel ignores this event because there is an existing connection
+with
+// handle 1
+```
+
+By explicitly setting the connection state to BT_CLOSED we can ensure a
+consistent state, even if we don't receive the disconnect complete event
+in time.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 3ff428df58a46..ff013e1d82a85 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2782,6 +2782,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+ goto done;
+ }
+
++ /* During suspend, mark connection as closed immediately
++ * since we might not receive HCI_EV_DISCONN_COMPLETE
++ */
++ if (hdev->suspended)
++ conn->state = BT_CLOSED;
++
+ mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
+
+ if (conn->type == ACL_LINK) {
+--
+2.50.1
+
--- /dev/null
+From 4a12ac6ea3860e8e49c16b8a10b4b550398d5ed4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:26 +0200
+Subject: Bluetooth: hci_event: Treat UNKNOWN_CONN_ID on disconnect as success
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit 2f050a5392b7a0928bf836d9891df4851463512c ]
+
+When the host sends an HCI_OP_DISCONNECT command, the controller may
+respond with the status HCI_ERROR_UNKNOWN_CONN_ID (0x02). E.g. this can
+happen on resume from suspend, if the link was terminated by the remote
+device before the event mask was correctly set.
+
+This is a btmon snippet that shows the issue:
+```
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+ L2CAP: Disconnection Request (0x06) ident 5 len 4
+ Destination CID: 65
+ Source CID: 72
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+ L2CAP: Disconnection Response (0x07) ident 5 len 4
+ Destination CID: 65
+ Source CID: 72
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+ L2CAP: Disconnection Request (0x06) ident 6 len 4
+ Destination CID: 64
+ Source CID: 71
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+ L2CAP: Disconnection Response (0x07) ident 6 len 4
+ Destination CID: 64
+ Source CID: 71
+< HCI Command: Set Event Mask (0x03|0x0001) plen 8
+ Mask: 0x3dbff807fffbffff
+ Inquiry Complete
+ Inquiry Result
+ Connection Complete
+ Connection Request
+ Disconnection Complete
+ Authentication Complete
+[...]
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+ Handle: 3 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+ Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+ Disconnect (0x01|0x0006) ncmd 1
+ Status: Unknown Connection Identifier (0x02)
+```
+
+Currently, the hci_cs_disconnect function treats any non-zero status
+as a command failure. This can be misleading because the connection is
+indeed being terminated and the controller is confirming that is has no
+knowledge of that connection handle. Meaning that the initial request of
+disconnecting a device should be treated as done.
+
+With this change we allow the function to proceed, following the success
+path, which correctly calls `mgmt_device_disconnected` and ensures a
+consistent state.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 866462c97dbaf..3ff428df58a46 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2767,7 +2767,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+ if (!conn)
+ goto unlock;
+
+- if (status) {
++ if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
+ mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+ conn->dst_type, status);
+
+--
+2.50.1
+
--- /dev/null
+From c8647fe81cac13a8586803254ba95ec303a1cda8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 12:20:55 +0300
+Subject: Bluetooth: hci_sync: fix set_local_name race condition
+
+From: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+
+[ Upstream commit 6bbd0d3f0c23fc53c17409dd7476f38ae0ff0cd9 ]
+
+Function set_name_sync() uses hdev->dev_name field to send
+HCI_OP_WRITE_LOCAL_NAME command, but copying from data to hdev->dev_name
+is called after mgmt cmd was queued, so it is possible that function
+set_name_sync() will read old name value.
+
+This change adds name as a parameter for function hci_update_name_sync()
+to avoid race condition.
+
+Fixes: 6f6ff38a1e14 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LOCAL_NAME")
+Signed-off-by: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_sync.h | 2 +-
+ net/bluetooth/hci_sync.c | 6 +++---
+ net/bluetooth/mgmt.c | 5 ++++-
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 3a7658d660224..a8b106d884d41 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -65,7 +65,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
+
+ int hci_update_eir_sync(struct hci_dev *hdev);
+ int hci_update_class_sync(struct hci_dev *hdev);
+-int hci_update_name_sync(struct hci_dev *hdev);
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
+ int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
+
+ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index acff47da799aa..965b0f2b43a72 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3424,13 +3424,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+ return hci_write_scan_enable_sync(hdev, scan);
+ }
+
+-int hci_update_name_sync(struct hci_dev *hdev)
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
+ {
+ struct hci_cp_write_local_name cp;
+
+ memset(&cp, 0, sizeof(cp));
+
+- memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
++ memcpy(cp.name, name, sizeof(cp.name));
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
+ sizeof(cp), &cp,
+@@ -3482,7 +3482,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
+ hci_write_fast_connectable_sync(hdev, false);
+ hci_update_scan_sync(hdev);
+ hci_update_class_sync(hdev);
+- hci_update_name_sync(hdev);
++ hci_update_name_sync(hdev, hdev->dev_name);
+ hci_update_eir_sync(hdev);
+ }
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 919e1bae2b269..27876512c63a4 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3897,8 +3897,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
+
+ static int set_name_sync(struct hci_dev *hdev, void *data)
+ {
++ struct mgmt_pending_cmd *cmd = data;
++ struct mgmt_cp_set_local_name *cp = cmd->param;
++
+ if (lmp_bredr_capable(hdev)) {
+- hci_update_name_sync(hdev);
++ hci_update_name_sync(hdev, cp->name);
+ hci_update_eir_sync(hdev);
+ }
+
+--
+2.50.1
+
--- /dev/null
+From ffd8dad18451b6f59f866ed6630bbf2d3aa890b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jul 2025 13:28:22 -0700
+Subject: drm/msm: Defer fd_install in SUBMIT ioctl
+
+From: Rob Clark <robin.clark@oss.qualcomm.com>
+
+[ Upstream commit f22853435bbd1e9836d0dce7fd99c040b94c2bf1 ]
+
+Avoid fd_install() until there are no more potential error paths, to
+avoid put_unused_fd() after the fd is made visible to userspace.
+
+Fixes: 68dc6c2d5eec ("drm/msm: Fix submit error-path leaks")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/665363/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index 572dd662e8095..6a02f790624a9 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -929,12 +929,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+
+ if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+ sync_file = sync_file_create(submit->user_fence);
+- if (!sync_file) {
++ if (!sync_file)
+ ret = -ENOMEM;
+- } else {
+- fd_install(out_fence_fd, sync_file->file);
+- args->fence_fd = out_fence_fd;
+- }
+ }
+
+ submit_attach_object_fences(submit);
+@@ -959,10 +955,14 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+ out_unlock:
+ mutex_unlock(&queue->lock);
+ out_post_unlock:
+- if (ret && (out_fence_fd >= 0)) {
+- put_unused_fd(out_fence_fd);
++ if (ret) {
++ if (out_fence_fd >= 0)
++ put_unused_fd(out_fence_fd);
+ if (sync_file)
+ fput(sync_file->file);
++ } else if (sync_file) {
++ fd_install(out_fence_fd, sync_file->file);
++ args->fence_fd = out_fence_fd;
+ }
+
+ if (!IS_ERR_OR_NULL(submit)) {
+--
+2.50.1
+
--- /dev/null
+From e5b4d67100cfc25f7953ca3f115d0e40a8147495 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+ BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+ Call trace:
+ kasan_check_range+0xe8/0x190
+ __asan_loadN+0x1c/0x28
+ memcmp+0x98/0xd0
+ efivarfs_d_compare+0x68/0xd8
+ __d_lookup_rcu_op_compare+0x178/0x218
+ __d_lookup_rcu+0x1f8/0x228
+ d_alloc_parallel+0x150/0x648
+ lookup_open.isra.0+0x5f0/0x8d0
+ open_last_lookups+0x264/0x828
+ path_openat+0x130/0x3f8
+ do_filp_open+0x114/0x248
+ do_sys_openat2+0x340/0x3c0
+ __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+ T1 T2
+ lookup_open
+ ->lookup
+ simple_lookup
+ d_add
+ // invalid dentry is added to hash list
+
+ lookup_open
+ d_alloc_parallel
+ __d_lookup_rcu
+ __d_lookup_rcu_op_compare
+ hlist_bl_for_each_entry_rcu
+ // invalid dentry can be retrieved
+ ->d_compare
+ efivarfs_d_compare
+ // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index b8c4641ed152b..9025430cf2ad3 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -47,6 +47,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+ int guid = len - EFI_VARIABLE_GUID_LEN;
+
++ /* Parallel lookups may produce a temporary invalid filename */
++ if (guid <= 0)
++ return 1;
++
+ if (name->len != len)
+ return 1;
+
+--
+2.50.1
+
--- /dev/null
+From 0d4293271a70cf23360bfe1b72e5341e9848a65d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:39 +0200
+Subject: HID: input: rename hidinput_set_battery_charge_status()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit a82231b2a8712d0218fc286a9b0da328d419a3f4 ]
+
+In preparation for a patch fixing a bug affecting
+hidinput_set_battery_charge_status(), rename the function to
+hidinput_update_battery_charge_status() and move it up so it can be used
+by hidinput_update_battery().
+
+Refactor, no functional changes.
+
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Stable-dep-of: e94536e1d181 ("HID: input: report battery status changes immediately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input-test.c | 10 +++++-----
+ drivers/hid/hid-input.c | 38 ++++++++++++++++++------------------
+ 2 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c
+index 77c2d45ac62a7..6f5c71660d823 100644
+--- a/drivers/hid/hid-input-test.c
++++ b/drivers/hid/hid-input-test.c
+@@ -7,7 +7,7 @@
+
+ #include <kunit/test.h>
+
+-static void hid_test_input_set_battery_charge_status(struct kunit *test)
++static void hid_test_input_update_battery_charge_status(struct kunit *test)
+ {
+ struct hid_device *dev;
+ bool handled;
+@@ -15,15 +15,15 @@ static void hid_test_input_set_battery_charge_status(struct kunit *test)
+ dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
++ handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
+ KUNIT_EXPECT_FALSE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
++ handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
+ KUNIT_EXPECT_TRUE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
++ handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
+ KUNIT_EXPECT_TRUE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
+ }
+@@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
+ }
+
+ static struct kunit_case hid_input_tests[] = {
+- KUNIT_CASE(hid_test_input_set_battery_charge_status),
++ KUNIT_CASE(hid_test_input_update_battery_charge_status),
+ KUNIT_CASE(hid_test_input_get_battery_property),
+ { }
+ };
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index b0091819fd58a..51be30b7c1851 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -609,6 +609,20 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ dev->battery = NULL;
+ }
+
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++ unsigned int usage, int value)
++{
++ switch (usage) {
++ case HID_BAT_CHARGING:
++ dev->battery_charge_status = value ?
++ POWER_SUPPLY_STATUS_CHARGING :
++ POWER_SUPPLY_STATUS_DISCHARGING;
++ return true;
++ }
++
++ return false;
++}
++
+ static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+ int capacity;
+@@ -631,20 +645,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
+ power_supply_changed(dev->battery);
+ }
+ }
+-
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
+-{
+- switch (usage) {
+- case HID_BAT_CHARGING:
+- dev->battery_charge_status = value ?
+- POWER_SUPPLY_STATUS_CHARGING :
+- POWER_SUPPLY_STATUS_DISCHARGING;
+- return true;
+- }
+-
+- return false;
+-}
+ #else /* !CONFIG_HID_BATTERY_STRENGTH */
+ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+ struct hid_field *field, bool is_percentage)
+@@ -656,14 +656,14 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++ unsigned int usage, int value)
+ {
++ return false;
+ }
+
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
++static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+- return false;
+ }
+ #endif /* CONFIG_HID_BATTERY_STRENGTH */
+
+@@ -1509,7 +1509,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+ return;
+
+ if (usage->type == EV_PWR) {
+- bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
++ bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+
+ if (!handled)
+ hidinput_update_battery(hid, value);
+--
+2.50.1
+
--- /dev/null
+From dfa8b47f74e76e1341248105b248a16cbac24cd1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:40 +0200
+Subject: HID: input: report battery status changes immediately
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit e94536e1d1818b0989aa19b443b7089f50133c35 ]
+
+Previously, the battery status (charging/discharging) was not reported
+immediately to user-space.
+
+For most input devices, this wasn't problematic because changing their
+battery status requires connecting them to a different bus.
+For example, a gamepad would report a discharging status while
+connected via Bluetooth and a charging status while connected via USB.
+
+However, certain devices are not connected or disconnected when their
+battery status changes. For example, a phone battery changes its status
+without connecting or disconnecting it.
+In these cases, the battery status was not reported immediately to user
+space.
+
+Report battery status changes immediately to user space to support
+these kinds of devices.
+
+Fixes: a608dc1c0639 ("HID: input: map battery system charging")
+Reported-by: 卢国宏 <luguohong@xiaomi.com>
+Closes: https://lore.kernel.org/linux-input/aI49Im0sGb6fpgc8@fedora/T/
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input.c | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 51be30b7c1851..cd9d031858438 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -623,13 +623,19 @@ static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+ return false;
+ }
+
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++ int value)
+ {
+ int capacity;
+
+ if (!dev->battery)
+ return;
+
++ if (hidinput_update_battery_charge_status(dev, usage, value)) {
++ power_supply_changed(dev->battery);
++ return;
++ }
++
+ if (value == 0 || value < dev->battery_min || value > dev->battery_max)
+ return;
+
+@@ -656,13 +662,8 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+
+-static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
+-{
+- return false;
+-}
+-
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++ int value)
+ {
+ }
+ #endif /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1509,11 +1510,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+ return;
+
+ if (usage->type == EV_PWR) {
+- bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+-
+- if (!handled)
+- hidinput_update_battery(hid, value);
+-
++ hidinput_update_battery(hid, usage->hid, value);
+ return;
+ }
+
+--
+2.50.1
+
--- /dev/null
+From ff0fa8ea093748ab38ebcb7f54a9e9bd08e1cf5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index dfc23cc173097..2acb63b547c35 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1094,7 +1094,7 @@ get_stats (struct net_device *dev)
+ dev->stats.rx_bytes += dr32(OctetRcvOk);
+ dev->stats.tx_bytes += dr32(OctetXmtOk);
+
+- dev->stats.multicast = dr32(McstFramesRcvdOk);
++ dev->stats.multicast += dr32(McstFramesRcvdOk);
+ dev->stats.collisions += dr32(SingleColFrames)
+ + dr32(MultiColFrames);
+
+--
+2.50.1
+
--- /dev/null
+From 3acb75e4c01db107debd7ea6867cdc8347d95c87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index c57a1cee98e2c..395bc567b15d3 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2549,12 +2549,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+ !netif_is_l3_master(dev_out))
+ return ERR_PTR(-EINVAL);
+
+- if (ipv4_is_lbcast(fl4->daddr))
++ if (ipv4_is_lbcast(fl4->daddr)) {
+ type = RTN_BROADCAST;
+- else if (ipv4_is_multicast(fl4->daddr))
++
++ /* reset fi to prevent gateway resolution */
++ fi = NULL;
++ } else if (ipv4_is_multicast(fl4->daddr)) {
+ type = RTN_MULTICAST;
+- else if (ipv4_is_zeronet(fl4->daddr))
++ } else if (ipv4_is_zeronet(fl4->daddr)) {
+ return ERR_PTR(-EINVAL);
++ }
+
+ if (dev_out->flags & IFF_LOOPBACK)
+ flags |= RTCF_LOCAL;
+--
+2.50.1
+
--- /dev/null
+From 831c343133b7497cd786713a7620c835e70ba618 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:28 +0300
+Subject: net/mlx5: Reload auxiliary drivers on fw_activate
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 34cc6a54914f478c93e176450fae6313404f9f74 ]
+
+The devlink reload fw_activate command performs firmware activation
+followed by driver reload, while devlink reload driver_reinit triggers
+only driver reload. However, the driver reload logic differs between the
+two modes, as on driver_reinit mode mlx5 also reloads auxiliary drivers,
+while in fw_activate mode the auxiliary drivers are suspended where
+applicable.
+
+Additionally, following the cited commit, if the device has multiple PFs,
+the behavior during fw_activate may vary between PFs: one PF may suspend
+auxiliary drivers, while another reloads them.
+
+Align devlink dev reload fw_activate behavior with devlink dev reload
+driver_reinit, to reload all auxiliary drivers.
+
+Fixes: 72ed5d5624af ("net/mlx5: Suspend auxiliary devices only in case of PCI device suspend")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-6-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 3749eb83d9e53..64dcfac9ce724 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -108,7 +108,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+ if (err)
+ return err;
+
+- mlx5_unload_one_devl_locked(dev, true);
++ mlx5_unload_one_devl_locked(dev, false);
+ err = mlx5_health_wait_pci_up(dev);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+--
+2.50.1
+
--- /dev/null
+From 2f9f2ec5cef9ae7ab2205ed3024788126759b0d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@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/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index c9d5d8d93994d..7899a7230299d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -346,7 +346,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ if (err)
+ return err;
+ }
+- priv->dcbx.xoff = xoff;
+
+ /* Apply the settings */
+ if (update_buffer) {
+@@ -355,6 +354,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ return err;
+ }
+
++ priv->dcbx.xoff = xoff;
++
+ if (update_prio2buffer)
+ err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+
+--
+2.50.1
+
--- /dev/null
+From 08f0d6bce3462cf84ed26cceed7135a084912a20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+index 80af7a5ac6046..a23e3d810f3e4 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -63,11 +63,23 @@ struct mlx5e_port_buffer {
+ struct mlx5e_bufferx_reg buffer[MLX5E_MAX_BUFFER];
+ };
+
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ u32 change, unsigned int mtu,
+ struct ieee_pfc *pfc,
+ u32 *buffer_size,
+ u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++ u32 change, unsigned int mtu,
++ void *pfc,
++ u32 *buffer_size,
++ u8 *prio2buffer)
++{
++ return 0;
++}
++#endif
+
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+ struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 887d446354006..7612070b66160 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -42,6 +42,7 @@
+ #include "eswitch.h"
+ #include "en.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2640,9 +2641,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ struct mlx5e_params *params = &priv->channels.params;
+ struct net_device *netdev = priv->netdev;
+ struct mlx5_core_dev *mdev = priv->mdev;
+- u16 mtu;
++ u16 mtu, prev_mtu;
+ int err;
+
++ mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+ err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+ if (err)
+ return err;
+@@ -2652,6 +2655,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+ __func__, mtu, params->sw_mtu);
+
++ if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++ err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++ NULL, NULL, NULL);
++ if (err) {
++ netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++ __func__, mtu, err, prev_mtu);
++
++ mlx5e_set_mtu(mdev, params, prev_mtu);
++ return err;
++ }
++ }
++
+ params->sw_mtu = mtu;
+ return 0;
+ }
+--
+2.50.1
+
--- /dev/null
+From b798855a1158684e6262f6096495bc5e99464e14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@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_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 7612070b66160..ae3a7b96f7978 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -107,6 +107,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+ if (up) {
+ netdev_info(priv->netdev, "Link up\n");
+ netif_carrier_on(priv->netdev);
++ mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++ NULL, NULL, NULL);
+ } else {
+ netdev_info(priv->netdev, "Link down\n");
+ netif_carrier_off(priv->netdev);
+--
+2.50.1
+
--- /dev/null
+From 9666ef8acc9799c4e776bfe40ead3ee83f50da46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:56 +0900
+Subject: net: rose: convert 'use' field to refcount_t
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit d860d1faa6b2ce3becfdb8b0c2b048ad31800061 ]
+
+The 'use' field in struct rose_neigh is used as a reference counter but
+lacks atomicity. This can lead to race conditions where a rose_neigh
+structure is freed while still being referenced by other code paths.
+
+For example, when rose_neigh->use becomes zero during an ioctl operation
+via rose_rt_ioctl(), the structure may be removed while its timer is
+still active, potentially causing use-after-free issues.
+
+This patch changes the type of 'use' from unsigned short to refcount_t and
+updates all code paths to use rose_neigh_hold() and rose_neigh_put() which
+operate reference counts atomically.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-3-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h | 18 +++++++++++++-----
+ net/rose/af_rose.c | 13 +++++++------
+ net/rose/rose_in.c | 12 ++++++------
+ net/rose/rose_route.c | 33 ++++++++++++++++++---------------
+ net/rose/rose_timer.c | 2 +-
+ 5 files changed, 45 insertions(+), 33 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 174b4f605d849..2b5491bbf39ab 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -8,6 +8,7 @@
+ #ifndef _ROSE_H
+ #define _ROSE_H
+
++#include <linux/refcount.h>
+ #include <linux/rose.h>
+ #include <net/ax25.h>
+ #include <net/sock.h>
+@@ -96,7 +97,7 @@ struct rose_neigh {
+ ax25_cb *ax25;
+ struct net_device *dev;
+ unsigned short count;
+- unsigned short use;
++ refcount_t use;
+ unsigned int number;
+ char restarted;
+ char dce_mode;
+@@ -151,12 +152,19 @@ struct rose_sock {
+
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
+
++static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
++{
++ refcount_inc(&rose_neigh->use);
++}
++
+ static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
+ {
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
++ if (refcount_dec_and_test(&rose_neigh->use)) {
++ if (rose_neigh->ax25)
++ ax25_cb_put(rose_neigh->ax25);
++ kfree(rose_neigh->digipeat);
++ kfree(rose_neigh);
++ }
+ }
+
+ /* af_rose.c */
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index b21c2ce401928..5a0bf022a84be 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -170,7 +170,7 @@ void rose_kill_by_neigh(struct rose_neigh *neigh)
+
+ if (rose->neighbour == neigh) {
+ rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose->neighbour = NULL;
+ }
+ }
+@@ -212,7 +212,7 @@ static void rose_kill_by_device(struct net_device *dev)
+ if (rose->device == dev) {
+ rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+ if (rose->neighbour)
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ netdev_put(rose->device, &rose->dev_tracker);
+ rose->device = NULL;
+ }
+@@ -655,7 +655,7 @@ static int rose_release(struct socket *sock)
+ break;
+
+ case ROSE_STATE_2:
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ release_sock(sk);
+ rose_disconnect(sk, 0, -1, -1);
+ lock_sock(sk);
+@@ -823,6 +823,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ rose->lci = rose_new_lci(rose->neighbour);
+ if (!rose->lci) {
+ err = -ENETUNREACH;
++ rose_neigh_put(rose->neighbour);
+ goto out_release;
+ }
+
+@@ -834,12 +835,14 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ dev = rose_dev_first();
+ if (!dev) {
+ err = -ENETUNREACH;
++ rose_neigh_put(rose->neighbour);
+ goto out_release;
+ }
+
+ user = ax25_findbyuid(current_euid());
+ if (!user) {
+ err = -EINVAL;
++ rose_neigh_put(rose->neighbour);
+ dev_put(dev);
+ goto out_release;
+ }
+@@ -874,8 +877,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+
+ rose->state = ROSE_STATE_1;
+
+- rose->neighbour->use++;
+-
+ rose_write_internal(sk, ROSE_CALL_REQUEST);
+ rose_start_heartbeat(sk);
+ rose_start_t1timer(sk);
+@@ -1077,7 +1078,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
+ GFP_ATOMIC);
+ make_rose->facilities = facilities;
+
+- make_rose->neighbour->use++;
++ rose_neigh_hold(make_rose->neighbour);
+
+ if (rose_sk(sk)->defer) {
+ make_rose->state = ROSE_STATE_5;
+diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
+index 4d67f36dce1b4..7caae93937ee9 100644
+--- a/net/rose/rose_in.c
++++ b/net/rose/rose_in.c
+@@ -56,7 +56,7 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -79,12 +79,12 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ case ROSE_CLEAR_CONFIRMATION:
+ rose_disconnect(sk, 0, -1, -1);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -120,7 +120,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ case ROSE_RR:
+@@ -233,7 +233,7 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -253,7 +253,7 @@ static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int framety
+ if (frametype == ROSE_CLEAR_REQUEST) {
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose_sk(sk)->neighbour->use--;
++ rose_neigh_put(rose_sk(sk)->neighbour);
+ }
+
+ return 0;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index b406b1e0fb1e7..42460da0854d5 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -93,11 +93,11 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ rose_neigh->ax25 = NULL;
+ rose_neigh->dev = dev;
+ rose_neigh->count = 0;
+- rose_neigh->use = 0;
+ rose_neigh->dce_mode = 0;
+ rose_neigh->loopback = 0;
+ rose_neigh->number = rose_neigh_no++;
+ rose_neigh->restarted = 0;
++ refcount_set(&rose_neigh->use, 1);
+
+ skb_queue_head_init(&rose_neigh->queue);
+
+@@ -255,10 +255,10 @@ static void rose_remove_route(struct rose_route *rose_route)
+ struct rose_route *s;
+
+ if (rose_route->neigh1 != NULL)
+- rose_route->neigh1->use--;
++ rose_neigh_put(rose_route->neigh1);
+
+ if (rose_route->neigh2 != NULL)
+- rose_route->neigh2->use--;
++ rose_neigh_put(rose_route->neigh2);
+
+ if ((s = rose_route_list) == rose_route) {
+ rose_route_list = rose_route->next;
+@@ -323,7 +323,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
+
+- if (rose_neigh->count == 0 && rose_neigh->use == 0) {
++ if (rose_neigh->count == 0) {
+ rose_remove_neigh(rose_neigh);
+ rose_neigh_put(rose_neigh);
+ }
+@@ -375,11 +375,11 @@ void rose_add_loopback_neigh(void)
+ sn->ax25 = NULL;
+ sn->dev = NULL;
+ sn->count = 0;
+- sn->use = 0;
+ sn->dce_mode = 1;
+ sn->loopback = 1;
+ sn->number = rose_neigh_no++;
+ sn->restarted = 1;
++ refcount_set(&sn->use, 1);
+
+ skb_queue_head_init(&sn->queue);
+
+@@ -561,8 +561,7 @@ static int rose_clear_routes(void)
+ s = rose_neigh;
+ rose_neigh = rose_neigh->next;
+
+- if (s->use == 0 && !s->loopback) {
+- s->count = 0;
++ if (!s->loopback) {
+ rose_remove_neigh(s);
+ rose_neigh_put(s);
+ }
+@@ -680,6 +679,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+ for (i = 0; i < node->count; i++) {
+ if (node->neighbour[i]->restarted) {
+ res = node->neighbour[i];
++ rose_neigh_hold(node->neighbour[i]);
+ goto out;
+ }
+ }
+@@ -691,6 +691,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+ for (i = 0; i < node->count; i++) {
+ if (!rose_ftimer_running(node->neighbour[i])) {
+ res = node->neighbour[i];
++ rose_neigh_hold(node->neighbour[i]);
+ goto out;
+ }
+ failed = 1;
+@@ -780,13 +781,13 @@ static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
+ }
+
+ if (rose_route->neigh1 == rose_neigh) {
+- rose_route->neigh1->use--;
++ rose_neigh_put(rose_route->neigh1);
+ rose_route->neigh1 = NULL;
+ rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
+ }
+
+ if (rose_route->neigh2 == rose_neigh) {
+- rose_route->neigh2->use--;
++ rose_neigh_put(rose_route->neigh2);
+ rose_route->neigh2 = NULL;
+ rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
+ }
+@@ -915,7 +916,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_clear_queues(sk);
+ rose->cause = ROSE_NETWORK_CONGESTION;
+ rose->diagnostic = 0;
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose->neighbour = NULL;
+ rose->lci = 0;
+ rose->state = ROSE_STATE_0;
+@@ -1040,12 +1041,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+
+ if ((new_lci = rose_new_lci(new_neigh)) == 0) {
+ rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
+- goto out;
++ goto put_neigh;
+ }
+
+ if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
+ rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
+- goto out;
++ goto put_neigh;
+ }
+
+ rose_route->lci1 = lci;
+@@ -1058,8 +1059,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_route->lci2 = new_lci;
+ rose_route->neigh2 = new_neigh;
+
+- rose_route->neigh1->use++;
+- rose_route->neigh2->use++;
++ rose_neigh_hold(rose_route->neigh1);
++ rose_neigh_hold(rose_route->neigh2);
+
+ rose_route->next = rose_route_list;
+ rose_route_list = rose_route;
+@@ -1071,6 +1072,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_transmit_link(skb, rose_route->neigh2);
+ res = 1;
+
++put_neigh:
++ rose_neigh_put(new_neigh);
+ out:
+ spin_unlock_bh(&rose_route_list_lock);
+ spin_unlock_bh(&rose_neigh_list_lock);
+@@ -1186,7 +1189,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+ (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+ rose_neigh->dev ? rose_neigh->dev->name : "???",
+ rose_neigh->count,
+- rose_neigh->use,
++ refcount_read(&rose_neigh->use) - 1,
+ (rose_neigh->dce_mode) ? "DCE" : "DTE",
+ (rose_neigh->restarted) ? "yes" : "no",
+ ax25_display_timer(&rose_neigh->t0timer) / HZ,
+diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
+index 1525773e94aa1..c52d7d20c5199 100644
+--- a/net/rose/rose_timer.c
++++ b/net/rose/rose_timer.c
+@@ -180,7 +180,7 @@ static void rose_timer_expiry(struct timer_list *t)
+ break;
+
+ case ROSE_STATE_2: /* T3 */
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose_disconnect(sk, ETIMEDOUT, -1, -1);
+ break;
+
+--
+2.50.1
+
--- /dev/null
+From 9d5f8b18b47e19d73d093926dfd2aedc48c01c5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:57 +0900
+Subject: net: rose: include node references in rose_neigh refcount
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit da9c9c877597170b929a6121a68dcd3dd9a80f45 ]
+
+Current implementation maintains two separate reference counting
+mechanisms: the 'count' field in struct rose_neigh tracks references from
+rose_node structures, while the 'use' field (now refcount_t) tracks
+references from rose_sock.
+
+This patch merges these two reference counting systems using 'use' field
+for proper reference management. Specifically, this patch adds incrementing
+and decrementing of rose_neigh->use when rose_neigh->count is incremented
+or decremented.
+
+This patch also modifies rose_rt_free(), rose_rt_device_down() and
+rose_clear_route() to properly release references to rose_neigh objects
+before freeing a rose_node through rose_remove_node().
+
+These changes ensure rose_neigh structures are properly freed only when
+all references, including those from rose_node structures, are released.
+As a result, this resolves a slab-use-after-free issue reported by Syzbot.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+942297eecf7d2d61d1f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=942297eecf7d2d61d1f1
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-4-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rose/rose_route.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 42460da0854d5..6acbb795c506d 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -178,6 +178,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ }
+ }
+ rose_neigh->count++;
++ rose_neigh_hold(rose_neigh);
+
+ goto out;
+ }
+@@ -187,6 +188,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ rose_node->neighbour[rose_node->count] = rose_neigh;
+ rose_node->count++;
+ rose_neigh->count++;
++ rose_neigh_hold(rose_neigh);
+ }
+
+ out:
+@@ -322,6 +324,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ for (i = 0; i < rose_node->count; i++) {
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
++ rose_neigh_put(rose_neigh);
+
+ if (rose_neigh->count == 0) {
+ rose_remove_neigh(rose_neigh);
+@@ -430,6 +433,7 @@ int rose_add_loopback_node(const rose_address *address)
+ rose_node_list = rose_node;
+
+ rose_loopback_neigh->count++;
++ rose_neigh_hold(rose_loopback_neigh);
+
+ out:
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -461,6 +465,7 @@ void rose_del_loopback_node(const rose_address *address)
+ rose_remove_node(rose_node);
+
+ rose_loopback_neigh->count--;
++ rose_neigh_put(rose_loopback_neigh);
+
+ out:
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -500,6 +505,7 @@ void rose_rt_device_down(struct net_device *dev)
+ memmove(&t->neighbour[i], &t->neighbour[i + 1],
+ sizeof(t->neighbour[0]) *
+ (t->count - i));
++ rose_neigh_put(s);
+ }
+
+ if (t->count <= 0)
+@@ -543,6 +549,7 @@ static int rose_clear_routes(void)
+ {
+ struct rose_neigh *s, *rose_neigh;
+ struct rose_node *t, *rose_node;
++ int i;
+
+ spin_lock_bh(&rose_node_list_lock);
+ spin_lock_bh(&rose_neigh_list_lock);
+@@ -553,8 +560,12 @@ static int rose_clear_routes(void)
+ while (rose_node != NULL) {
+ t = rose_node;
+ rose_node = rose_node->next;
+- if (!t->loopback)
++
++ if (!t->loopback) {
++ for (i = 0; i < rose_node->count; i++)
++ rose_neigh_put(t->neighbour[i]);
+ rose_remove_node(t);
++ }
+ }
+
+ while (rose_neigh != NULL) {
+@@ -1189,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+ (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+ rose_neigh->dev ? rose_neigh->dev->name : "???",
+ rose_neigh->count,
+- refcount_read(&rose_neigh->use) - 1,
++ refcount_read(&rose_neigh->use) - rose_neigh->count - 1,
+ (rose_neigh->dce_mode) ? "DCE" : "DTE",
+ (rose_neigh->restarted) ? "yes" : "no",
+ ax25_display_timer(&rose_neigh->t0timer) / HZ,
+@@ -1294,6 +1305,7 @@ void __exit rose_rt_free(void)
+ struct rose_neigh *s, *rose_neigh = rose_neigh_list;
+ struct rose_node *t, *rose_node = rose_node_list;
+ struct rose_route *u, *rose_route = rose_route_list;
++ int i;
+
+ while (rose_neigh != NULL) {
+ s = rose_neigh;
+@@ -1307,6 +1319,8 @@ void __exit rose_rt_free(void)
+ t = rose_node;
+ rose_node = rose_node->next;
+
++ for (i = 0; i < t->count; i++)
++ rose_neigh_put(t->neighbour[i]);
+ rose_remove_node(t);
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 3c8bbd7d9ec2674b5e4dd6ed3fb22c2486bb1b4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:55 +0900
+Subject: net: rose: split remove and free operations in rose_remove_neigh()
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit dcb34659028f856c423a29ef9b4e2571d203444d ]
+
+The current rose_remove_neigh() performs two distinct operations:
+1. Removes rose_neigh from rose_neigh_list
+2. Frees the rose_neigh structure
+
+Split these operations into separate functions to improve maintainability
+and prepare for upcoming refcount_t conversion. The timer cleanup remains
+in rose_remove_neigh() because free operations can be called from timer
+itself.
+
+This patch introduce rose_neigh_put() to handle the freeing of rose_neigh
+structures and modify rose_remove_neigh() to handle removal only.
+
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-2-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h | 8 ++++++++
+ net/rose/rose_route.c | 15 ++++++---------
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 23267b4efcfa3..174b4f605d849 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -151,6 +151,14 @@ struct rose_sock {
+
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
+
++static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
++{
++ if (rose_neigh->ax25)
++ ax25_cb_put(rose_neigh->ax25);
++ kfree(rose_neigh->digipeat);
++ kfree(rose_neigh);
++}
++
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int sysctl_rose_restart_request_timeout;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index a7054546f52df..b406b1e0fb1e7 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -234,20 +234,12 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+
+ if ((s = rose_neigh_list) == rose_neigh) {
+ rose_neigh_list = rose_neigh->next;
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
+ return;
+ }
+
+ while (s != NULL && s->next != NULL) {
+ if (s->next == rose_neigh) {
+ s->next = rose_neigh->next;
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
+ return;
+ }
+
+@@ -331,8 +323,10 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
+
+- if (rose_neigh->count == 0 && rose_neigh->use == 0)
++ if (rose_neigh->count == 0 && rose_neigh->use == 0) {
+ rose_remove_neigh(rose_neigh);
++ rose_neigh_put(rose_neigh);
++ }
+
+ rose_node->count--;
+
+@@ -513,6 +507,7 @@ void rose_rt_device_down(struct net_device *dev)
+ }
+
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+ spin_unlock_bh(&rose_neigh_list_lock);
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -569,6 +564,7 @@ static int rose_clear_routes(void)
+ if (s->use == 0 && !s->loopback) {
+ s->count = 0;
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+ }
+
+@@ -1301,6 +1297,7 @@ void __exit rose_rt_free(void)
+ rose_neigh = rose_neigh->next;
+
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+
+ while (rose_node != NULL) {
+--
+2.50.1
+
--- /dev/null
+From e4d3b2f3c42ea950f76ef8f986c6084ee0b23228 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 5e98355f422b3..3e4318d5dcdf5 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -199,10 +199,6 @@ static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
+ }
+
+ writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+- /* Enable MTL RX overflow */
+- value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+- writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+
+ static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
+--
+2.50.1
+
--- /dev/null
+From 9da465f24262fd3c9e37cca7ad2144a4c8ef0eaa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:55:43 +0200
+Subject: phy: mscc: Fix when PTP clock is register and unregister
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]
+
+It looks like that every time when the interface was set down and up the
+driver was creating a new ptp clock. On top of this the function
+ptp_clock_unregister was never called.
+Therefore fix this by calling ptp_clock_register and initialize the
+mii_ts struct inside the probe function and call ptp_clock_unregister when
+driver is removed.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h | 4 ++++
+ drivers/net/phy/mscc/mscc_main.c | 4 +---
+ drivers/net/phy/mscc/mscc_ptp.c | 34 ++++++++++++++++++++------------
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index 878298304430c..fcfbff691b3c6 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -474,6 +474,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -488,6 +489,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
+ {
+ return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+ return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index 36734bb217e42..2fabb6a7d2415 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2326,9 +2326,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+- struct vsc8531_private *priv = phydev->priv;
+-
+- skb_queue_purge(&priv->rx_skbs_list);
++ vsc8584_ptp_deinit(phydev);
+ }
+
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index add1a9ee721af..1f6237705b44b 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1297,7 +1297,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+- struct vsc8531_private *vsc8531 = phydev->priv;
+ static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+ static const u8 ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+ u32 val;
+@@ -1514,17 +1513,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+
+ vsc85xx_ts_eth_cmp1_sig(phydev);
+
+- vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+- vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+- vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+- vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
+- phydev->mii_ts = &vsc8531->mii_ts;
+-
+- memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+-
+- vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+- &phydev->mdio.dev);
+- return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++ return 0;
+ }
+
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1551,6 +1540,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+ return 0;
+ }
+
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++ struct vsc8531_private *vsc8531 = phydev->priv;
++
++ if (vsc8531->ptp->ptp_clock) {
++ ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++ skb_queue_purge(&vsc8531->rx_skbs_list);
++ }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+ struct vsc8531_private *priv = phydev->priv;
+@@ -1608,7 +1607,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+
+ vsc8531->ptp->phydev = phydev;
+
+- return 0;
++ vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++ vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++ vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++ vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
++ phydev->mii_ts = &vsc8531->mii_ts;
++
++ memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
++ vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++ &phydev->mdio.dev);
++ return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+--
+2.50.1
+
--- /dev/null
+From fea42020e1cc8cf9cd2d6c512325306a8903b262 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 5b3c093611baf..7209d00a9c257 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+ }
+
+- switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++ switch (inst_no_rt & ~KVM_MASK_RB) {
+ case KVM_INST_MTSRIN:
+ if (features & KVM_MAGIC_FEAT_SR) {
+ u32 inst_rb = _inst & KVM_MASK_RB;
+ kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+ }
+ break;
+-#endif
+ }
++#endif
+
+- switch (_inst) {
+ #ifdef CONFIG_BOOKE
++ switch (_inst) {
+ case KVM_INST_WRTEEI_0:
+ kvm_patch_ins_wrteei_0(inst);
+ break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ case KVM_INST_WRTEEI_1:
+ kvm_patch_ins_wrtee(inst, 0, 1);
+ break;
+-#endif
+ }
++#endif
+ }
+
+ extern u32 kvm_template_start[];
+--
+2.50.1
+
--- /dev/null
+From 192861fb3fee49d6282d4a56c7068160ef4216f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+ sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+ sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+ sctp_get_port net/sctp/socket.c:8523 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+ x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+ sctp_get_port net/sctp/socket.c:8515 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index d081858c2d073..a1cb8ac0408af 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -547,7 +547,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+ addr->v6.sin6_family = AF_INET6;
+ addr->v6.sin6_port = 0;
++ addr->v6.sin6_flowinfo = 0;
+ addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++ addr->v6.sin6_scope_id = 0;
+ }
+
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+--
+2.50.1
+
nfs-fold-nfs_page_group_lock_subrequests-into-nfs_lock_and_join_requests.patch
nfs-fix-a-race-when-updating-an-existing-write.patch
vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+drm-msm-defer-fd_install-in-submit-ioctl.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+hid-input-rename-hidinput_set_battery_charge_status.patch
+hid-input-report-battery-status-changes-immediately.patch
+bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
+bluetooth-hci_event-mark-connection-as-closed-during.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+bluetooth-hci_sync-fix-set_local_name-race-condition.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
+net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+net-rose-split-remove-and-free-operations-in-rose_re.patch
+net-rose-convert-use-field-to-refcount_t.patch
+net-rose-include-node-references-in-rose_neigh-refco.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
--- /dev/null
+From 687aceb7b0d9af513b48098f317fcb30bf1e67bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+ struct atmtcp_control {
+ struct atmtcp_hdr hdr; /* must be first */
+ ...
+ atm_kptr_t vcc; /* both directions */
+ ...
+ } __ATM_API_ALIGN;
+
+ typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+ 1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+ 2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS: 00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x19b/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c | 17 ++++++++++++++---
+ include/linux/atmdev.h | 1 +
+ net/atm/common.c | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index eeae160c898d3..fa3c76a2b49d1 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+ return NULL;
+ }
+
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++ struct atmtcp_hdr *hdr;
++
++ if (skb->len < sizeof(struct atmtcp_hdr))
++ return -EINVAL;
++
++ hdr = (struct atmtcp_hdr *)skb->data;
++ if (hdr->length == ATMTCP_HDR_MAGIC)
++ return -EINVAL;
++
++ return 0;
++}
+
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ struct sk_buff *new_skb;
+ int result = 0;
+
+- if (skb->len < sizeof(struct atmtcp_hdr))
+- goto done;
+-
+ dev = vcc->dev_data;
+ hdr = (struct atmtcp_hdr *) skb->data;
+ if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+ .close = atmtcp_c_close,
++ .pre_send = atmtcp_c_pre_send,
+ .send = atmtcp_c_send
+ };
+
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8..70807c679f1ab 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+ int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+ void __user *arg);
+ #endif
++ int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+ int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/net/atm/common.c b/net/atm/common.c
+index d7f7976ea13ac..881c7f259dbd4 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+
+ skb->dev = NULL; /* for paths shared with net_device interfaces */
+ if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+- atm_return_tx(vcc, skb);
+- kfree_skb(skb);
+ error = -EFAULT;
+- goto out;
++ goto free_skb;
+ }
+ if (eff != size)
+ memset(skb->data + size, 0, eff-size);
++
++ if (vcc->dev->ops->pre_send) {
++ error = vcc->dev->ops->pre_send(vcc, skb);
++ if (error)
++ goto free_skb;
++ }
++
+ error = vcc->dev->ops->send(vcc, skb);
+ error = error ? error : size;
+ out:
+ release_sock(sk);
+ return error;
++free_skb:
++ atm_return_tx(vcc, skb);
++ kfree_skb(skb);
++ goto out;
+ }
+
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+--
+2.50.1
+
--- /dev/null
+From 8742d460d4ff9605984e6f4221b08411b078b60f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index b8213bfa0a674..262ff30261d67 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4395,7 +4395,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+ if (!conn)
+ continue;
+
+- conn->sent -= count;
++ /* Check if there is really enough packets outstanding before
++ * attempting to decrease the sent counter otherwise it could
++ * underflow..
++ */
++ if (conn->sent >= count) {
++ conn->sent -= count;
++ } else {
++ bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++ conn, conn->sent, count);
++ conn->sent = 0;
++ }
+
+ switch (conn->type) {
+ case ACL_LINK:
+--
+2.50.1
+
--- /dev/null
+From a38f9aa0ee062b0243b10165b8a71996ed90c694 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:27 +0200
+Subject: Bluetooth: hci_event: Mark connection as closed during suspend
+ disconnect
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit b7fafbc499b5ee164018eb0eefe9027f5a6aaad2 ]
+
+When suspending, the disconnect command for an active Bluetooth
+connection could be issued, but the corresponding
+`HCI_EV_DISCONN_COMPLETE` event might not be received before the system
+completes the suspend process. This can lead to an inconsistent state.
+
+On resume, the controller may auto-accept reconnections from the same
+device (due to suspend event filters), but these new connections are
+rejected by the kernel which still has connection objects from before
+suspend. Resulting in errors like:
+```
+kernel: Bluetooth: hci0: ACL packet for unknown connection handle 1
+kernel: Bluetooth: hci0: Ignoring HCI_Connection_Complete for existing
+connection
+```
+
+This is a btmon snippet that shows the issue:
+```
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+ Handle: 1 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+ Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+ Disconnect (0x01|0x0006) ncmd 2
+ Status: Success (0x00)
+[...]
+// Host suspends with the event filter set for the device
+// On resume, the device tries to reconnect with a new handle
+
+> HCI Event: Connect Complete (0x03) plen 11
+ Status: Success (0x00)
+ Handle: 2
+ Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+
+// Kernel ignores this event because there is an existing connection
+with
+// handle 1
+```
+
+By explicitly setting the connection state to BT_CLOSED we can ensure a
+consistent state, even if we don't receive the disconnect complete event
+in time.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 428aba38a3654..b8213bfa0a674 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2709,6 +2709,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+ goto done;
+ }
+
++ /* During suspend, mark connection as closed immediately
++ * since we might not receive HCI_EV_DISCONN_COMPLETE
++ */
++ if (hdev->suspended)
++ conn->state = BT_CLOSED;
++
+ mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
+
+ if (conn->type == ACL_LINK) {
+--
+2.50.1
+
--- /dev/null
+From eacf8dc08de40aae74d47b0f4990737307871633 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:26 +0200
+Subject: Bluetooth: hci_event: Treat UNKNOWN_CONN_ID on disconnect as success
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit 2f050a5392b7a0928bf836d9891df4851463512c ]
+
+When the host sends an HCI_OP_DISCONNECT command, the controller may
+respond with the status HCI_ERROR_UNKNOWN_CONN_ID (0x02). E.g. this can
+happen on resume from suspend, if the link was terminated by the remote
+device before the event mask was correctly set.
+
+This is a btmon snippet that shows the issue:
+```
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+ L2CAP: Disconnection Request (0x06) ident 5 len 4
+ Destination CID: 65
+ Source CID: 72
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+ L2CAP: Disconnection Response (0x07) ident 5 len 4
+ Destination CID: 65
+ Source CID: 72
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+ L2CAP: Disconnection Request (0x06) ident 6 len 4
+ Destination CID: 64
+ Source CID: 71
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+ L2CAP: Disconnection Response (0x07) ident 6 len 4
+ Destination CID: 64
+ Source CID: 71
+< HCI Command: Set Event Mask (0x03|0x0001) plen 8
+ Mask: 0x3dbff807fffbffff
+ Inquiry Complete
+ Inquiry Result
+ Connection Complete
+ Connection Request
+ Disconnection Complete
+ Authentication Complete
+[...]
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+ Handle: 3 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+ Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+ Disconnect (0x01|0x0006) ncmd 1
+ Status: Unknown Connection Identifier (0x02)
+```
+
+Currently, the hci_cs_disconnect function treats any non-zero status
+as a command failure. This can be misleading because the connection is
+indeed being terminated and the controller is confirming that is has no
+knowledge of that connection handle. Meaning that the initial request of
+disconnecting a device should be treated as done.
+
+With this change we allow the function to proceed, following the success
+path, which correctly calls `mgmt_device_disconnected` and ensures a
+consistent state.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 768bd5fd808f2..428aba38a3654 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2694,7 +2694,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+ if (!conn)
+ goto unlock;
+
+- if (status) {
++ if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
+ mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+ conn->dst_type, status);
+
+--
+2.50.1
+
--- /dev/null
+From 1efa42f26b69b7a61f88a8c52cb27c12632a334a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 12:20:55 +0300
+Subject: Bluetooth: hci_sync: fix set_local_name race condition
+
+From: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+
+[ Upstream commit 6bbd0d3f0c23fc53c17409dd7476f38ae0ff0cd9 ]
+
+Function set_name_sync() uses hdev->dev_name field to send
+HCI_OP_WRITE_LOCAL_NAME command, but copying from data to hdev->dev_name
+is called after mgmt cmd was queued, so it is possible that function
+set_name_sync() will read old name value.
+
+This change adds name as a parameter for function hci_update_name_sync()
+to avoid race condition.
+
+Fixes: 6f6ff38a1e14 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LOCAL_NAME")
+Signed-off-by: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_sync.h | 2 +-
+ net/bluetooth/hci_sync.c | 6 +++---
+ net/bluetooth/mgmt.c | 5 ++++-
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index dbabc17b30cdf..17e5112f7840e 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -93,7 +93,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
+
+ int hci_update_eir_sync(struct hci_dev *hdev);
+ int hci_update_class_sync(struct hci_dev *hdev);
+-int hci_update_name_sync(struct hci_dev *hdev);
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
+ int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
+
+ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index af86df9de941d..bc2aa514b8c5d 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3491,13 +3491,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+ return hci_write_scan_enable_sync(hdev, scan);
+ }
+
+-int hci_update_name_sync(struct hci_dev *hdev)
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
+ {
+ struct hci_cp_write_local_name cp;
+
+ memset(&cp, 0, sizeof(cp));
+
+- memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
++ memcpy(cp.name, name, sizeof(cp.name));
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
+ sizeof(cp), &cp,
+@@ -3550,7 +3550,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
+ hci_write_fast_connectable_sync(hdev, false);
+ hci_update_scan_sync(hdev);
+ hci_update_class_sync(hdev);
+- hci_update_name_sync(hdev);
++ hci_update_name_sync(hdev, hdev->dev_name);
+ hci_update_eir_sync(hdev);
+ }
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index ade93532db34b..8b75647076bae 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3826,8 +3826,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
+
+ static int set_name_sync(struct hci_dev *hdev, void *data)
+ {
++ struct mgmt_pending_cmd *cmd = data;
++ struct mgmt_cp_set_local_name *cp = cmd->param;
++
+ if (lmp_bredr_capable(hdev)) {
+- hci_update_name_sync(hdev);
++ hci_update_name_sync(hdev, cp->name);
+ hci_update_eir_sync(hdev);
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 8a59728704077d2ebdbcded760bcf3b467776186 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:26 -0700
+Subject: bnxt_en: Adjust TX rings if reservation is less than requested
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit 1ee581c24dfdcbc6de25aac95a48c1f08e9a542c ]
+
+Before we accept an ethtool request to increase a resource (such as
+rings), we call the FW to check that the requested resource is likely
+available first before we commit. But it is still possible that
+the actual reservation or allocation can fail. The existing code
+is missing the logic to adjust the TX rings in case the reserved
+TX rings are less than requested. Add a warning message (a similar
+message for RX rings already exists) and add the logic to adjust
+the TX rings. Without this fix, the number of TX rings reported
+to the stack can exceed the actual TX rings and ethtool -l will
+report more than the actual TX rings.
+
+Fixes: 674f50a5b026 ("bnxt_en: Implement new method to reserve rings.")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-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 | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index dc123822771b6..b8c6087a5c31e 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -7788,6 +7788,11 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
+ hwr.rx = rx_rings << 1;
+ tx_cp = bnxt_num_tx_to_cp(bp, hwr.tx);
+ hwr.cp = sh ? max_t(int, tx_cp, rx_rings) : tx_cp + rx_rings;
++ if (hwr.tx != bp->tx_nr_rings) {
++ netdev_warn(bp->dev,
++ "Able to reserve only %d out of %d requested TX rings\n",
++ hwr.tx, bp->tx_nr_rings);
++ }
+ bp->tx_nr_rings = hwr.tx;
+
+ /* If we cannot reserve all the RX rings, reset the RSS map only
+@@ -12269,6 +12274,13 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
+ if (rc)
+ return rc;
+
++ /* Make adjustments if reserved TX rings are less than requested */
++ bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
++ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
++ if (bp->tx_nr_rings_xdp) {
++ bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
++ bp->tx_nr_rings += bp->tx_nr_rings_xdp;
++ }
+ rc = bnxt_alloc_mem(bp, irq_re_init);
+ if (rc) {
+ netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
+--
+2.50.1
+
--- /dev/null
+From a7e3730820faf6b43ca08e0dc86d3b5f3d26e2ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:25 -0700
+Subject: bnxt_en: Fix memory corruption when FW resources change during ifdown
+
+From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+
+[ Upstream commit 2747328ba2714f1a7454208dbbc1dc0631990b4a ]
+
+bnxt_set_dflt_rings() assumes that it is always called before any TC has
+been created. So it doesn't take bp->num_tc into account and assumes
+that it is always 0 or 1.
+
+In the FW resource or capability change scenario, the FW will return
+flags in bnxt_hwrm_if_change() that will cause the driver to
+reinitialize and call bnxt_cancel_reservations(). This will lead to
+bnxt_init_dflt_ring_mode() calling bnxt_set_dflt_rings() and bp->num_tc
+may be greater than 1. This will cause bp->tx_ring[] to be sized too
+small and cause memory corruption in bnxt_alloc_cp_rings().
+
+Fix it by properly scaling the TX rings by bp->num_tc in the code
+paths mentioned above. Add 2 helper functions to determine
+bp->tx_nr_rings and bp->tx_nr_rings_per_tc.
+
+Fixes: ec5d31e3c15d ("bnxt_en: Handle firmware reset status during IF_UP.")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
+Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-2-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 | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index f4bafc71a7399..dc123822771b6 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -12241,6 +12241,17 @@ static int bnxt_set_xps_mapping(struct bnxt *bp)
+ return rc;
+ }
+
++static int bnxt_tx_nr_rings(struct bnxt *bp)
++{
++ return bp->num_tc ? bp->tx_nr_rings_per_tc * bp->num_tc :
++ bp->tx_nr_rings_per_tc;
++}
++
++static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
++{
++ return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings;
++}
++
+ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
+ {
+ int rc = 0;
+@@ -15676,7 +15687,7 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
+ bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings);
+ bp->rx_nr_rings = bp->cp_nr_rings;
+ bp->tx_nr_rings_per_tc = bp->cp_nr_rings;
+- bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
++ bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+ }
+
+ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+@@ -15708,7 +15719,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+ bnxt_trim_dflt_sh_rings(bp);
+ else
+ bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
+- bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
++ bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+
+ avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
+ if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
+@@ -15721,7 +15732,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+ rc = __bnxt_reserve_rings(bp);
+ if (rc && rc != -ENODEV)
+ netdev_warn(bp->dev, "Unable to reserve tx rings\n");
+- bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+ if (sh)
+ bnxt_trim_dflt_sh_rings(bp);
+
+@@ -15730,7 +15741,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+ rc = __bnxt_reserve_rings(bp);
+ if (rc && rc != -ENODEV)
+ netdev_warn(bp->dev, "2nd rings reservation failed.\n");
+- bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+ }
+ if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
+ bp->rx_nr_rings++;
+@@ -15764,7 +15775,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
+ if (rc)
+ goto init_dflt_ring_err;
+
+- bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+
+ bnxt_set_dflt_rfs(bp);
+
+--
+2.50.1
+
--- /dev/null
+From 2ffd938d0b3fe90bd0cdbda7e7e124825add1978 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:27 -0700
+Subject: bnxt_en: Fix stats context reservation logic
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit b4fc8faacfea2538184a1dbd616ae9447a361f3d ]
+
+The HW resource reservation logic allows the L2 driver to use the
+RoCE resources if the RoCE driver is not registered. When calculating
+the stats contexts available for L2, we should not blindly subtract
+the stats contexts reserved for RoCE unless the RoCE driver is
+registered. This bug may cause the L2 rings to be less than the
+number requested when we are close to running out of stats contexts.
+
+Fixes: 2e4592dc9bee ("bnxt_en: Change MSIX/NQs allocation policy")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-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 | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index b8c6087a5c31e..08886c3a28c61 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -7780,7 +7780,8 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
+ }
+ rx_rings = min_t(int, rx_rings, hwr.grp);
+ hwr.cp = min_t(int, hwr.cp, bp->cp_nr_rings);
+- if (hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
++ if (bnxt_ulp_registered(bp->edev) &&
++ hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
+ hwr.stat -= bnxt_get_ulp_stat_ctxs(bp);
+ hwr.cp = min_t(int, hwr.cp, hwr.stat);
+ rc = bnxt_trim_rings(bp, &rx_rings, &hwr.tx, hwr.cp, sh);
+--
+2.50.1
+
--- /dev/null
+From 23bb2edbf20032947f7a47761276665fe714ce36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jul 2025 10:48:50 +0800
+Subject: drm/mediatek: Add error handling for old state CRTC in atomic_disable
+
+From: Jason-JH Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 0c6b24d70da21201ed009a2aca740d2dfddc7ab5 ]
+
+Introduce error handling to address an issue where, after a hotplug
+event, the cursor continues to update. This situation can lead to a
+kernel panic due to accessing the NULL `old_state->crtc`.
+
+E,g.
+Unable to handle kernel NULL pointer dereference at virtual address
+Call trace:
+ mtk_crtc_plane_disable+0x24/0x140
+ mtk_plane_atomic_update+0x8c/0xa8
+ drm_atomic_helper_commit_planes+0x114/0x2c8
+ drm_atomic_helper_commit_tail_rpm+0x4c/0x158
+ commit_tail+0xa0/0x168
+ drm_atomic_helper_commit+0x110/0x120
+ drm_atomic_commit+0x8c/0xe0
+ drm_atomic_helper_update_plane+0xd4/0x128
+ __setplane_atomic+0xcc/0x110
+ drm_mode_cursor_common+0x250/0x440
+ drm_mode_cursor_ioctl+0x44/0x70
+ drm_ioctl+0x264/0x5d8
+ __arm64_sys_ioctl+0xd8/0x510
+ invoke_syscall+0x6c/0xe0
+ do_el0_svc+0x68/0xe8
+ el0_svc+0x34/0x60
+ el0t_64_sync_handler+0x1c/0xf8
+ el0t_64_sync+0x180/0x188
+
+Adding NULL pointer checks to ensure stability by preventing operations
+on an invalid CRTC state.
+
+Fixes: d208261e9f7c ("drm/mediatek: Add wait_event_timeout when disabling plane")
+Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20250728025036.24953-1-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_plane.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
+index 74c2704efb664..6e20f7037b5bb 100644
+--- a/drivers/gpu/drm/mediatek/mtk_plane.c
++++ b/drivers/gpu/drm/mediatek/mtk_plane.c
+@@ -292,7 +292,8 @@ static void mtk_plane_atomic_disable(struct drm_plane *plane,
+ wmb(); /* Make sure the above parameter is set before update */
+ mtk_plane_state->pending.dirty = true;
+
+- mtk_crtc_plane_disable(old_state->crtc, plane);
++ if (old_state && old_state->crtc)
++ mtk_crtc_plane_disable(old_state->crtc, plane);
+ }
+
+ static void mtk_plane_atomic_update(struct drm_plane *plane,
+--
+2.50.1
+
--- /dev/null
+From 93316df3cf5624b86066b09d9e48489023825a58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jul 2025 13:28:22 -0700
+Subject: drm/msm: Defer fd_install in SUBMIT ioctl
+
+From: Rob Clark <robin.clark@oss.qualcomm.com>
+
+[ Upstream commit f22853435bbd1e9836d0dce7fd99c040b94c2bf1 ]
+
+Avoid fd_install() until there are no more potential error paths, to
+avoid put_unused_fd() after the fd is made visible to userspace.
+
+Fixes: 68dc6c2d5eec ("drm/msm: Fix submit error-path leaks")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/665363/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index 4b3a8ee8e278f..3eee6517541e3 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -879,12 +879,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+
+ if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+ sync_file = sync_file_create(submit->user_fence);
+- if (!sync_file) {
++ if (!sync_file)
+ ret = -ENOMEM;
+- } else {
+- fd_install(out_fence_fd, sync_file->file);
+- args->fence_fd = out_fence_fd;
+- }
+ }
+
+ if (ret)
+@@ -912,10 +908,14 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+ out_unlock:
+ mutex_unlock(&queue->lock);
+ out_post_unlock:
+- if (ret && (out_fence_fd >= 0)) {
+- put_unused_fd(out_fence_fd);
++ if (ret) {
++ if (out_fence_fd >= 0)
++ put_unused_fd(out_fence_fd);
+ if (sync_file)
+ fput(sync_file->file);
++ } else if (sync_file) {
++ fd_install(out_fence_fd, sync_file->file);
++ args->fence_fd = out_fence_fd;
+ }
+
+ if (!IS_ERR_OR_NULL(submit)) {
+--
+2.50.1
+
--- /dev/null
+From a57a0e8e68d8d2fbf0fab60ef8f37dca9d5aecd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jul 2025 18:50:37 +0300
+Subject: drm/msm/kms: move snapshot init earlier in KMS init
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 553666f839b86545300773954df7426a45c169c4 ]
+
+Various parts of the display driver can be triggering the display
+snapshot (including the IOMMU fault handlers). Move the call to
+msm_disp_snapshot_init() before KMS initialization, otherwise it is
+possible to ocassionally trigger the kernel fault during init:
+
+ __lock_acquire+0x44/0x2798 (P)
+ lock_acquire+0x114/0x25c
+ _raw_spin_lock_irqsave+0x6c/0x90
+ kthread_queue_work+0x2c/0xac
+ msm_disp_snapshot_state+0x2c/0x4c
+ msm_kms_fault_handler+0x2c/0x74
+ msm_disp_fault_handler+0x30/0x48
+ report_iommu_fault+0x54/0x128
+ arm_smmu_context_fault+0x74/0x184
+ __handle_irq_event_percpu+0xa4/0x24c
+ handle_irq_event_percpu+0x20/0x5c
+ handle_irq_event+0x48/0x84
+ handle_fasteoi_irq+0xcc/0x170
+ generic_handle_domain_irq+0x48/0x70
+ gic_handle_irq+0x54/0x11c
+ call_on_irq_stack+0x3c/0x50
+ do_interrupt_handler+0x54/0x78
+ el1_interrupt+0x3c/0x5c
+ el1h_64_irq_handler+0x20/0x30
+ el1h_64_irq+0x6c/0x70
+ _raw_spin_unlock_irqrestore+0x44/0x68 (P)
+ klist_next+0xc4/0x124
+ bus_for_each_drv+0x9c/0xe8
+ __device_attach+0xfc/0x190
+ device_initial_probe+0x1c/0x2c
+ bus_probe_device+0x44/0xa0
+ device_add+0x204/0x3e4
+ platform_device_add+0x170/0x244
+ platform_device_register_full+0x130/0x138
+ drm_connector_hdmi_audio_init+0xc0/0x108
+ drm_bridge_connector_init+0x318/0x394
+ msm_dsi_manager_connector_init+0xac/0xdc
+ msm_dsi_modeset_init+0x78/0xc0
+ _dpu_kms_drm_obj_init+0x198/0x75c
+ dpu_kms_hw_init+0x2f8/0x494
+ msm_drm_kms_init+0xb0/0x230
+ msm_drm_init+0x218/0x250
+ msm_drm_bind+0x3c/0x4c
+ try_to_bring_up_aggregate_device+0x208/0x2a4
+ __component_add+0xa8/0x188
+ component_add+0x1c/0x2c
+ dsi_dev_attach+0x24/0x34
+ dsi_host_attach+0x68/0xa0
+ devm_mipi_dsi_attach+0x40/0xcc
+ lt9611_attach_dsi+0x94/0x118
+ lt9611_probe+0x368/0x3c8
+ i2c_device_probe+0x2d0/0x3d8
+ really_probe+0x130/0x354
+ __driver_probe_device+0xac/0x110
+ driver_probe_device+0x44/0x110
+ __device_attach_driver+0xb0/0x138
+ bus_for_each_drv+0x90/0xe8
+ __device_attach+0xfc/0x190
+ device_initial_probe+0x1c/0x2c
+ bus_probe_device+0x44/0xa0
+ deferred_probe_work_func+0xac/0x110
+ process_one_work+0x20c/0x51c
+ process_scheduled_works+0x58/0x88
+ worker_thread+0x1ec/0x304
+ kthread+0x194/0x1d4
+ ret_from_fork+0x10/0x20
+
+Reported-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Fixes: 98659487b845 ("drm/msm: add support to take dpu snapshot")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/664149/
+Link: https://lore.kernel.org/r/20250715-msm-move-snapshot-init-v1-1-f39c396192ab@oss.qualcomm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_kms.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_kms.c b/drivers/gpu/drm/msm/msm_kms.c
+index 6749f0fbca96d..52464a1346f81 100644
+--- a/drivers/gpu/drm/msm/msm_kms.c
++++ b/drivers/gpu/drm/msm/msm_kms.c
+@@ -241,6 +241,12 @@ int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv)
+ if (ret)
+ return ret;
+
++ ret = msm_disp_snapshot_init(ddev);
++ if (ret) {
++ DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
++ return ret;
++ }
++
+ ret = priv->kms_init(ddev);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "failed to load kms\n");
+@@ -293,10 +299,6 @@ int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv)
+ goto err_msm_uninit;
+ }
+
+- ret = msm_disp_snapshot_init(ddev);
+- if (ret)
+- DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
+-
+ drm_mode_config_reset(ddev);
+
+ return 0;
+--
+2.50.1
+
--- /dev/null
+From 3644bfe38ef67e87834d43291a213eec2e79cc48 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jul 2025 18:09:38 +0530
+Subject: drm/msm: update the high bitfield of certain DSI registers
+
+From: Ayushi Makhija <quic_amakhija@quicinc.com>
+
+[ Upstream commit 494045c561e68945b1183ff416b8db8e37a122d6 ]
+
+Currently, the high bitfield of certain DSI registers
+do not align with the configuration of the SWI registers
+description. This can lead to wrong programming these DSI
+registers, for example for 4k resloution where H_TOTAL is
+taking 13 bits but software is programming only 12 bits
+because of the incorrect bitmask for H_TOTAL bitfeild,
+this is causing DSI FIFO errors. To resolve this issue,
+increase the high bitfield of the DSI registers from 12 bits
+to 16 bits in dsi.xml to match the SWI register configuration.
+
+Signed-off-by: Ayushi Makhija <quic_amakhija@quicinc.com>
+Fixes: 4f52f5e63b62 ("drm/msm: import XML display registers database")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/666229/
+Link: https://lore.kernel.org/r/20250730123938.1038640-1-quic_amakhija@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/registers/display/dsi.xml | 28 +++++++++----------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/registers/display/dsi.xml b/drivers/gpu/drm/msm/registers/display/dsi.xml
+index 501ffc585a9f6..c7a7b633d747b 100644
+--- a/drivers/gpu/drm/msm/registers/display/dsi.xml
++++ b/drivers/gpu/drm/msm/registers/display/dsi.xml
+@@ -159,28 +159,28 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+ <bitfield name="RGB_SWAP" low="12" high="14" type="dsi_rgb_swap"/>
+ </reg32>
+ <reg32 offset="0x00020" name="ACTIVE_H">
+- <bitfield name="START" low="0" high="11" type="uint"/>
+- <bitfield name="END" low="16" high="27" type="uint"/>
++ <bitfield name="START" low="0" high="15" type="uint"/>
++ <bitfield name="END" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x00024" name="ACTIVE_V">
+- <bitfield name="START" low="0" high="11" type="uint"/>
+- <bitfield name="END" low="16" high="27" type="uint"/>
++ <bitfield name="START" low="0" high="15" type="uint"/>
++ <bitfield name="END" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x00028" name="TOTAL">
+- <bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+- <bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
++ <bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
++ <bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x0002c" name="ACTIVE_HSYNC">
+- <bitfield name="START" low="0" high="11" type="uint"/>
+- <bitfield name="END" low="16" high="27" type="uint"/>
++ <bitfield name="START" low="0" high="15" type="uint"/>
++ <bitfield name="END" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x00030" name="ACTIVE_VSYNC_HPOS">
+- <bitfield name="START" low="0" high="11" type="uint"/>
+- <bitfield name="END" low="16" high="27" type="uint"/>
++ <bitfield name="START" low="0" high="15" type="uint"/>
++ <bitfield name="END" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x00034" name="ACTIVE_VSYNC_VPOS">
+- <bitfield name="START" low="0" high="11" type="uint"/>
+- <bitfield name="END" low="16" high="27" type="uint"/>
++ <bitfield name="START" low="0" high="15" type="uint"/>
++ <bitfield name="END" low="16" high="31" type="uint"/>
+ </reg32>
+
+ <reg32 offset="0x00038" name="CMD_DMA_CTRL">
+@@ -209,8 +209,8 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+ <bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x00058" name="CMD_MDP_STREAM0_TOTAL">
+- <bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+- <bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
++ <bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
++ <bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x0005c" name="CMD_MDP_STREAM1_CTRL">
+ <bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+--
+2.50.1
+
--- /dev/null
+From 9f1639b83ddb706015a8fa3e576957489ed4a49f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:03 -0500
+Subject: drm/nouveau: remove unused increment in gm200_flcn_pio_imem_wr
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit f529b8915543fb9ceb732cec5571f7fe12bc9530 ]
+
+The 'tag' parameter is passed by value and is not actually used after
+being incremented, so remove the increment. It's the function that calls
+gm200_flcn_pio_imem_wr that is supposed to (and does) increment 'tag'.
+
+Fixes: 0e44c2170876 ("drm/nouveau/flcn: new code to load+boot simple HS FWs (VPR scrubber)")
+Reviewed-by: Philipp Stanner <phasta@kernel.org>
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-2-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index b7da3ab44c277..6a004c6e67425 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -103,7 +103,7 @@ gm200_flcn_pio_imem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 i
+ static void
+ gm200_flcn_pio_imem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len, u16 tag)
+ {
+- nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag++);
++ nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag);
+ while (len >= 4) {
+ nvkm_falcon_wr32(falcon, 0x184 + (port * 0x10), *(u32 *)img);
+ img += 4;
+--
+2.50.1
+
--- /dev/null
+From 768c07fc37905da64c3caa744c8051260da4965b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:04 -0500
+Subject: drm/nouveau: remove unused memory target test
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit 64c722b5e7f6b909b0e448e580f64628a0d76208 ]
+
+The memory target check is a hold-over from a refactor. It's harmless
+but distracting, so just remove it.
+
+Fixes: 2541626cfb79 ("drm/nouveau/acr: use common falcon HS FW code for ACR FWs")
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-3-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index 6a004c6e67425..7c43397c19e61 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -249,9 +249,11 @@ int
+ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+ {
+ struct nvkm_falcon *falcon = fw->falcon;
+- int target, ret;
++ int ret;
+
+ if (fw->inst) {
++ int target;
++
+ nvkm_falcon_mask(falcon, 0x048, 0x00000001, 0x00000001);
+
+ switch (nvkm_memory_target(fw->inst)) {
+@@ -285,15 +287,6 @@ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+ }
+
+ if (fw->boot) {
+- switch (nvkm_memory_target(&fw->fw.mem.memory)) {
+- case NVKM_MEM_TARGET_VRAM: target = 4; break;
+- case NVKM_MEM_TARGET_HOST: target = 5; break;
+- case NVKM_MEM_TARGET_NCOH: target = 6; break;
+- default:
+- WARN_ON(1);
+- return -EINVAL;
+- }
+-
+ ret = nvkm_falcon_pio_wr(falcon, fw->boot, 0, 0,
+ IMEM, falcon->code.limit - fw->boot_size, fw->boot_size,
+ fw->boot_addr >> 8, false);
+--
+2.50.1
+
--- /dev/null
+From 60f50f33cd54966008a221b09a9f682a0127dcff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:28:41 -0700
+Subject: drm/xe: Don't trigger rebind on initial dma-buf validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthew Brost <matthew.brost@intel.com>
+
+[ Upstream commit 16ca06aa2c2218cb21907c0c45a746958c944def ]
+
+On the first validate of an imported dma-buf (initial bind), the device
+has no GPU mappings, so a rebind is unnecessary. Rebinding here is
+harmful in multi-GPU setups and for VMs using preempt-fence mode, as it
+would evict in-flight GPU work.
+
+v2:
+ - Drop dma_buf_validated, check for XE_PL_SYSTEM (Thomas)
+
+Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Link: https://lore.kernel.org/r/20250825152841.3837378-1-matthew.brost@intel.com
+(cherry picked from commit ffdf968762e4fb3cdae54e811ec3525e67440a60)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index 5f745d9ed6cc2..445bbe0299b08 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -671,7 +671,8 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
+ }
+
+ if (ttm_bo->type == ttm_bo_type_sg) {
+- ret = xe_bo_move_notify(bo, ctx);
++ if (new_mem->mem_type == XE_PL_SYSTEM)
++ ret = xe_bo_move_notify(bo, ctx);
+ if (!ret)
+ ret = xe_bo_move_dmabuf(ttm_bo, new_mem);
+ return ret;
+--
+2.50.1
+
--- /dev/null
+From b324dc7789028df9286c46bfd4fc6fda30707fe7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 10:39:04 +0200
+Subject: drm/xe/xe_sync: avoid race during ufence signaling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
+
+[ Upstream commit 04e1f683cd28dc9407b238543871a6e09a570dc0 ]
+
+Marking ufence as signalled after copy_to_user() is too late.
+Worker thread which signals ufence by memory write might be raced
+with another userspace vm-bind call. In map/unmap scenario unmap
+may still see ufence is not signalled causing -EBUSY. Change the
+order of marking / write to user-fence fixes this issue.
+
+Fixes: 977e5b82e090 ("drm/xe: Expose user fence from xe_sync_entry")
+Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/5536
+Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Matthew Auld <matthew.auld@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://lore.kernel.org/r/20250820083903.2109891-2-zbigniew.kempczynski@intel.com
+(cherry picked from commit 8ae04fe9ffc93d6bc3bc63ac08375427d69cee06)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_sync.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c
+index b0684e6d2047b..dd7bd766ae184 100644
+--- a/drivers/gpu/drm/xe/xe_sync.c
++++ b/drivers/gpu/drm/xe/xe_sync.c
+@@ -77,6 +77,7 @@ static void user_fence_worker(struct work_struct *w)
+ {
+ struct xe_user_fence *ufence = container_of(w, struct xe_user_fence, worker);
+
++ WRITE_ONCE(ufence->signalled, 1);
+ if (mmget_not_zero(ufence->mm)) {
+ kthread_use_mm(ufence->mm);
+ if (copy_to_user(ufence->addr, &ufence->value, sizeof(ufence->value)))
+@@ -89,7 +90,6 @@ static void user_fence_worker(struct work_struct *w)
+ * Wake up waiters only after updating the ufence state, allowing the UMD
+ * to safely reuse the same ufence without encountering -EBUSY errors.
+ */
+- WRITE_ONCE(ufence->signalled, 1);
+ wake_up_all(&ufence->xe->ufence_wq);
+ user_fence_put(ufence);
+ }
+--
+2.50.1
+
--- /dev/null
+From 3c58e54ef9ec24d58a23ea32aa2373306d37a0e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Aug 2025 11:36:54 +0300
+Subject: dt-bindings: display/msm: qcom,mdp5: drop lut clock
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 7ab3b7579a6d2660a3425b9ea93b9a140b07f49c ]
+
+None of MDP5 platforms have a LUT clock on the display-controller, it
+was added by the mistake. Drop it, fixing DT warnings on MSM8976 /
+MSM8956 platforms. Technically it's an ABI break, but no other platforms
+are affected.
+
+Fixes: 385c8ac763b3 ("dt-bindings: display/msm: convert MDP5 schema to YAML format")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Patchwork: https://patchwork.freedesktop.org/patch/667822/
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+index e153f8d26e7aa..2735c78b0b67a 100644
+--- a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
++++ b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+@@ -60,7 +60,6 @@ properties:
+ - const: bus
+ - const: core
+ - const: vsync
+- - const: lut
+ - const: tbu
+ - const: tbu_rt
+ # MSM8996 has additional iommu clock
+--
+2.50.1
+
--- /dev/null
+From 1329715063cc21aa07b52f39911d96b406c76254 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 18:07:10 +0200
+Subject: efi: stmm: Fix incorrect buffer allocation method
+
+From: Jan Kiszka <jan.kiszka@siemens.com>
+
+[ Upstream commit c5e81e672699e0c5557b2b755cc8f7a69aa92bff ]
+
+The communication buffer allocated by setup_mm_hdr() is later on passed
+to tee_shm_register_kernel_buf(). The latter expects those buffers to be
+contiguous pages, but setup_mm_hdr() just uses kmalloc(). That can cause
+various corruptions or BUGs, specifically since commit 9aec2fb0fd5e
+("slab: allocate frozen pages"), though it was broken before as well.
+
+Fix this by using alloc_pages_exact() instead of kmalloc().
+
+Fixes: c44b6be62e8d ("efi: Add tee-based EFI variable driver")
+Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
+Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
+Acked-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/stmm/tee_stmm_efi.c | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/firmware/efi/stmm/tee_stmm_efi.c b/drivers/firmware/efi/stmm/tee_stmm_efi.c
+index f741ca279052b..e15d11ed165ee 100644
+--- a/drivers/firmware/efi/stmm/tee_stmm_efi.c
++++ b/drivers/firmware/efi/stmm/tee_stmm_efi.c
+@@ -143,6 +143,10 @@ static efi_status_t mm_communicate(u8 *comm_buf, size_t payload_size)
+ return var_hdr->ret_status;
+ }
+
++#define COMM_BUF_SIZE(__payload_size) (MM_COMMUNICATE_HEADER_SIZE + \
++ MM_VARIABLE_COMMUNICATE_SIZE + \
++ (__payload_size))
++
+ /**
+ * setup_mm_hdr() - Allocate a buffer for StandAloneMM and initialize the
+ * header data.
+@@ -173,9 +177,8 @@ static void *setup_mm_hdr(u8 **dptr, size_t payload_size, size_t func,
+ return NULL;
+ }
+
+- comm_buf = kzalloc(MM_COMMUNICATE_HEADER_SIZE +
+- MM_VARIABLE_COMMUNICATE_SIZE + payload_size,
+- GFP_KERNEL);
++ comm_buf = alloc_pages_exact(COMM_BUF_SIZE(payload_size),
++ GFP_KERNEL | __GFP_ZERO);
+ if (!comm_buf) {
+ *ret = EFI_OUT_OF_RESOURCES;
+ return NULL;
+@@ -239,7 +242,7 @@ static efi_status_t get_max_payload(size_t *size)
+ */
+ *size -= 2;
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+@@ -282,7 +285,7 @@ static efi_status_t get_property_int(u16 *name, size_t name_size,
+ memcpy(var_property, &smm_property->property, sizeof(*var_property));
+
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+@@ -347,7 +350,7 @@ static efi_status_t tee_get_variable(u16 *name, efi_guid_t *vendor,
+ memcpy(data, (u8 *)var_acc->name + var_acc->name_size,
+ var_acc->data_size);
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+@@ -404,7 +407,7 @@ static efi_status_t tee_get_next_variable(unsigned long *name_size,
+ memcpy(name, var_getnext->name, var_getnext->name_size);
+
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+@@ -467,7 +470,7 @@ static efi_status_t tee_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ ret = mm_communicate(comm_buf, payload_size);
+ dev_dbg(pvt_data.dev, "Set Variable %s %d %lx\n", __FILE__, __LINE__, ret);
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+@@ -507,7 +510,7 @@ static efi_status_t tee_query_variable_info(u32 attributes,
+ *max_variable_size = mm_query_info->max_variable_size;
+
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 3ac5c874579749a79dd928cbafa4115d9757d66a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+ BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+ Call trace:
+ kasan_check_range+0xe8/0x190
+ __asan_loadN+0x1c/0x28
+ memcmp+0x98/0xd0
+ efivarfs_d_compare+0x68/0xd8
+ __d_lookup_rcu_op_compare+0x178/0x218
+ __d_lookup_rcu+0x1f8/0x228
+ d_alloc_parallel+0x150/0x648
+ lookup_open.isra.0+0x5f0/0x8d0
+ open_last_lookups+0x264/0x828
+ path_openat+0x130/0x3f8
+ do_filp_open+0x114/0x248
+ do_sys_openat2+0x340/0x3c0
+ __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+ T1 T2
+ lookup_open
+ ->lookup
+ simple_lookup
+ d_add
+ // invalid dentry is added to hash list
+
+ lookup_open
+ d_alloc_parallel
+ __d_lookup_rcu
+ __d_lookup_rcu_op_compare
+ hlist_bl_for_each_entry_rcu
+ // invalid dentry can be retrieved
+ ->d_compare
+ efivarfs_d_compare
+ // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 11ebddc57bc73..1831e015b2f26 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -127,6 +127,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+ int guid = len - EFI_VARIABLE_GUID_LEN;
+
++ /* Parallel lookups may produce a temporary invalid filename */
++ if (guid <= 0)
++ return 1;
++
+ if (name->len != len)
+ return 1;
+
+--
+2.50.1
+
--- /dev/null
+From 0ab0a25913e4111285f05def02dcd646101a15c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 15:56:13 -0700
+Subject: fbnic: Move phylink resume out of service_task and into open/close
+
+From: Alexander Duyck <alexanderduyck@fb.com>
+
+[ Upstream commit 6ede14a2c6365e7e5d855643c7c8390b5268c467 ]
+
+The fbnic driver was presenting with the following locking assert coming
+out of a PM resume:
+[ 42.208116][ T164] RTNL: assertion failed at drivers/net/phy/phylink.c (2611)
+[ 42.208492][ T164] WARNING: CPU: 1 PID: 164 at drivers/net/phy/phylink.c:2611 phylink_resume+0x190/0x1e0
+[ 42.208872][ T164] Modules linked in:
+[ 42.209140][ T164] CPU: 1 UID: 0 PID: 164 Comm: bash Not tainted 6.17.0-rc2-virtme #134 PREEMPT(full)
+[ 42.209496][ T164] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-5.fc42 04/01/2014
+[ 42.209861][ T164] RIP: 0010:phylink_resume+0x190/0x1e0
+[ 42.210057][ T164] Code: 83 e5 01 0f 85 b0 fe ff ff c6 05 1c cd 3e 02 01 90 ba 33 0a 00 00 48 c7 c6 20 3a 1d a5 48 c7 c7 e0 3e 1d a5 e8 21 b8 90 fe 90 <0f> 0b 90 90 e9 86 fe ff ff e8 42 ea 1f ff e9 e2 fe ff ff 48 89 ef
+[ 42.210708][ T164] RSP: 0018:ffffc90000affbd8 EFLAGS: 00010296
+[ 42.210983][ T164] RAX: 0000000000000000 RBX: ffff8880078d8400 RCX: 0000000000000000
+[ 42.211235][ T164] RDX: 0000000000000000 RSI: 1ffffffff4f10938 RDI: 0000000000000001
+[ 42.211466][ T164] RBP: 0000000000000000 R08: ffffffffa2ae79ea R09: fffffbfff4b3eb84
+[ 42.211707][ T164] R10: 0000000000000003 R11: 0000000000000000 R12: ffff888007ad8000
+[ 42.211997][ T164] R13: 0000000000000002 R14: ffff888006a18800 R15: ffffffffa34c59e0
+[ 42.212234][ T164] FS: 00007f0dc8e39740(0000) GS:ffff88808f51f000(0000) knlGS:0000000000000000
+[ 42.212505][ T164] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 42.212704][ T164] CR2: 00007f0dc8e9fe10 CR3: 000000000b56d003 CR4: 0000000000772ef0
+[ 42.213227][ T164] PKRU: 55555554
+[ 42.213366][ T164] Call Trace:
+[ 42.213483][ T164] <TASK>
+[ 42.213565][ T164] __fbnic_pm_attach.isra.0+0x8e/0xa0
+[ 42.213725][ T164] pci_reset_function+0x116/0x1d0
+[ 42.213895][ T164] reset_store+0xa0/0x100
+[ 42.214025][ T164] ? pci_dev_reset_attr_is_visible+0x50/0x50
+[ 42.214221][ T164] ? sysfs_file_kobj+0xc1/0x1e0
+[ 42.214374][ T164] ? sysfs_kf_write+0x65/0x160
+[ 42.214526][ T164] kernfs_fop_write_iter+0x2f8/0x4c0
+[ 42.214677][ T164] ? kernfs_vma_page_mkwrite+0x1f0/0x1f0
+[ 42.214836][ T164] new_sync_write+0x308/0x6f0
+[ 42.214987][ T164] ? __lock_acquire+0x34c/0x740
+[ 42.215135][ T164] ? new_sync_read+0x6f0/0x6f0
+[ 42.215288][ T164] ? lock_acquire.part.0+0xbc/0x260
+[ 42.215440][ T164] ? ksys_write+0xff/0x200
+[ 42.215590][ T164] ? perf_trace_sched_switch+0x6d0/0x6d0
+[ 42.215742][ T164] vfs_write+0x65e/0xbb0
+[ 42.215876][ T164] ksys_write+0xff/0x200
+[ 42.215994][ T164] ? __ia32_sys_read+0xc0/0xc0
+[ 42.216141][ T164] ? do_user_addr_fault+0x269/0x9f0
+[ 42.216292][ T164] ? rcu_is_watching+0x15/0xd0
+[ 42.216442][ T164] do_syscall_64+0xbb/0x360
+[ 42.216591][ T164] entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[ 42.216784][ T164] RIP: 0033:0x7f0dc8ea9986
+
+A bit of digging showed that we were invoking the phylink_resume as a part
+of the fbnic_up path when we were enabling the service task while not
+holding the RTNL lock. We should be enabling this sooner as a part of the
+ndo_open path and then just letting the service task come online later.
+This will help to enforce the correct locking and brings the phylink
+interface online at the same time as the network interface, instead of at a
+later time.
+
+I tested this on QEMU to verify this was working by putting the system to
+sleep using "echo mem > /sys/power/state" to put the system to sleep in the
+guest and then using the command "system_wakeup" in the QEMU monitor.
+
+Fixes: 69684376eed5 ("eth: fbnic: Add link detection")
+Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Link: https://patch.msgid.link/175616257316.1963577.12238158800417771119.stgit@ahduyck-xeon-server.home.arpa
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 4 ++++
+ drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 2 --
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+index 79e94632533c8..a8c95b1732f4d 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+@@ -53,6 +53,8 @@ int __fbnic_open(struct fbnic_net *fbn)
+ fbnic_bmc_rpc_init(fbd);
+ fbnic_rss_reinit(fbd, fbn);
+
++ phylink_resume(fbn->phylink);
++
+ return 0;
+ release_ownership:
+ fbnic_fw_xmit_ownership_msg(fbn->fbd, false);
+@@ -79,6 +81,8 @@ static int fbnic_stop(struct net_device *netdev)
+ {
+ struct fbnic_net *fbn = netdev_priv(netdev);
+
++ phylink_suspend(fbn->phylink, fbnic_bmc_present(fbn->fbd));
++
+ fbnic_down(fbn);
+ fbnic_pcs_irq_disable(fbn->fbd);
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+index 268489b15616f..72bdc6c76c0c5 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+@@ -116,14 +116,12 @@ static void fbnic_service_task_start(struct fbnic_net *fbn)
+ struct fbnic_dev *fbd = fbn->fbd;
+
+ schedule_delayed_work(&fbd->service_task, HZ);
+- phylink_resume(fbn->phylink);
+ }
+
+ static void fbnic_service_task_stop(struct fbnic_net *fbn)
+ {
+ struct fbnic_dev *fbd = fbn->fbd;
+
+- phylink_suspend(fbn->phylink, fbnic_bmc_present(fbd));
+ cancel_delayed_work(&fbd->service_task);
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 6ed7183eeaccdf5f881b37501585d73357b3fe81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:39 +0200
+Subject: HID: input: rename hidinput_set_battery_charge_status()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit a82231b2a8712d0218fc286a9b0da328d419a3f4 ]
+
+In preparation for a patch fixing a bug affecting
+hidinput_set_battery_charge_status(), rename the function to
+hidinput_update_battery_charge_status() and move it up so it can be used
+by hidinput_update_battery().
+
+Refactor, no functional changes.
+
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Stable-dep-of: e94536e1d181 ("HID: input: report battery status changes immediately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input-test.c | 10 +++++-----
+ drivers/hid/hid-input.c | 38 ++++++++++++++++++------------------
+ 2 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c
+index 77c2d45ac62a7..6f5c71660d823 100644
+--- a/drivers/hid/hid-input-test.c
++++ b/drivers/hid/hid-input-test.c
+@@ -7,7 +7,7 @@
+
+ #include <kunit/test.h>
+
+-static void hid_test_input_set_battery_charge_status(struct kunit *test)
++static void hid_test_input_update_battery_charge_status(struct kunit *test)
+ {
+ struct hid_device *dev;
+ bool handled;
+@@ -15,15 +15,15 @@ static void hid_test_input_set_battery_charge_status(struct kunit *test)
+ dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
++ handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
+ KUNIT_EXPECT_FALSE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
++ handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
+ KUNIT_EXPECT_TRUE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
++ handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
+ KUNIT_EXPECT_TRUE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
+ }
+@@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
+ }
+
+ static struct kunit_case hid_input_tests[] = {
+- KUNIT_CASE(hid_test_input_set_battery_charge_status),
++ KUNIT_CASE(hid_test_input_update_battery_charge_status),
+ KUNIT_CASE(hid_test_input_get_battery_property),
+ { }
+ };
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 9d80635a91ebd..b372b74f3e24b 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -595,6 +595,20 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ dev->battery = NULL;
+ }
+
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++ unsigned int usage, int value)
++{
++ switch (usage) {
++ case HID_BAT_CHARGING:
++ dev->battery_charge_status = value ?
++ POWER_SUPPLY_STATUS_CHARGING :
++ POWER_SUPPLY_STATUS_DISCHARGING;
++ return true;
++ }
++
++ return false;
++}
++
+ static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+ int capacity;
+@@ -617,20 +631,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
+ power_supply_changed(dev->battery);
+ }
+ }
+-
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
+-{
+- switch (usage) {
+- case HID_BAT_CHARGING:
+- dev->battery_charge_status = value ?
+- POWER_SUPPLY_STATUS_CHARGING :
+- POWER_SUPPLY_STATUS_DISCHARGING;
+- return true;
+- }
+-
+- return false;
+-}
+ #else /* !CONFIG_HID_BATTERY_STRENGTH */
+ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+ struct hid_field *field, bool is_percentage)
+@@ -642,14 +642,14 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++ unsigned int usage, int value)
+ {
++ return false;
+ }
+
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
++static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+- return false;
+ }
+ #endif /* CONFIG_HID_BATTERY_STRENGTH */
+
+@@ -1515,7 +1515,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+ return;
+
+ if (usage->type == EV_PWR) {
+- bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
++ bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+
+ if (!handled)
+ hidinput_update_battery(hid, value);
+--
+2.50.1
+
--- /dev/null
+From 83093093b438e989a01804dd51939eca14ee3f84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:40 +0200
+Subject: HID: input: report battery status changes immediately
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit e94536e1d1818b0989aa19b443b7089f50133c35 ]
+
+Previously, the battery status (charging/discharging) was not reported
+immediately to user-space.
+
+For most input devices, this wasn't problematic because changing their
+battery status requires connecting them to a different bus.
+For example, a gamepad would report a discharging status while
+connected via Bluetooth and a charging status while connected via USB.
+
+However, certain devices are not connected or disconnected when their
+battery status changes. For example, a phone battery changes its status
+without connecting or disconnecting it.
+In these cases, the battery status was not reported immediately to user
+space.
+
+Report battery status changes immediately to user space to support
+these kinds of devices.
+
+Fixes: a608dc1c0639 ("HID: input: map battery system charging")
+Reported-by: 卢国宏 <luguohong@xiaomi.com>
+Closes: https://lore.kernel.org/linux-input/aI49Im0sGb6fpgc8@fedora/T/
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input.c | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index b372b74f3e24b..f5c217ac4bfaa 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -609,13 +609,19 @@ static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+ return false;
+ }
+
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++ int value)
+ {
+ int capacity;
+
+ if (!dev->battery)
+ return;
+
++ if (hidinput_update_battery_charge_status(dev, usage, value)) {
++ power_supply_changed(dev->battery);
++ return;
++ }
++
+ if (value == 0 || value < dev->battery_min || value > dev->battery_max)
+ return;
+
+@@ -642,13 +648,8 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+
+-static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
+-{
+- return false;
+-}
+-
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++ int value)
+ {
+ }
+ #endif /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1515,11 +1516,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+ return;
+
+ if (usage->type == EV_PWR) {
+- bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+-
+- if (!handled)
+- hidinput_update_battery(hid, value);
+-
++ hidinput_update_battery(hid, usage->hid, value);
+ return;
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 47b18549e5d8bd0cf953155c44834f4bfc3e496d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Sep 2024 17:27:09 +0000
+Subject: hv_netvsc: Link queues to NAPIs
+
+From: Joe Damato <jdamato@fastly.com>
+
+[ Upstream commit 8b641b5e4c782464c8818a71b443eeef8984bf34 ]
+
+Use netif_queue_set_napi to link queues to NAPI instances so that they
+can be queried with netlink.
+
+Shradha Gupta tested the patch and reported that the results are
+as expected:
+
+$ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/netdev.yaml \
+ --dump queue-get --json='{"ifindex": 2}'
+
+ [{'id': 0, 'ifindex': 2, 'napi-id': 8193, 'type': 'rx'},
+ {'id': 1, 'ifindex': 2, 'napi-id': 8194, 'type': 'rx'},
+ {'id': 2, 'ifindex': 2, 'napi-id': 8195, 'type': 'rx'},
+ {'id': 3, 'ifindex': 2, 'napi-id': 8196, 'type': 'rx'},
+ {'id': 4, 'ifindex': 2, 'napi-id': 8197, 'type': 'rx'},
+ {'id': 5, 'ifindex': 2, 'napi-id': 8198, 'type': 'rx'},
+ {'id': 6, 'ifindex': 2, 'napi-id': 8199, 'type': 'rx'},
+ {'id': 7, 'ifindex': 2, 'napi-id': 8200, 'type': 'rx'},
+ {'id': 0, 'ifindex': 2, 'napi-id': 8193, 'type': 'tx'},
+ {'id': 1, 'ifindex': 2, 'napi-id': 8194, 'type': 'tx'},
+ {'id': 2, 'ifindex': 2, 'napi-id': 8195, 'type': 'tx'},
+ {'id': 3, 'ifindex': 2, 'napi-id': 8196, 'type': 'tx'},
+ {'id': 4, 'ifindex': 2, 'napi-id': 8197, 'type': 'tx'},
+ {'id': 5, 'ifindex': 2, 'napi-id': 8198, 'type': 'tx'},
+ {'id': 6, 'ifindex': 2, 'napi-id': 8199, 'type': 'tx'},
+ {'id': 7, 'ifindex': 2, 'napi-id': 8200, 'type': 'tx'}]
+
+Signed-off-by: Joe Damato <jdamato@fastly.com>
+Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
+Tested-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 9448ccd85336 ("net: hv_netvsc: fix loss of early receive events from host during channel open.")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hyperv/netvsc.c | 13 ++++++++++++-
+ drivers/net/hyperv/rndis_filter.c | 9 +++++++--
+ 2 files changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+index 807465dd4c8e3..87ac2a5f18091 100644
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -712,8 +712,13 @@ void netvsc_device_remove(struct hv_device *device)
+ for (i = 0; i < net_device->num_chn; i++) {
+ /* See also vmbus_reset_channel_cb(). */
+ /* only disable enabled NAPI channel */
+- if (i < ndev->real_num_rx_queues)
++ if (i < ndev->real_num_rx_queues) {
++ netif_queue_set_napi(ndev, i, NETDEV_QUEUE_TYPE_TX,
++ NULL);
++ netif_queue_set_napi(ndev, i, NETDEV_QUEUE_TYPE_RX,
++ NULL);
+ napi_disable(&net_device->chan_table[i].napi);
++ }
+
+ netif_napi_del(&net_device->chan_table[i].napi);
+ }
+@@ -1826,6 +1831,10 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+ netdev_dbg(ndev, "hv_netvsc channel opened successfully\n");
+
+ napi_enable(&net_device->chan_table[0].napi);
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
++ &net_device->chan_table[0].napi);
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
++ &net_device->chan_table[0].napi);
+
+ /* Connect with the NetVsp */
+ ret = netvsc_connect_vsp(device, net_device, device_info);
+@@ -1844,6 +1853,8 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+
+ close:
+ RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
+ napi_disable(&net_device->chan_table[0].napi);
+
+ /* Now, we can close the channel safely */
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+index e457f809fe311..9b8769a8b77a1 100644
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1255,10 +1255,15 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
+ ret = vmbus_open(new_sc, netvsc_ring_bytes,
+ netvsc_ring_bytes, NULL, 0,
+ netvsc_channel_cb, nvchan);
+- if (ret == 0)
++ if (ret == 0) {
+ napi_enable(&nvchan->napi);
+- else
++ netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++ &nvchan->napi);
++ netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++ &nvchan->napi);
++ } else {
+ netdev_notice(ndev, "sub channel open failed: %d\n", ret);
++ }
+
+ if (atomic_inc_return(&nvscdev->open_chn) == nvscdev->num_chn)
+ wake_up(&nvscdev->subchan_open);
+--
+2.50.1
+
--- /dev/null
+From 13b10e4ac93c7b81a58b661ff2004d05ab52d197 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 09:57:09 -0700
+Subject: ice: don't leave device non-functional if Tx scheduler config fails
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 86aae43f21cf784c1d7f6a9af93e5116b0f232ab ]
+
+The ice_cfg_tx_topo function attempts to apply Tx scheduler topology
+configuration based on NVM parameters, selecting either a 5 or 9 layer
+topology.
+
+As part of this flow, the driver acquires the "Global Configuration Lock",
+which is a hardware resource associated with programming the DDP package
+to the device. This "lock" is implemented by firmware as a way to
+guarantee that only one PF can program the DDP for a device. Unlike a
+traditional lock, once a PF has acquired this lock, no other PF will be
+able to acquire it again (including that PF) until a CORER of the device.
+Future requests to acquire the lock report that global configuration has
+already completed.
+
+The following flow is used to program the Tx topology:
+
+ * Read the DDP package for scheduler configuration data
+ * Acquire the global configuration lock
+ * Program Tx scheduler topology according to DDP package data
+ * Trigger a CORER which clears the global configuration lock
+
+This is followed by the flow for programming the DDP package:
+
+ * Acquire the global configuration lock (again)
+ * Download the DDP package to the device
+ * Release the global configuration lock.
+
+However, if configuration of the Tx topology fails, (i.e.
+ice_get_set_tx_topo returns an error code), the driver exits
+ice_cfg_tx_topo() immediately, and fails to trigger CORER.
+
+While the global configuration lock is held, the firmware rejects most
+AdminQ commands, as it is waiting for the DDP package download (or Tx
+scheduler topology programming) to occur.
+
+The current driver flows assume that the global configuration lock has been
+reset by CORER after programming the Tx topology. Thus, the same PF
+attempts to acquire the global lock again, and fails. This results in the
+driver reporting "an unknown error occurred when loading the DDP package".
+It then attempts to enter safe mode, but ultimately fails to finish
+ice_probe() since nearly all AdminQ command report error codes, and the
+driver stops loading the device at some point during its initialization.
+
+The only currently known way that ice_get_set_tx_topo() can fail is with
+certain older DDP packages which contain invalid topology configuration, on
+firmware versions which strictly validate this data. The most recent
+releases of the DDP have resolved the invalid data. However, it is still
+poor practice to essentially brick the device, and prevent access to the
+device even through safe mode or recovery mode. It is also plausible that
+this command could fail for some other reason in the future.
+
+We cannot simply release the global lock after a failed call to
+ice_get_set_tx_topo(). Releasing the lock indicates to firmware that global
+configuration (downloading of the DDP) has completed. Future attempts by
+this or other PFs to load the DDP will fail with a report that the DDP
+package has already been downloaded. Then, PFs will enter safe mode as they
+realize that the package on the device does not meet the minimum version
+requirement to load. The reported error messages are confusing, as they
+indicate the version of the default "safe mode" package in the NVM, rather
+than the version of the file loaded from /lib/firmware.
+
+Instead, we need to trigger CORER to clear global configuration. This is
+the lowest level of hardware reset which clears the global configuration
+lock and related state. It also clears any already downloaded DDP.
+Crucially, it does *not* clear the Tx scheduler topology configuration.
+
+Refactor ice_cfg_tx_topo() to always trigger a CORER after acquiring the
+global lock, regardless of success or failure of the topology
+configuration.
+
+We need to re-initialize the HW structure when we trigger the CORER. Thus,
+it makes sense for this to be the responsibility of ice_cfg_tx_topo()
+rather than its caller, ice_init_tx_topology(). This avoids needless
+re-initialization in cases where we don't attempt to update the Tx
+scheduler topology, such as if it has already been programmed.
+
+There is one catch: failure to re-initialize the HW struct should stop
+ice_probe(). If this function fails, we won't have a valid HW structure and
+cannot ensure the device is functioning properly. To handle this, ensure
+ice_cfg_tx_topo() returns a limited set of error codes. Set aside one
+specifically, -ENODEV, to indicate that the ice_init_tx_topology() should
+fail and stop probe.
+
+Other error codes indicate failure to apply the Tx scheduler topology. This
+is treated as a non-fatal error, with an informational message informing
+the system administrator that the updated Tx topology did not apply. This
+allows the device to load and function with the default Tx scheduler
+topology, rather than failing to load entirely.
+
+Note that this use of CORER will not result in loops with future PFs
+attempting to also load the invalid Tx topology configuration. The first PF
+will acquire the global configuration lock as part of programming the DDP.
+Each PF after this will attempt to acquire the global lock as part of
+programming the Tx topology, and will fail with the indication from
+firmware that global configuration is already complete. Tx scheduler
+topology configuration is only performed during driver init (probe or
+devlink reload) and not during cleanup for a CORER that happens after probe
+completes.
+
+Fixes: 91427e6d9030 ("ice: Support 5 layer topology")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_ddp.c | 44 ++++++++++++++++-------
+ drivers/net/ethernet/intel/ice/ice_main.c | 16 ++++++---
+ 2 files changed, 43 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c
+index e4c8cd12a41d1..04bec5d8e7084 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ddp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ddp.c
+@@ -2352,7 +2352,13 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,
+ * The function will apply the new Tx topology from the package buffer
+ * if available.
+ *
+- * Return: zero when update was successful, negative values otherwise.
++ * Return:
++ * * 0 - Successfully applied topology configuration.
++ * * -EBUSY - Failed to acquire global configuration lock.
++ * * -EEXIST - Topology configuration has already been applied.
++ * * -EIO - Unable to apply topology configuration.
++ * * -ENODEV - Failed to re-initialize device after applying configuration.
++ * * Other negative error codes indicate unexpected failures.
+ */
+ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+ {
+@@ -2385,7 +2391,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+
+ if (status) {
+ ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");
+- return status;
++ return -EIO;
+ }
+
+ /* Is default topology already applied ? */
+@@ -2472,31 +2478,45 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+ ICE_GLOBAL_CFG_LOCK_TIMEOUT);
+ if (status) {
+ ice_debug(hw, ICE_DBG_INIT, "Failed to acquire global lock\n");
+- return status;
++ return -EBUSY;
+ }
+
+ /* Check if reset was triggered already. */
+ reg = rd32(hw, GLGEN_RSTAT);
+ if (reg & GLGEN_RSTAT_DEVSTATE_M) {
+- /* Reset is in progress, re-init the HW again */
+ ice_debug(hw, ICE_DBG_INIT, "Reset is in progress. Layer topology might be applied already\n");
+ ice_check_reset(hw);
+- return 0;
++ /* Reset is in progress, re-init the HW again */
++ goto reinit_hw;
+ }
+
+ /* Set new topology */
+ status = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true);
+ if (status) {
+- ice_debug(hw, ICE_DBG_INIT, "Failed setting Tx topology\n");
+- return status;
++ ice_debug(hw, ICE_DBG_INIT, "Failed to set Tx topology, status %pe\n",
++ ERR_PTR(status));
++ /* only report -EIO here as the caller checks the error value
++ * and reports an informational error message informing that
++ * the driver failed to program Tx topology.
++ */
++ status = -EIO;
+ }
+
+- /* New topology is updated, delay 1 second before issuing the CORER */
++ /* Even if Tx topology config failed, we need to CORE reset here to
++ * clear the global configuration lock. Delay 1 second to allow
++ * hardware to settle then issue a CORER
++ */
+ msleep(1000);
+ ice_reset(hw, ICE_RESET_CORER);
+- /* CORER will clear the global lock, so no explicit call
+- * required for release.
+- */
++ ice_check_reset(hw);
++
++reinit_hw:
++ /* Since we triggered a CORER, re-initialize hardware */
++ ice_deinit_hw(hw);
++ if (ice_init_hw(hw)) {
++ ice_debug(hw, ICE_DBG_INIT, "Failed to re-init hardware after setting Tx topology\n");
++ return -ENODEV;
++ }
+
+- return 0;
++ return status;
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index d1abd21cfc647..74d4f2fde3e0f 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -4559,17 +4559,23 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware)
+ dev_info(dev, "Tx scheduling layers switching feature disabled\n");
+ else
+ dev_info(dev, "Tx scheduling layers switching feature enabled\n");
+- /* if there was a change in topology ice_cfg_tx_topo triggered
+- * a CORER and we need to re-init hw
++ return 0;
++ } else if (err == -ENODEV) {
++ /* If we failed to re-initialize the device, we can no longer
++ * continue loading.
+ */
+- ice_deinit_hw(hw);
+- err = ice_init_hw(hw);
+-
++ dev_warn(dev, "Failed to initialize hardware after applying Tx scheduling configuration.\n");
+ return err;
+ } else if (err == -EIO) {
+ dev_info(dev, "DDP package does not support Tx scheduling layers switching feature - please update to the latest DDP package and try again\n");
++ return 0;
++ } else if (err == -EEXIST) {
++ return 0;
+ }
+
++ /* Do not treat this as a fatal error. */
++ dev_info(dev, "Failed to apply Tx scheduling configuration, err %pe\n",
++ ERR_PTR(err));
+ return 0;
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 84791f14f20b44015822f6ca5791d1c0bd24585b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Aug 2025 17:53:10 +0200
+Subject: ice: fix incorrect counter for buffer allocation failures
+
+From: Michal Kubiak <michal.kubiak@intel.com>
+
+[ Upstream commit b1a0c977c6f1130f7dd125ee3db8c2435d7e3d41 ]
+
+Currently, the driver increments `alloc_page_failed` when buffer allocation fails
+in `ice_clean_rx_irq()`. However, this counter is intended for page allocation
+failures, not buffer allocation issues.
+
+This patch corrects the counter by incrementing `alloc_buf_failed` instead,
+ensuring accurate statistics reporting for buffer allocation failures.
+
+Fixes: 2fba7dc5157b ("ice: Add support for XDP multi-buffer on Rx side")
+Reported-by: Jacob Keller <jacob.e.keller@intel.com>
+Suggested-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Priya Singh <priyax.singh@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index f522dd42093a9..cde69f5686656 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -1295,7 +1295,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ skb = ice_construct_skb(rx_ring, xdp);
+ /* exit if we failed to retrieve a buffer */
+ if (!skb) {
+- rx_ring->ring_stats->rx_stats.alloc_page_failed++;
++ rx_ring->ring_stats->rx_stats.alloc_buf_failed++;
+ xdp_verdict = ICE_XDP_CONSUMED;
+ }
+ ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+--
+2.50.1
+
--- /dev/null
+From ec18b0f742f2f8c03c0d6c975059403927507bb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Aug 2025 15:27:12 -0700
+Subject: ice: use fixed adapter index for E825C embedded devices
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 5c5e5b52bf05c7fe88768318c041052c5fac36b8 ]
+
+The ice_adapter structure is used by the ice driver to connect multiple
+physical functions of a device in software. It was introduced by
+commit 0e2bddf9e5f9 ("ice: add ice_adapter for shared data across PFs on
+the same NIC") and is primarily used for PTP support, as well as for
+handling certain cross-PF synchronization.
+
+The original design of ice_adapter used PCI address information to
+determine which devices should be connected. This was extended to support
+E825C devices by commit fdb7f54700b1 ("ice: Initial support for E825C
+hardware in ice_adapter"), which used the device ID for E825C devices
+instead of the PCI address.
+
+Later, commit 0093cb194a75 ("ice: use DSN instead of PCI BDF for
+ice_adapter index") replaced the use of Bus/Device/Function addressing with
+use of the device serial number.
+
+E825C devices may appear in "Dual NAC" configuration which has multiple
+physical devices tied to the same clock source and which need to use the
+same ice_adapter. Unfortunately, each "NAC" has its own NVM which has its
+own unique Device Serial Number. Thus, use of the DSN for connecting
+ice_adapter does not work properly. It "worked" in the pre-production
+systems because the DSN was not initialized on the test NVMs and all the
+NACs had the same zero'd serial number.
+
+Since we cannot rely on the DSN, lets fall back to the logic in the
+original E825C support which used the device ID. This is safe for E825C
+only because of the embedded nature of the device. It isn't a discreet
+adapter that can be plugged into an arbitrary system. All E825C devices on
+a given system are connected to the same clock source and need to be
+configured through the same PTP clock.
+
+To make this separation clear, reserve bit 63 of the 64-bit index values as
+a "fixed index" indicator. Always clear this bit when using the device
+serial number as an index.
+
+For E825C, use a fixed value defined as the 0x579C E825C backplane device
+ID bitwise ORed with the fixed index indicator. This is slightly different
+than the original logic of just using the device ID directly. Doing so
+prevents a potential issue with systems where only one of the NACs is
+connected with an external PHY over SGMII. In that case, one NAC would
+have the E825C_SGMII device ID, but the other would not.
+
+Separate the determination of the full 64-bit index from the 32-bit
+reduction logic. Provide both ice_adapter_index() and a wrapping
+ice_adapter_xa_index() which handles reducing the index to a long on 32-bit
+systems. As before, cache the full index value in the adapter structure to
+warn about collisions.
+
+This fixes issues with E825C not initializing PTP on both NACs, due to
+failure to connect the appropriate devices to the same ice_adapter.
+
+Fixes: 0093cb194a75 ("ice: use DSN instead of PCI BDF for ice_adapter index")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_adapter.c | 49 +++++++++++++++-----
+ drivers/net/ethernet/intel/ice/ice_adapter.h | 4 +-
+ 2 files changed, 40 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.c b/drivers/net/ethernet/intel/ice/ice_adapter.c
+index 66e070095d1bb..10285995c9edd 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.c
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.c
+@@ -13,16 +13,45 @@
+ static DEFINE_XARRAY(ice_adapters);
+ static DEFINE_MUTEX(ice_adapters_mutex);
+
+-static unsigned long ice_adapter_index(u64 dsn)
++#define ICE_ADAPTER_FIXED_INDEX BIT_ULL(63)
++
++#define ICE_ADAPTER_INDEX_E825C \
++ (ICE_DEV_ID_E825C_BACKPLANE | ICE_ADAPTER_FIXED_INDEX)
++
++static u64 ice_adapter_index(struct pci_dev *pdev)
+ {
++ switch (pdev->device) {
++ case ICE_DEV_ID_E825C_BACKPLANE:
++ case ICE_DEV_ID_E825C_QSFP:
++ case ICE_DEV_ID_E825C_SFP:
++ case ICE_DEV_ID_E825C_SGMII:
++ /* E825C devices have multiple NACs which are connected to the
++ * same clock source, and which must share the same
++ * ice_adapter structure. We can't use the serial number since
++ * each NAC has its own NVM generated with its own unique
++ * Device Serial Number. Instead, rely on the embedded nature
++ * of the E825C devices, and use a fixed index. This relies on
++ * the fact that all E825C physical functions in a given
++ * system are part of the same overall device.
++ */
++ return ICE_ADAPTER_INDEX_E825C;
++ default:
++ return pci_get_dsn(pdev) & ~ICE_ADAPTER_FIXED_INDEX;
++ }
++}
++
++static unsigned long ice_adapter_xa_index(struct pci_dev *pdev)
++{
++ u64 index = ice_adapter_index(pdev);
++
+ #if BITS_PER_LONG == 64
+- return dsn;
++ return index;
+ #else
+- return (u32)dsn ^ (u32)(dsn >> 32);
++ return (u32)index ^ (u32)(index >> 32);
+ #endif
+ }
+
+-static struct ice_adapter *ice_adapter_new(u64 dsn)
++static struct ice_adapter *ice_adapter_new(struct pci_dev *pdev)
+ {
+ struct ice_adapter *adapter;
+
+@@ -30,7 +59,7 @@ static struct ice_adapter *ice_adapter_new(u64 dsn)
+ if (!adapter)
+ return NULL;
+
+- adapter->device_serial_number = dsn;
++ adapter->index = ice_adapter_index(pdev);
+ spin_lock_init(&adapter->ptp_gltsyn_time_lock);
+ refcount_set(&adapter->refcount, 1);
+
+@@ -63,24 +92,23 @@ static void ice_adapter_free(struct ice_adapter *adapter)
+ */
+ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
+ {
+- u64 dsn = pci_get_dsn(pdev);
+ struct ice_adapter *adapter;
+ unsigned long index;
+ int err;
+
+- index = ice_adapter_index(dsn);
++ index = ice_adapter_xa_index(pdev);
+ scoped_guard(mutex, &ice_adapters_mutex) {
+ err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
+ if (err == -EBUSY) {
+ adapter = xa_load(&ice_adapters, index);
+ refcount_inc(&adapter->refcount);
+- WARN_ON_ONCE(adapter->device_serial_number != dsn);
++ WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev));
+ return adapter;
+ }
+ if (err)
+ return ERR_PTR(err);
+
+- adapter = ice_adapter_new(dsn);
++ adapter = ice_adapter_new(pdev);
+ if (!adapter)
+ return ERR_PTR(-ENOMEM);
+ xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
+@@ -99,11 +127,10 @@ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
+ */
+ void ice_adapter_put(struct pci_dev *pdev)
+ {
+- u64 dsn = pci_get_dsn(pdev);
+ struct ice_adapter *adapter;
+ unsigned long index;
+
+- index = ice_adapter_index(dsn);
++ index = ice_adapter_xa_index(pdev);
+ scoped_guard(mutex, &ice_adapters_mutex) {
+ adapter = xa_load(&ice_adapters, index);
+ if (WARN_ON(!adapter))
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.h b/drivers/net/ethernet/intel/ice/ice_adapter.h
+index ac15c0d2bc1a4..409467847c753 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.h
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.h
+@@ -32,7 +32,7 @@ struct ice_port_list {
+ * @refcount: Reference count. struct ice_pf objects hold the references.
+ * @ctrl_pf: Control PF of the adapter
+ * @ports: Ports list
+- * @device_serial_number: DSN cached for collision detection on 32bit systems
++ * @index: 64-bit index cached for collision detection on 32bit systems
+ */
+ struct ice_adapter {
+ refcount_t refcount;
+@@ -41,7 +41,7 @@ struct ice_adapter {
+
+ struct ice_pf *ctrl_pf;
+ struct ice_port_list ports;
+- u64 device_serial_number;
++ u64 index;
+ };
+
+ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev);
+--
+2.50.1
+
--- /dev/null
+From a8e2d0e7edd1d9a33531482f397fb8c24195a72c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 13:44:35 +0000
+Subject: l2tp: do not use sock_hold() in pppol2tp_session_get_sock()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 9b8c88f875c04d4cb9111bd5dd9291c7e9691bf5 ]
+
+pppol2tp_session_get_sock() is using RCU, it must be ready
+for sk_refcnt being zero.
+
+Commit ee40fb2e1eb5 ("l2tp: protect sock pointer of
+struct pppol2tp_session with RCU") was correct because it
+had a call_rcu(..., pppol2tp_put_sk) which was later removed in blamed commit.
+
+pppol2tp_recv() can use pppol2tp_session_get_sock() as well.
+
+Fixes: c5cbaef992d6 ("l2tp: refactor ppp socket/session relationship")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: James Chapman <jchapman@katalix.com>
+Reviewed-by: Guillaume Nault <gnault@redhat.com>
+Link: https://patch.msgid.link/20250826134435.1683435-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_ppp.c | 25 ++++++++-----------------
+ 1 file changed, 8 insertions(+), 17 deletions(-)
+
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index 53baf2dd5d5da..16c514f628eac 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -129,22 +129,12 @@ static const struct ppp_channel_ops pppol2tp_chan_ops = {
+
+ static const struct proto_ops pppol2tp_ops;
+
+-/* Retrieves the pppol2tp socket associated to a session.
+- * A reference is held on the returned socket, so this function must be paired
+- * with sock_put().
+- */
++/* Retrieves the pppol2tp socket associated to a session. */
+ static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session)
+ {
+ struct pppol2tp_session *ps = l2tp_session_priv(session);
+- struct sock *sk;
+-
+- rcu_read_lock();
+- sk = rcu_dereference(ps->sk);
+- if (sk)
+- sock_hold(sk);
+- rcu_read_unlock();
+
+- return sk;
++ return rcu_dereference(ps->sk);
+ }
+
+ /* Helpers to obtain tunnel/session contexts from sockets.
+@@ -206,14 +196,13 @@ static int pppol2tp_recvmsg(struct socket *sock, struct msghdr *msg,
+
+ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
+ {
+- struct pppol2tp_session *ps = l2tp_session_priv(session);
+- struct sock *sk = NULL;
++ struct sock *sk;
+
+ /* If the socket is bound, send it in to PPP's input queue. Otherwise
+ * queue it on the session socket.
+ */
+ rcu_read_lock();
+- sk = rcu_dereference(ps->sk);
++ sk = pppol2tp_session_get_sock(session);
+ if (!sk)
+ goto no_sock;
+
+@@ -510,13 +499,14 @@ static void pppol2tp_show(struct seq_file *m, void *arg)
+ struct l2tp_session *session = arg;
+ struct sock *sk;
+
++ rcu_read_lock();
+ sk = pppol2tp_session_get_sock(session);
+ if (sk) {
+ struct pppox_sock *po = pppox_sk(sk);
+
+ seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan));
+- sock_put(sk);
+ }
++ rcu_read_unlock();
+ }
+
+ static void pppol2tp_session_init(struct l2tp_session *session)
+@@ -1529,6 +1519,7 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
+ port = ntohs(inet->inet_sport);
+ }
+
++ rcu_read_lock();
+ sk = pppol2tp_session_get_sock(session);
+ if (sk) {
+ state = sk->sk_state;
+@@ -1564,8 +1555,8 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
+ struct pppox_sock *po = pppox_sk(sk);
+
+ seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan));
+- sock_put(sk);
+ }
++ rcu_read_unlock();
+ }
+
+ static int pppol2tp_seq_show(struct seq_file *m, void *v)
+--
+2.50.1
+
--- /dev/null
+From c9f00cf87102c00aa4da68a43d324fb233ae7947 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index 787218d60c6b1..2c1b551e14423 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1091,7 +1091,7 @@ get_stats (struct net_device *dev)
+ dev->stats.rx_bytes += dr32(OctetRcvOk);
+ dev->stats.tx_bytes += dr32(OctetXmtOk);
+
+- dev->stats.multicast = dr32(McstFramesRcvdOk);
++ dev->stats.multicast += dr32(McstFramesRcvdOk);
+ dev->stats.collisions += dr32(SingleColFrames)
+ + dr32(MultiColFrames);
+
+--
+2.50.1
+
--- /dev/null
+From 3a60e772658803e5a200c03d353f7b78750ac313 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 04:56:27 -0700
+Subject: net: hv_netvsc: fix loss of early receive events from host during
+ channel open.
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 9448ccd853368582efa9db05db344f8bb9dffe0f ]
+
+The hv_netvsc driver currently enables NAPI after opening the primary and
+subchannels. This ordering creates a race: if the Hyper-V host places data
+in the host -> guest ring buffer and signals the channel before
+napi_enable() has been called, the channel callback will run but
+napi_schedule_prep() will return false. As a result, the NAPI poller never
+gets scheduled, the data in the ring buffer is not consumed, and the
+receive queue may remain permanently stuck until another interrupt happens
+to arrive.
+
+Fix this by enabling NAPI and registering it with the RX/TX queues before
+vmbus channel is opened. This guarantees that any early host signal after
+open will correctly trigger NAPI scheduling and the ring buffer will be
+drained.
+
+Fixes: 76bb5db5c749d ("netvsc: fix use after free on module removal")
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20250825115627.GA32189@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hyperv/netvsc.c | 17 ++++++++---------
+ drivers/net/hyperv/rndis_filter.c | 23 ++++++++++++++++-------
+ 2 files changed, 24 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+index 87ac2a5f18091..5f14799b68c53 100644
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -1811,6 +1811,11 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+
+ /* Enable NAPI handler before init callbacks */
+ netif_napi_add(ndev, &net_device->chan_table[0].napi, netvsc_poll);
++ napi_enable(&net_device->chan_table[0].napi);
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
++ &net_device->chan_table[0].napi);
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
++ &net_device->chan_table[0].napi);
+
+ /* Open the channel */
+ device->channel->next_request_id_callback = vmbus_next_request_id;
+@@ -1830,12 +1835,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+ /* Channel is opened */
+ netdev_dbg(ndev, "hv_netvsc channel opened successfully\n");
+
+- napi_enable(&net_device->chan_table[0].napi);
+- netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
+- &net_device->chan_table[0].napi);
+- netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
+- &net_device->chan_table[0].napi);
+-
+ /* Connect with the NetVsp */
+ ret = netvsc_connect_vsp(device, net_device, device_info);
+ if (ret != 0) {
+@@ -1853,14 +1852,14 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+
+ close:
+ RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
+- netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
+- netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
+- napi_disable(&net_device->chan_table[0].napi);
+
+ /* Now, we can close the channel safely */
+ vmbus_close(device->channel);
+
+ cleanup:
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
++ napi_disable(&net_device->chan_table[0].napi);
+ netif_napi_del(&net_device->chan_table[0].napi);
+
+ cleanup2:
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+index 9b8769a8b77a1..9a92552ee35c2 100644
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1252,17 +1252,26 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
+ new_sc->rqstor_size = netvsc_rqstor_size(netvsc_ring_bytes);
+ new_sc->max_pkt_size = NETVSC_MAX_PKT_SIZE;
+
++ /* Enable napi before opening the vmbus channel to avoid races
++ * as the host placing data on the host->guest ring may be left
++ * out if napi was not enabled.
++ */
++ napi_enable(&nvchan->napi);
++ netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++ &nvchan->napi);
++ netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++ &nvchan->napi);
++
+ ret = vmbus_open(new_sc, netvsc_ring_bytes,
+ netvsc_ring_bytes, NULL, 0,
+ netvsc_channel_cb, nvchan);
+- if (ret == 0) {
+- napi_enable(&nvchan->napi);
+- netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
+- &nvchan->napi);
+- netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
+- &nvchan->napi);
+- } else {
++ if (ret != 0) {
+ netdev_notice(ndev, "sub channel open failed: %d\n", ret);
++ netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++ NULL);
++ netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++ NULL);
++ napi_disable(&nvchan->napi);
+ }
+
+ if (atomic_inc_return(&nvscdev->open_chn) == nvscdev->num_chn)
+--
+2.50.1
+
--- /dev/null
+From 2053842dfbc405f44eb671b366bcb3f68e00f445 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 9a5c9497b3931..261ddb6542a40 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2532,12 +2532,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+ !netif_is_l3_master(dev_out))
+ return ERR_PTR(-EINVAL);
+
+- if (ipv4_is_lbcast(fl4->daddr))
++ if (ipv4_is_lbcast(fl4->daddr)) {
+ type = RTN_BROADCAST;
+- else if (ipv4_is_multicast(fl4->daddr))
++
++ /* reset fi to prevent gateway resolution */
++ fi = NULL;
++ } else if (ipv4_is_multicast(fl4->daddr)) {
+ type = RTN_MULTICAST;
+- else if (ipv4_is_zeronet(fl4->daddr))
++ } else if (ipv4_is_zeronet(fl4->daddr)) {
+ return ERR_PTR(-EINVAL);
++ }
+
+ if (dev_out->flags & IFF_LOOPBACK)
+ flags |= RTCF_LOCAL;
+--
+2.50.1
+
--- /dev/null
+From d50a0061fa6e2e36188ec60bb5f3c0201b9effe3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 10:30:22 -0400
+Subject: net: macb: Disable clocks once
+
+From: Neil Mandir <neil.mandir@seco.com>
+
+[ Upstream commit dac978e51cce0c1f00a14c4a82f81d387f79b2d4 ]
+
+When the driver is removed the clocks are disabled twice: once in
+macb_remove and a second time by runtime pm. Disable wakeup in remove so
+all the clocks are disabled and skip the second call to macb_clks_disable.
+Always suspend the device as we always set it active in probe.
+
+Fixes: d54f89af6cc4 ("net: macb: Add pm runtime support")
+Signed-off-by: Neil Mandir <neil.mandir@seco.com>
+Co-developed-by: Sean Anderson <sean.anderson@linux.dev>
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Link: https://patch.msgid.link/20250826143022.935521-1-sean.anderson@linux.dev
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index 2421a7bcd221e..6c2d69ef1a8db 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -5230,14 +5230,11 @@ static void macb_remove(struct platform_device *pdev)
+ mdiobus_unregister(bp->mii_bus);
+ mdiobus_free(bp->mii_bus);
+
++ device_set_wakeup_enable(&bp->pdev->dev, 0);
+ cancel_work_sync(&bp->hresp_err_bh_work);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+- if (!pm_runtime_suspended(&pdev->dev)) {
+- macb_clks_disable(bp->pclk, bp->hclk, bp->tx_clk,
+- bp->rx_clk, bp->tsu_clk);
+- pm_runtime_set_suspended(&pdev->dev);
+- }
++ pm_runtime_set_suspended(&pdev->dev);
+ phylink_destroy(bp->phylink);
+ free_netdev(dev);
+ }
+--
+2.50.1
+
--- /dev/null
+From 4682769487e10126710667542f30f606416557a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Aug 2025 07:25:27 +0800
+Subject: net: macb: fix unregister_netdev call order in macb_remove()
+
+From: luoguangfei <15388634752@163.com>
+
+[ Upstream commit 01b9128c5db1b470575d07b05b67ffa3cb02ebf1 ]
+
+When removing a macb device, the driver calls phy_exit() before
+unregister_netdev(). This leads to a WARN from kernfs:
+
+ ------------[ cut here ]------------
+ kernfs: can not remove 'attached_dev', no directory
+ WARNING: CPU: 1 PID: 27146 at fs/kernfs/dir.c:1683
+ Call trace:
+ kernfs_remove_by_name_ns+0xd8/0xf0
+ sysfs_remove_link+0x24/0x58
+ phy_detach+0x5c/0x168
+ phy_disconnect+0x4c/0x70
+ phylink_disconnect_phy+0x6c/0xc0 [phylink]
+ macb_close+0x6c/0x170 [macb]
+ ...
+ macb_remove+0x60/0x168 [macb]
+ platform_remove+0x5c/0x80
+ ...
+
+The warning happens because the PHY is being exited while the netdev
+is still registered. The correct order is to unregister the netdev
+before shutting down the PHY and cleaning up the MDIO bus.
+
+Fix this by moving unregister_netdev() ahead of phy_exit() in
+macb_remove().
+
+Fixes: 8b73fa3ae02b ("net: macb: Added ZynqMP-specific initialization")
+Signed-off-by: luoguangfei <15388634752@163.com>
+Link: https://patch.msgid.link/20250818232527.1316-1-15388634752@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index 3c2a7919b1289..2421a7bcd221e 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -5225,11 +5225,11 @@ static void macb_remove(struct platform_device *pdev)
+
+ if (dev) {
+ bp = netdev_priv(dev);
++ unregister_netdev(dev);
+ phy_exit(bp->sgmii_phy);
+ mdiobus_unregister(bp->mii_bus);
+ mdiobus_free(bp->mii_bus);
+
+- unregister_netdev(dev);
+ cancel_work_sync(&bp->hresp_err_bh_work);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+--
+2.50.1
+
--- /dev/null
+From 4ae30f329aee5fe1c57434e23ad9ae6cfc1fb216 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:29 +0300
+Subject: net/mlx5: Fix lockdep assertion on sync reset unload event
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 902a8bc23a24882200f57cadc270e15a2cfaf2bb ]
+
+Fix lockdep assertion triggered during sync reset unload event. When the
+sync reset flow is initiated using the devlink reload fw_activate
+option, the PF already holds the devlink lock while handling unload
+event. In this case, delegate sync reset unload event handling back to
+the devlink callback process to avoid double-locking and resolve the
+lockdep warning.
+
+Kernel log:
+WARNING: CPU: 9 PID: 1578 at devl_assert_locked+0x31/0x40
+[...]
+Call Trace:
+<TASK>
+ mlx5_unload_one_devl_locked+0x2c/0xc0 [mlx5_core]
+ mlx5_sync_reset_unload_event+0xaf/0x2f0 [mlx5_core]
+ process_one_work+0x222/0x640
+ worker_thread+0x199/0x350
+ kthread+0x10b/0x230
+ ? __pfx_worker_thread+0x10/0x10
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x8e/0x100
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+</TASK>
+
+Fixes: 7a9770f1bfea ("net/mlx5: Handle sync reset unload event")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-7-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ .../ethernet/mellanox/mlx5/core/fw_reset.c | 108 ++++++++++--------
+ .../ethernet/mellanox/mlx5/core/fw_reset.h | 1 +
+ 3 files changed, 63 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 7211e65ad2dcc..511b3ba245420 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+ if (err)
+ return err;
+
+- mlx5_unload_one_devl_locked(dev, false);
++ mlx5_sync_reset_unload_flow(dev, true);
+ err = mlx5_health_wait_pci_up(dev);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 4f55e55ecb551..0829912157c97 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -12,7 +12,8 @@ enum {
+ MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
+ MLX5_FW_RESET_FLAGS_PENDING_COMP,
+ MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
+- MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
++ MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
++ MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
+ };
+
+ struct mlx5_fw_reset {
+@@ -218,7 +219,7 @@ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev)
+ return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false);
+ }
+
+-static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unloaded)
++static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+ {
+ struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
+ struct devlink *devlink = priv_to_devlink(dev);
+@@ -227,8 +228,7 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unload
+ if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) {
+ complete(&fw_reset->done);
+ } else {
+- if (!unloaded)
+- mlx5_unload_one(dev, false);
++ mlx5_sync_reset_unload_flow(dev, false);
+ if (mlx5_health_wait_pci_up(dev))
+ mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
+ else
+@@ -271,7 +271,7 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work)
+
+ mlx5_sync_reset_clear_reset_requested(dev, false);
+ mlx5_enter_error_state(dev, true);
+- mlx5_fw_reset_complete_reload(dev, false);
++ mlx5_fw_reset_complete_reload(dev);
+ }
+
+ #define MLX5_RESET_POLL_INTERVAL (HZ / 10)
+@@ -581,6 +581,59 @@ static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method)
+ return err;
+ }
+
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked)
++{
++ struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
++ unsigned long timeout;
++ bool reset_action;
++ u8 rst_state;
++ int err;
++
++ if (locked)
++ mlx5_unload_one_devl_locked(dev, false);
++ else
++ mlx5_unload_one(dev, false);
++
++ if (!test_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags))
++ return;
++
++ mlx5_set_fw_rst_ack(dev);
++ mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
++
++ reset_action = false;
++ timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
++ do {
++ rst_state = mlx5_get_fw_rst_state(dev);
++ if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
++ rst_state == MLX5_FW_RST_STATE_IDLE) {
++ reset_action = true;
++ break;
++ }
++ msleep(20);
++ } while (!time_after(jiffies, timeout));
++
++ if (!reset_action) {
++ mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
++ rst_state);
++ fw_reset->ret = -ETIMEDOUT;
++ goto done;
++ }
++
++ mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n",
++ rst_state);
++ if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
++ err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
++ if (err) {
++ mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n",
++ err);
++ fw_reset->ret = err;
++ }
++ }
++
++done:
++ clear_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
++}
++
+ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ {
+ struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+@@ -608,16 +661,13 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ mlx5_enter_error_state(dev, true);
+ done:
+ fw_reset->ret = err;
+- mlx5_fw_reset_complete_reload(dev, false);
++ mlx5_fw_reset_complete_reload(dev);
+ }
+
+ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ {
+ struct mlx5_fw_reset *fw_reset;
+ struct mlx5_core_dev *dev;
+- unsigned long timeout;
+- bool reset_action;
+- u8 rst_state;
+ int err;
+
+ fw_reset = container_of(work, struct mlx5_fw_reset, reset_unload_work);
+@@ -626,6 +676,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ if (mlx5_sync_reset_clear_reset_requested(dev, false))
+ return;
+
++ set_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
+ mlx5_core_warn(dev, "Sync Reset Unload. Function is forced down.\n");
+
+ err = mlx5_cmd_fast_teardown_hca(dev);
+@@ -634,44 +685,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ else
+ mlx5_enter_error_state(dev, true);
+
+- if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
+- mlx5_unload_one_devl_locked(dev, false);
+- else
+- mlx5_unload_one(dev, false);
+-
+- mlx5_set_fw_rst_ack(dev);
+- mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
+-
+- reset_action = false;
+- timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
+- do {
+- rst_state = mlx5_get_fw_rst_state(dev);
+- if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
+- rst_state == MLX5_FW_RST_STATE_IDLE) {
+- reset_action = true;
+- break;
+- }
+- msleep(20);
+- } while (!time_after(jiffies, timeout));
+-
+- if (!reset_action) {
+- mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
+- rst_state);
+- fw_reset->ret = -ETIMEDOUT;
+- goto done;
+- }
+-
+- mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state);
+- if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
+- err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+- if (err) {
+- mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", err);
+- fw_reset->ret = err;
+- }
+- }
+-
+-done:
+- mlx5_fw_reset_complete_reload(dev, true);
++ mlx5_fw_reset_complete_reload(dev);
+ }
+
+ static void mlx5_sync_reset_abort_event(struct work_struct *work)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+index ea527d06a85f0..d5b28525c960d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+@@ -12,6 +12,7 @@ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel,
+ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
+
+ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
+ int mlx5_fw_reset_verify_fw_complete(struct mlx5_core_dev *dev,
+ struct netlink_ext_ack *extack);
+ void mlx5_fw_reset_events_start(struct mlx5_core_dev *dev);
+--
+2.50.1
+
--- /dev/null
+From 0305d98a7569aa2db9f851517fd3bf6d6209cc08 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:30 +0300
+Subject: net/mlx5: Nack sync reset when SFs are present
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 26e42ec7712d392d561964514b1f253b1a96f42d ]
+
+If PF (Physical Function) has SFs (Sub-Functions), since the SFs are not
+taking part in the synchronization flow, sync reset can lead to fatal
+error on the SFs, as the function will be closed unexpectedly from the
+SF point of view.
+
+Add a check to prevent sync reset when there are SFs on a PF device
+which is not ECPF, as ECPF is teardowned gracefully before reset.
+
+Fixes: 92501fa6e421 ("net/mlx5: Ack on sync_reset_request only if PF can do reset_now")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Parav Pandit <parav@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-8-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 6 ++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c | 10 ++++++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h | 6 ++++++
+ 3 files changed, 22 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 0829912157c97..516df7f1997eb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -6,6 +6,7 @@
+ #include "fw_reset.h"
+ #include "diag/fw_tracer.h"
+ #include "lib/tout.h"
++#include "sf/sf.h"
+
+ enum {
+ MLX5_FW_RESET_FLAGS_RESET_REQUESTED,
+@@ -423,6 +424,11 @@ static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev,
+ return false;
+ }
+
++ if (!mlx5_core_is_ecpf(dev) && !mlx5_sf_table_empty(dev)) {
++ mlx5_core_warn(dev, "SFs should be removed before reset\n");
++ return false;
++ }
++
+ #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)
+ if (reset_method != MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET) {
+ err = mlx5_check_hotplug_interrupt(dev);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index b96909fbeb12d..bdac3db1bd61d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -518,3 +518,13 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+ WARN_ON(!xa_empty(&table->function_ids));
+ kfree(table);
+ }
++
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++ struct mlx5_sf_table *table = dev->priv.sf_table;
++
++ if (!table)
++ return true;
++
++ return xa_empty(&table->function_ids);
++}
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+index 860f9ddb7107b..89559a37997ad 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+@@ -17,6 +17,7 @@ void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev);
+
+ int mlx5_sf_table_init(struct mlx5_core_dev *dev);
+ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev);
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev);
+
+ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+ const struct devlink_port_new_attrs *add_attr,
+@@ -61,6 +62,11 @@ static inline void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+ {
+ }
+
++static inline bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++ return true;
++}
++
+ #endif
+
+ #endif
+--
+2.50.1
+
--- /dev/null
+From 80660628a803bd3aacc006ba6403cfc16e627fd4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:28 +0300
+Subject: net/mlx5: Reload auxiliary drivers on fw_activate
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 34cc6a54914f478c93e176450fae6313404f9f74 ]
+
+The devlink reload fw_activate command performs firmware activation
+followed by driver reload, while devlink reload driver_reinit triggers
+only driver reload. However, the driver reload logic differs between the
+two modes, as on driver_reinit mode mlx5 also reloads auxiliary drivers,
+while in fw_activate mode the auxiliary drivers are suspended where
+applicable.
+
+Additionally, following the cited commit, if the device has multiple PFs,
+the behavior during fw_activate may vary between PFs: one PF may suspend
+auxiliary drivers, while another reloads them.
+
+Align devlink dev reload fw_activate behavior with devlink dev reload
+driver_reinit, to reload all auxiliary drivers.
+
+Fixes: 72ed5d5624af ("net/mlx5: Suspend auxiliary devices only in case of PCI device suspend")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-6-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index a2cf3e79693dd..7211e65ad2dcc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+ if (err)
+ return err;
+
+- mlx5_unload_one_devl_locked(dev, true);
++ mlx5_unload_one_devl_locked(dev, false);
+ err = mlx5_health_wait_pci_up(dev);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+--
+2.50.1
+
--- /dev/null
+From b11f28dc3d930781e666b59b5287b57ec75144c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@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/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index 3efa8bf1d14ef..4720523813b97 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -575,7 +575,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ if (err)
+ return err;
+ }
+- priv->dcbx.xoff = xoff;
+
+ /* Apply the settings */
+ if (update_buffer) {
+@@ -584,6 +583,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ return err;
+ }
+
++ priv->dcbx.xoff = xoff;
++
+ if (update_prio2buffer)
+ err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+
+--
+2.50.1
+
--- /dev/null
+From 66bef2beb2be1701962f54c355755376b35f1c32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+index f4a19ffbb641c..66d276a1be836 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -66,11 +66,23 @@ struct mlx5e_port_buffer {
+ struct mlx5e_bufferx_reg buffer[MLX5E_MAX_NETWORK_BUFFER];
+ };
+
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ u32 change, unsigned int mtu,
+ struct ieee_pfc *pfc,
+ u32 *buffer_size,
+ u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++ u32 change, unsigned int mtu,
++ void *pfc,
++ u32 *buffer_size,
++ u8 *prio2buffer)
++{
++ return 0;
++}
++#endif
+
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+ struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 4a2f58a9d7066..de2327ffb0f78 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -47,6 +47,7 @@
+ #include "en.h"
+ #include "en/dim.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2917,9 +2918,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ struct mlx5e_params *params = &priv->channels.params;
+ struct net_device *netdev = priv->netdev;
+ struct mlx5_core_dev *mdev = priv->mdev;
+- u16 mtu;
++ u16 mtu, prev_mtu;
+ int err;
+
++ mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+ err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+ if (err)
+ return err;
+@@ -2929,6 +2932,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+ __func__, mtu, params->sw_mtu);
+
++ if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++ err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++ NULL, NULL, NULL);
++ if (err) {
++ netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++ __func__, mtu, err, prev_mtu);
++
++ mlx5e_set_mtu(mdev, params, prev_mtu);
++ return err;
++ }
++ }
++
+ params->sw_mtu = mtu;
+ return 0;
+ }
+--
+2.50.1
+
--- /dev/null
+From ad7d85c7665145322f6cc2c6d3169d00eb152099 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@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_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index de2327ffb0f78..6176457b846bc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -135,6 +135,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+ if (up) {
+ netdev_info(priv->netdev, "Link up\n");
+ netif_carrier_on(priv->netdev);
++ mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++ NULL, NULL, NULL);
+ } else {
+ netdev_info(priv->netdev, "Link down\n");
+ netif_carrier_off(priv->netdev);
+--
+2.50.1
+
--- /dev/null
+From af3b1f96a4b1ec39e8ae59d453e7c3db06736ec4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:56 +0900
+Subject: net: rose: convert 'use' field to refcount_t
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit d860d1faa6b2ce3becfdb8b0c2b048ad31800061 ]
+
+The 'use' field in struct rose_neigh is used as a reference counter but
+lacks atomicity. This can lead to race conditions where a rose_neigh
+structure is freed while still being referenced by other code paths.
+
+For example, when rose_neigh->use becomes zero during an ioctl operation
+via rose_rt_ioctl(), the structure may be removed while its timer is
+still active, potentially causing use-after-free issues.
+
+This patch changes the type of 'use' from unsigned short to refcount_t and
+updates all code paths to use rose_neigh_hold() and rose_neigh_put() which
+operate reference counts atomically.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-3-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h | 18 +++++++++++++-----
+ net/rose/af_rose.c | 13 +++++++------
+ net/rose/rose_in.c | 12 ++++++------
+ net/rose/rose_route.c | 33 ++++++++++++++++++---------------
+ net/rose/rose_timer.c | 2 +-
+ 5 files changed, 45 insertions(+), 33 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 174b4f605d849..2b5491bbf39ab 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -8,6 +8,7 @@
+ #ifndef _ROSE_H
+ #define _ROSE_H
+
++#include <linux/refcount.h>
+ #include <linux/rose.h>
+ #include <net/ax25.h>
+ #include <net/sock.h>
+@@ -96,7 +97,7 @@ struct rose_neigh {
+ ax25_cb *ax25;
+ struct net_device *dev;
+ unsigned short count;
+- unsigned short use;
++ refcount_t use;
+ unsigned int number;
+ char restarted;
+ char dce_mode;
+@@ -151,12 +152,19 @@ struct rose_sock {
+
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
+
++static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
++{
++ refcount_inc(&rose_neigh->use);
++}
++
+ static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
+ {
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
++ if (refcount_dec_and_test(&rose_neigh->use)) {
++ if (rose_neigh->ax25)
++ ax25_cb_put(rose_neigh->ax25);
++ kfree(rose_neigh->digipeat);
++ kfree(rose_neigh);
++ }
+ }
+
+ /* af_rose.c */
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index a4a668b88a8f2..b8078b42f5de6 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -170,7 +170,7 @@ void rose_kill_by_neigh(struct rose_neigh *neigh)
+
+ if (rose->neighbour == neigh) {
+ rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose->neighbour = NULL;
+ }
+ }
+@@ -212,7 +212,7 @@ static void rose_kill_by_device(struct net_device *dev)
+ if (rose->device == dev) {
+ rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+ if (rose->neighbour)
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ netdev_put(rose->device, &rose->dev_tracker);
+ rose->device = NULL;
+ }
+@@ -655,7 +655,7 @@ static int rose_release(struct socket *sock)
+ break;
+
+ case ROSE_STATE_2:
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ release_sock(sk);
+ rose_disconnect(sk, 0, -1, -1);
+ lock_sock(sk);
+@@ -823,6 +823,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ rose->lci = rose_new_lci(rose->neighbour);
+ if (!rose->lci) {
+ err = -ENETUNREACH;
++ rose_neigh_put(rose->neighbour);
+ goto out_release;
+ }
+
+@@ -834,12 +835,14 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ dev = rose_dev_first();
+ if (!dev) {
+ err = -ENETUNREACH;
++ rose_neigh_put(rose->neighbour);
+ goto out_release;
+ }
+
+ user = ax25_findbyuid(current_euid());
+ if (!user) {
+ err = -EINVAL;
++ rose_neigh_put(rose->neighbour);
+ dev_put(dev);
+ goto out_release;
+ }
+@@ -874,8 +877,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+
+ rose->state = ROSE_STATE_1;
+
+- rose->neighbour->use++;
+-
+ rose_write_internal(sk, ROSE_CALL_REQUEST);
+ rose_start_heartbeat(sk);
+ rose_start_t1timer(sk);
+@@ -1077,7 +1078,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
+ GFP_ATOMIC);
+ make_rose->facilities = facilities;
+
+- make_rose->neighbour->use++;
++ rose_neigh_hold(make_rose->neighbour);
+
+ if (rose_sk(sk)->defer) {
+ make_rose->state = ROSE_STATE_5;
+diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
+index 4d67f36dce1b4..7caae93937ee9 100644
+--- a/net/rose/rose_in.c
++++ b/net/rose/rose_in.c
+@@ -56,7 +56,7 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -79,12 +79,12 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ case ROSE_CLEAR_CONFIRMATION:
+ rose_disconnect(sk, 0, -1, -1);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -120,7 +120,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ case ROSE_RR:
+@@ -233,7 +233,7 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -253,7 +253,7 @@ static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int framety
+ if (frametype == ROSE_CLEAR_REQUEST) {
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose_sk(sk)->neighbour->use--;
++ rose_neigh_put(rose_sk(sk)->neighbour);
+ }
+
+ return 0;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index b406b1e0fb1e7..42460da0854d5 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -93,11 +93,11 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ rose_neigh->ax25 = NULL;
+ rose_neigh->dev = dev;
+ rose_neigh->count = 0;
+- rose_neigh->use = 0;
+ rose_neigh->dce_mode = 0;
+ rose_neigh->loopback = 0;
+ rose_neigh->number = rose_neigh_no++;
+ rose_neigh->restarted = 0;
++ refcount_set(&rose_neigh->use, 1);
+
+ skb_queue_head_init(&rose_neigh->queue);
+
+@@ -255,10 +255,10 @@ static void rose_remove_route(struct rose_route *rose_route)
+ struct rose_route *s;
+
+ if (rose_route->neigh1 != NULL)
+- rose_route->neigh1->use--;
++ rose_neigh_put(rose_route->neigh1);
+
+ if (rose_route->neigh2 != NULL)
+- rose_route->neigh2->use--;
++ rose_neigh_put(rose_route->neigh2);
+
+ if ((s = rose_route_list) == rose_route) {
+ rose_route_list = rose_route->next;
+@@ -323,7 +323,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
+
+- if (rose_neigh->count == 0 && rose_neigh->use == 0) {
++ if (rose_neigh->count == 0) {
+ rose_remove_neigh(rose_neigh);
+ rose_neigh_put(rose_neigh);
+ }
+@@ -375,11 +375,11 @@ void rose_add_loopback_neigh(void)
+ sn->ax25 = NULL;
+ sn->dev = NULL;
+ sn->count = 0;
+- sn->use = 0;
+ sn->dce_mode = 1;
+ sn->loopback = 1;
+ sn->number = rose_neigh_no++;
+ sn->restarted = 1;
++ refcount_set(&sn->use, 1);
+
+ skb_queue_head_init(&sn->queue);
+
+@@ -561,8 +561,7 @@ static int rose_clear_routes(void)
+ s = rose_neigh;
+ rose_neigh = rose_neigh->next;
+
+- if (s->use == 0 && !s->loopback) {
+- s->count = 0;
++ if (!s->loopback) {
+ rose_remove_neigh(s);
+ rose_neigh_put(s);
+ }
+@@ -680,6 +679,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+ for (i = 0; i < node->count; i++) {
+ if (node->neighbour[i]->restarted) {
+ res = node->neighbour[i];
++ rose_neigh_hold(node->neighbour[i]);
+ goto out;
+ }
+ }
+@@ -691,6 +691,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+ for (i = 0; i < node->count; i++) {
+ if (!rose_ftimer_running(node->neighbour[i])) {
+ res = node->neighbour[i];
++ rose_neigh_hold(node->neighbour[i]);
+ goto out;
+ }
+ failed = 1;
+@@ -780,13 +781,13 @@ static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
+ }
+
+ if (rose_route->neigh1 == rose_neigh) {
+- rose_route->neigh1->use--;
++ rose_neigh_put(rose_route->neigh1);
+ rose_route->neigh1 = NULL;
+ rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
+ }
+
+ if (rose_route->neigh2 == rose_neigh) {
+- rose_route->neigh2->use--;
++ rose_neigh_put(rose_route->neigh2);
+ rose_route->neigh2 = NULL;
+ rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
+ }
+@@ -915,7 +916,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_clear_queues(sk);
+ rose->cause = ROSE_NETWORK_CONGESTION;
+ rose->diagnostic = 0;
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose->neighbour = NULL;
+ rose->lci = 0;
+ rose->state = ROSE_STATE_0;
+@@ -1040,12 +1041,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+
+ if ((new_lci = rose_new_lci(new_neigh)) == 0) {
+ rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
+- goto out;
++ goto put_neigh;
+ }
+
+ if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
+ rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
+- goto out;
++ goto put_neigh;
+ }
+
+ rose_route->lci1 = lci;
+@@ -1058,8 +1059,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_route->lci2 = new_lci;
+ rose_route->neigh2 = new_neigh;
+
+- rose_route->neigh1->use++;
+- rose_route->neigh2->use++;
++ rose_neigh_hold(rose_route->neigh1);
++ rose_neigh_hold(rose_route->neigh2);
+
+ rose_route->next = rose_route_list;
+ rose_route_list = rose_route;
+@@ -1071,6 +1072,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_transmit_link(skb, rose_route->neigh2);
+ res = 1;
+
++put_neigh:
++ rose_neigh_put(new_neigh);
+ out:
+ spin_unlock_bh(&rose_route_list_lock);
+ spin_unlock_bh(&rose_neigh_list_lock);
+@@ -1186,7 +1189,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+ (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+ rose_neigh->dev ? rose_neigh->dev->name : "???",
+ rose_neigh->count,
+- rose_neigh->use,
++ refcount_read(&rose_neigh->use) - 1,
+ (rose_neigh->dce_mode) ? "DCE" : "DTE",
+ (rose_neigh->restarted) ? "yes" : "no",
+ ax25_display_timer(&rose_neigh->t0timer) / HZ,
+diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
+index 1525773e94aa1..c52d7d20c5199 100644
+--- a/net/rose/rose_timer.c
++++ b/net/rose/rose_timer.c
+@@ -180,7 +180,7 @@ static void rose_timer_expiry(struct timer_list *t)
+ break;
+
+ case ROSE_STATE_2: /* T3 */
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose_disconnect(sk, ETIMEDOUT, -1, -1);
+ break;
+
+--
+2.50.1
+
--- /dev/null
+From 93c95d20d183797f279f77a77bcda21d14739ed3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:57 +0900
+Subject: net: rose: include node references in rose_neigh refcount
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit da9c9c877597170b929a6121a68dcd3dd9a80f45 ]
+
+Current implementation maintains two separate reference counting
+mechanisms: the 'count' field in struct rose_neigh tracks references from
+rose_node structures, while the 'use' field (now refcount_t) tracks
+references from rose_sock.
+
+This patch merges these two reference counting systems using 'use' field
+for proper reference management. Specifically, this patch adds incrementing
+and decrementing of rose_neigh->use when rose_neigh->count is incremented
+or decremented.
+
+This patch also modifies rose_rt_free(), rose_rt_device_down() and
+rose_clear_route() to properly release references to rose_neigh objects
+before freeing a rose_node through rose_remove_node().
+
+These changes ensure rose_neigh structures are properly freed only when
+all references, including those from rose_node structures, are released.
+As a result, this resolves a slab-use-after-free issue reported by Syzbot.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+942297eecf7d2d61d1f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=942297eecf7d2d61d1f1
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-4-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rose/rose_route.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 42460da0854d5..6acbb795c506d 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -178,6 +178,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ }
+ }
+ rose_neigh->count++;
++ rose_neigh_hold(rose_neigh);
+
+ goto out;
+ }
+@@ -187,6 +188,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ rose_node->neighbour[rose_node->count] = rose_neigh;
+ rose_node->count++;
+ rose_neigh->count++;
++ rose_neigh_hold(rose_neigh);
+ }
+
+ out:
+@@ -322,6 +324,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ for (i = 0; i < rose_node->count; i++) {
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
++ rose_neigh_put(rose_neigh);
+
+ if (rose_neigh->count == 0) {
+ rose_remove_neigh(rose_neigh);
+@@ -430,6 +433,7 @@ int rose_add_loopback_node(const rose_address *address)
+ rose_node_list = rose_node;
+
+ rose_loopback_neigh->count++;
++ rose_neigh_hold(rose_loopback_neigh);
+
+ out:
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -461,6 +465,7 @@ void rose_del_loopback_node(const rose_address *address)
+ rose_remove_node(rose_node);
+
+ rose_loopback_neigh->count--;
++ rose_neigh_put(rose_loopback_neigh);
+
+ out:
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -500,6 +505,7 @@ void rose_rt_device_down(struct net_device *dev)
+ memmove(&t->neighbour[i], &t->neighbour[i + 1],
+ sizeof(t->neighbour[0]) *
+ (t->count - i));
++ rose_neigh_put(s);
+ }
+
+ if (t->count <= 0)
+@@ -543,6 +549,7 @@ static int rose_clear_routes(void)
+ {
+ struct rose_neigh *s, *rose_neigh;
+ struct rose_node *t, *rose_node;
++ int i;
+
+ spin_lock_bh(&rose_node_list_lock);
+ spin_lock_bh(&rose_neigh_list_lock);
+@@ -553,8 +560,12 @@ static int rose_clear_routes(void)
+ while (rose_node != NULL) {
+ t = rose_node;
+ rose_node = rose_node->next;
+- if (!t->loopback)
++
++ if (!t->loopback) {
++ for (i = 0; i < rose_node->count; i++)
++ rose_neigh_put(t->neighbour[i]);
+ rose_remove_node(t);
++ }
+ }
+
+ while (rose_neigh != NULL) {
+@@ -1189,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+ (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+ rose_neigh->dev ? rose_neigh->dev->name : "???",
+ rose_neigh->count,
+- refcount_read(&rose_neigh->use) - 1,
++ refcount_read(&rose_neigh->use) - rose_neigh->count - 1,
+ (rose_neigh->dce_mode) ? "DCE" : "DTE",
+ (rose_neigh->restarted) ? "yes" : "no",
+ ax25_display_timer(&rose_neigh->t0timer) / HZ,
+@@ -1294,6 +1305,7 @@ void __exit rose_rt_free(void)
+ struct rose_neigh *s, *rose_neigh = rose_neigh_list;
+ struct rose_node *t, *rose_node = rose_node_list;
+ struct rose_route *u, *rose_route = rose_route_list;
++ int i;
+
+ while (rose_neigh != NULL) {
+ s = rose_neigh;
+@@ -1307,6 +1319,8 @@ void __exit rose_rt_free(void)
+ t = rose_node;
+ rose_node = rose_node->next;
+
++ for (i = 0; i < t->count; i++)
++ rose_neigh_put(t->neighbour[i]);
+ rose_remove_node(t);
+ }
+
+--
+2.50.1
+
--- /dev/null
+From a2748e21b13e2c0c770b77e13d842cb1edc831e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:55 +0900
+Subject: net: rose: split remove and free operations in rose_remove_neigh()
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit dcb34659028f856c423a29ef9b4e2571d203444d ]
+
+The current rose_remove_neigh() performs two distinct operations:
+1. Removes rose_neigh from rose_neigh_list
+2. Frees the rose_neigh structure
+
+Split these operations into separate functions to improve maintainability
+and prepare for upcoming refcount_t conversion. The timer cleanup remains
+in rose_remove_neigh() because free operations can be called from timer
+itself.
+
+This patch introduce rose_neigh_put() to handle the freeing of rose_neigh
+structures and modify rose_remove_neigh() to handle removal only.
+
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-2-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h | 8 ++++++++
+ net/rose/rose_route.c | 15 ++++++---------
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 23267b4efcfa3..174b4f605d849 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -151,6 +151,14 @@ struct rose_sock {
+
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
+
++static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
++{
++ if (rose_neigh->ax25)
++ ax25_cb_put(rose_neigh->ax25);
++ kfree(rose_neigh->digipeat);
++ kfree(rose_neigh);
++}
++
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int sysctl_rose_restart_request_timeout;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index a7054546f52df..b406b1e0fb1e7 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -234,20 +234,12 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+
+ if ((s = rose_neigh_list) == rose_neigh) {
+ rose_neigh_list = rose_neigh->next;
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
+ return;
+ }
+
+ while (s != NULL && s->next != NULL) {
+ if (s->next == rose_neigh) {
+ s->next = rose_neigh->next;
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
+ return;
+ }
+
+@@ -331,8 +323,10 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
+
+- if (rose_neigh->count == 0 && rose_neigh->use == 0)
++ if (rose_neigh->count == 0 && rose_neigh->use == 0) {
+ rose_remove_neigh(rose_neigh);
++ rose_neigh_put(rose_neigh);
++ }
+
+ rose_node->count--;
+
+@@ -513,6 +507,7 @@ void rose_rt_device_down(struct net_device *dev)
+ }
+
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+ spin_unlock_bh(&rose_neigh_list_lock);
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -569,6 +564,7 @@ static int rose_clear_routes(void)
+ if (s->use == 0 && !s->loopback) {
+ s->count = 0;
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+ }
+
+@@ -1301,6 +1297,7 @@ void __exit rose_rt_free(void)
+ rose_neigh = rose_neigh->next;
+
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+
+ while (rose_node != NULL) {
+--
+2.50.1
+
--- /dev/null
+From ae8d420d7e128b9a02396d38cd542c9b890c81dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:54 +0800
+Subject: net: stmmac: Set CIC bit only for TX queues with COE
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit b1eded580ab28119de0b0f21efe37ee2b4419144 ]
+
+Currently, in the AF_XDP transmit paths, the CIC bit of
+TX Desc3 is set for all packets. Setting this bit for
+packets transmitting through queues that don't support
+checksum offloading causes the TX DMA to get stuck after
+transmitting some packets. This patch ensures the CIC bit
+of TX Desc3 is set only if the TX queue supports checksum
+offloading.
+
+Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-3-c225fe4444c0@altera.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 | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 058cd9e9fd71d..40d56ff66b6a8 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2488,6 +2488,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+ struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
+ struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
++ bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+ struct xsk_buff_pool *pool = tx_q->xsk_pool;
+ unsigned int entry = tx_q->cur_tx;
+ struct dma_desc *tx_desc = NULL;
+@@ -2573,7 +2574,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+ }
+
+ stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len,
+- true, priv->mode, true, true,
++ csum, priv->mode, true, true,
+ xdp_desc.len);
+
+ stmmac_enable_dma_transmission(priv, priv->ioaddr, queue);
+@@ -4902,6 +4903,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+ {
+ struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
++ bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+ unsigned int entry = tx_q->cur_tx;
+ struct dma_desc *tx_desc;
+ dma_addr_t dma_addr;
+@@ -4953,7 +4955,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+ stmmac_set_desc_addr(priv, tx_desc, dma_addr);
+
+ stmmac_prepare_tx_desc(priv, tx_desc, 1, xdpf->len,
+- true, priv->mode, true, true,
++ csum, priv->mode, true, true,
+ xdpf->len);
+
+ tx_q->tx_count_frames++;
+--
+2.50.1
+
--- /dev/null
+From 1a4d2517f1d21daef0a273d2adbfac5da7ae5030 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:53 +0800
+Subject: net: stmmac: xgmac: Correct supported speed modes
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 42ef11b2bff5b6a2910c28d2ea47cc00e0fbcaec ]
+
+Correct supported speed modes as per the XGMAC databook.
+Commit 9cb54af214a7 ("net: stmmac: Fix IP-cores specific
+MAC capabilities") removes support for 10M, 100M and
+1000HD. 1000HD is not supported by XGMAC IP, but it does
+support 10M and 100M FD mode for XGMAC version >= 2_20,
+and it also supports 10M and 100M HD mode if the HDSEL bit
+is set in the MAC_HW_FEATURE0 reg. This commit enables support
+for 10M and 100M speed modes for XGMAC IP based on XGMAC
+version and MAC capabilities.
+
+Fixes: 9cb54af214a7 ("net: stmmac: Fix IP-cores specific MAC capabilities")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-2-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 13 +++++++++++--
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 5 +++++
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+index f519d43738b08..445259f2ee935 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+@@ -47,6 +47,14 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,
+ writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
+ }
+
++static void dwxgmac2_update_caps(struct stmmac_priv *priv)
++{
++ if (!priv->dma_cap.mbps_10_100)
++ priv->hw->link.caps &= ~(MAC_10 | MAC_100);
++ else if (!priv->dma_cap.half_duplex)
++ priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD);
++}
++
+ static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
+ {
+ u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
+@@ -1532,6 +1540,7 @@ static void dwxgmac3_fpe_configure(void __iomem *ioaddr,
+
+ const struct stmmac_ops dwxgmac210_ops = {
+ .core_init = dwxgmac2_core_init,
++ .update_caps = dwxgmac2_update_caps,
+ .set_mac = dwxgmac2_set_mac,
+ .rx_ipc = dwxgmac2_rx_ipc,
+ .rx_queue_enable = dwxgmac2_rx_queue_enable,
+@@ -1646,8 +1655,8 @@ int dwxgmac2_setup(struct stmmac_priv *priv)
+ mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+
+ mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+- MAC_1000FD | MAC_2500FD | MAC_5000FD |
+- MAC_10000FD;
++ MAC_10 | MAC_100 | MAC_1000FD |
++ MAC_2500FD | MAC_5000FD | MAC_10000FD;
+ mac->link.duplex = 0;
+ mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
+ mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 7201a38842651..4d6bb995d8d84 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -382,8 +382,11 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
+ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+ struct dma_features *dma_cap)
+ {
++ struct stmmac_priv *priv;
+ u32 hw_cap;
+
++ priv = container_of(dma_cap, struct stmmac_priv, dma_cap);
++
+ /* MAC HW feature 0 */
+ hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
+ dma_cap->edma = (hw_cap & XGMAC_HWFEAT_EDMA) >> 31;
+@@ -406,6 +409,8 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+ dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4;
+ dma_cap->half_duplex = (hw_cap & XGMAC_HWFEAT_HDSEL) >> 3;
+ dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;
++ if (dma_cap->mbps_1000 && priv->synopsys_id >= DWXGMAC_CORE_2_20)
++ dma_cap->mbps_10_100 = 1;
+
+ /* MAC HW feature 1 */
+ hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
+--
+2.50.1
+
--- /dev/null
+From 21d8fd933800cb4019e17798b522eca54b67be1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 5dcc95bc0ad28..7201a38842651 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -203,10 +203,6 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+ }
+
+ writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+- /* Enable MTL RX overflow */
+- value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+- writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+
+ static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+--
+2.50.1
+
--- /dev/null
+From 2c88ee76ee491dd224dfb5c628dfd172dd4ea8a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Aug 2025 10:24:21 -0700
+Subject: of: reserved_mem: Restructure call site for
+ dma_contiguous_early_fixup()
+
+From: Oreoluwa Babatunde <oreoluwa.babatunde@oss.qualcomm.com>
+
+[ Upstream commit 2c223f7239f376a90d71903ec474ba887cf21d94 ]
+
+Restructure the call site for dma_contiguous_early_fixup() to
+where the reserved_mem nodes are being parsed from the DT so that
+dma_mmu_remap[] is populated before dma_contiguous_remap() is called.
+
+Fixes: 8a6e02d0c00e ("of: reserved_mem: Restructure how the reserved memory regions are processed")
+Signed-off-by: Oreoluwa Babatunde <oreoluwa.babatunde@oss.qualcomm.com>
+Tested-by: William Zhang <william.zhang@broadcom.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20250806172421.2748302-1-oreoluwa.babatunde@oss.qualcomm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/of_reserved_mem.c | 16 ++++++++++++----
+ include/linux/dma-map-ops.h | 3 +++
+ kernel/dma/contiguous.c | 2 --
+ 3 files changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
+index 45445a1600a96..7b5d6562fe4a0 100644
+--- a/drivers/of/of_reserved_mem.c
++++ b/drivers/of/of_reserved_mem.c
+@@ -24,6 +24,7 @@
+ #include <linux/memblock.h>
+ #include <linux/kmemleak.h>
+ #include <linux/cma.h>
++#include <linux/dma-map-ops.h>
+
+ #include "of_private.h"
+
+@@ -128,13 +129,17 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
+ base = dt_mem_next_cell(dt_root_addr_cells, &prop);
+ size = dt_mem_next_cell(dt_root_size_cells, &prop);
+
+- if (size &&
+- early_init_dt_reserve_memory(base, size, nomap) == 0)
++ if (size && early_init_dt_reserve_memory(base, size, nomap) == 0) {
++ /* Architecture specific contiguous memory fixup. */
++ if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
++ of_get_flat_dt_prop(node, "reusable", NULL))
++ dma_contiguous_early_fixup(base, size);
+ pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
+ uname, &base, (unsigned long)(size / SZ_1M));
+- else
++ } else {
+ pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
+ uname, &base, (unsigned long)(size / SZ_1M));
++ }
+
+ len -= t_len;
+ }
+@@ -417,7 +422,10 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
+ uname, (unsigned long)(size / SZ_1M));
+ return -ENOMEM;
+ }
+-
++ /* Architecture specific contiguous memory fixup. */
++ if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
++ of_get_flat_dt_prop(node, "reusable", NULL))
++ dma_contiguous_early_fixup(base, size);
+ /* Save region in the reserved_mem array */
+ fdt_reserved_mem_save_node(node, uname, base, size);
+ return 0;
+diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
+index b7773201414c2..b42408a24ad13 100644
+--- a/include/linux/dma-map-ops.h
++++ b/include/linux/dma-map-ops.h
+@@ -153,6 +153,9 @@ static inline void dma_free_contiguous(struct device *dev, struct page *page,
+ {
+ __free_pages(page, get_order(size));
+ }
++static inline void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
++{
++}
+ #endif /* CONFIG_DMA_CMA*/
+
+ #ifdef CONFIG_DMA_DECLARE_COHERENT
+diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
+index 8df0dfaaca18e..9e5d63efe7c57 100644
+--- a/kernel/dma/contiguous.c
++++ b/kernel/dma/contiguous.c
+@@ -480,8 +480,6 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
+ pr_err("Reserved memory: unable to setup CMA region\n");
+ return err;
+ }
+- /* Architecture specific contiguous memory fixup. */
+- dma_contiguous_early_fixup(rmem->base, rmem->size);
+
+ if (default_cma)
+ dma_contiguous_default_area = cma;
+--
+2.50.1
+
--- /dev/null
+From 136619f1311981f6639f4ce9ef7d3c5800678d66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:55:43 +0200
+Subject: phy: mscc: Fix when PTP clock is register and unregister
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]
+
+It looks like that every time when the interface was set down and up the
+driver was creating a new ptp clock. On top of this the function
+ptp_clock_unregister was never called.
+Therefore fix this by calling ptp_clock_register and initialize the
+mii_ts struct inside the probe function and call ptp_clock_unregister when
+driver is removed.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h | 4 ++++
+ drivers/net/phy/mscc/mscc_main.c | 4 +---
+ drivers/net/phy/mscc/mscc_ptp.c | 34 ++++++++++++++++++++------------
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index 58c6d47fbe046..2bfe314ef881c 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -481,6 +481,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -495,6 +496,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
+ {
+ return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+ return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index 42cafa68c4009..19983b206405c 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2337,9 +2337,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+- struct vsc8531_private *priv = phydev->priv;
+-
+- skb_queue_purge(&priv->rx_skbs_list);
++ vsc8584_ptp_deinit(phydev);
+ }
+
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index 80992827a3bdd..920f35f8f84e7 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1295,7 +1295,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+- struct vsc8531_private *vsc8531 = phydev->priv;
+ static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+ static const u8 ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+ u32 val;
+@@ -1512,17 +1511,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+
+ vsc85xx_ts_eth_cmp1_sig(phydev);
+
+- vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+- vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+- vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+- vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
+- phydev->mii_ts = &vsc8531->mii_ts;
+-
+- memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+-
+- vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+- &phydev->mdio.dev);
+- return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++ return 0;
+ }
+
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1549,6 +1538,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+ return 0;
+ }
+
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++ struct vsc8531_private *vsc8531 = phydev->priv;
++
++ if (vsc8531->ptp->ptp_clock) {
++ ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++ skb_queue_purge(&vsc8531->rx_skbs_list);
++ }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+ struct vsc8531_private *priv = phydev->priv;
+@@ -1609,7 +1608,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+
+ vsc8531->ptp->phydev = phydev;
+
+- return 0;
++ vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++ vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++ vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++ vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
++ phydev->mii_ts = &vsc8531->mii_ts;
++
++ memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
++ vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++ &phydev->mdio.dev);
++ return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+--
+2.50.1
+
--- /dev/null
+From b55c17db53adb9617ed394336f77e7e15147127c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 5b3c093611baf..7209d00a9c257 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+ }
+
+- switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++ switch (inst_no_rt & ~KVM_MASK_RB) {
+ case KVM_INST_MTSRIN:
+ if (features & KVM_MAGIC_FEAT_SR) {
+ u32 inst_rb = _inst & KVM_MASK_RB;
+ kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+ }
+ break;
+-#endif
+ }
++#endif
+
+- switch (_inst) {
+ #ifdef CONFIG_BOOKE
++ switch (_inst) {
+ case KVM_INST_WRTEEI_0:
+ kvm_patch_ins_wrteei_0(inst);
+ break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ case KVM_INST_WRTEEI_1:
+ kvm_patch_ins_wrtee(inst, 0, 1);
+ break;
+-#endif
+ }
++#endif
+ }
+
+ extern u32 kvm_template_start[];
+--
+2.50.1
+
--- /dev/null
+From a8034c1d5c73cced6548531d13f4c797523ded0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+ sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+ sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+ sctp_get_port net/sctp/socket.c:8523 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+ x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+ sctp_get_port net/sctp/socket.c:8515 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 38e2fbdcbeac4..9f835e674c599 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -546,7 +546,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+ addr->v6.sin6_family = AF_INET6;
+ addr->v6.sin6_port = 0;
++ addr->v6.sin6_flowinfo = 0;
+ addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++ addr->v6.sin6_scope_id = 0;
+ }
+
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+--
+2.50.1
+
erofs-fix-atomic-context-detection-when-config_debug.patch
acpi-ec-add-device-to-acpi_ec_no_wakeup-qurik-list.patch
vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+drm-msm-defer-fd_install-in-submit-ioctl.patch
+of-reserved_mem-restructure-call-site-for-dma_contig.patch
+drm-msm-kms-move-snapshot-init-earlier-in-kms-init.patch
+drm-msm-update-the-high-bitfield-of-certain-dsi-regi.patch
+drm-mediatek-add-error-handling-for-old-state-crtc-i.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+hid-input-rename-hidinput_set_battery_charge_status.patch
+hid-input-report-battery-status-changes-immediately.patch
+net-macb-fix-unregister_netdev-call-order-in-macb_re.patch
+bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
+bluetooth-hci_event-mark-connection-as-closed-during.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+bluetooth-hci_sync-fix-set_local_name-race-condition.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch
+drm-nouveau-remove-unused-memory-target-test.patch
+ice-don-t-leave-device-non-functional-if-tx-schedule.patch
+ice-use-fixed-adapter-index-for-e825c-embedded-devic.patch
+ice-fix-incorrect-counter-for-buffer-allocation-fail.patch
+dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+efi-stmm-fix-incorrect-buffer-allocation-method.patch
+drm-xe-xe_sync-avoid-race-during-ufence-signaling.patch
+drm-xe-don-t-trigger-rebind-on-initial-dma-buf-valid.patch
+phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
+bnxt_en-fix-memory-corruption-when-fw-resources-chan.patch
+bnxt_en-adjust-tx-rings-if-reservation-is-less-than-.patch
+bnxt_en-fix-stats-context-reservation-logic.patch
+net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
+net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch
+net-mlx5-nack-sync-reset-when-sfs-are-present.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+net-stmmac-xgmac-correct-supported-speed-modes.patch
+net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch
+hv_netvsc-link-queues-to-napis.patch
+net-hv_netvsc-fix-loss-of-early-receive-events-from-.patch
+net-rose-split-remove-and-free-operations-in-rose_re.patch
+net-rose-convert-use-field-to-refcount_t.patch
+net-rose-include-node-references-in-rose_neigh-refco.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_so.patch
+fbnic-move-phylink-resume-out-of-service_task-and-in.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
+net-macb-disable-clocks-once.patch
--- /dev/null
+From f9253d2466a57b581daa54dbfd40320a109d165f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+ struct atmtcp_control {
+ struct atmtcp_hdr hdr; /* must be first */
+ ...
+ atm_kptr_t vcc; /* both directions */
+ ...
+ } __ATM_API_ALIGN;
+
+ typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+ 1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+ 2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS: 00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x19b/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c | 17 ++++++++++++++---
+ include/linux/atmdev.h | 1 +
+ net/atm/common.c | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index eeae160c898d3..fa3c76a2b49d1 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+ return NULL;
+ }
+
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++ struct atmtcp_hdr *hdr;
++
++ if (skb->len < sizeof(struct atmtcp_hdr))
++ return -EINVAL;
++
++ hdr = (struct atmtcp_hdr *)skb->data;
++ if (hdr->length == ATMTCP_HDR_MAGIC)
++ return -EINVAL;
++
++ return 0;
++}
+
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ struct sk_buff *new_skb;
+ int result = 0;
+
+- if (skb->len < sizeof(struct atmtcp_hdr))
+- goto done;
+-
+ dev = vcc->dev_data;
+ hdr = (struct atmtcp_hdr *) skb->data;
+ if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+ .close = atmtcp_c_close,
++ .pre_send = atmtcp_c_pre_send,
+ .send = atmtcp_c_send
+ };
+
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8..70807c679f1ab 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+ int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+ void __user *arg);
+ #endif
++ int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+ int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/net/atm/common.c b/net/atm/common.c
+index d7f7976ea13ac..881c7f259dbd4 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+
+ skb->dev = NULL; /* for paths shared with net_device interfaces */
+ if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+- atm_return_tx(vcc, skb);
+- kfree_skb(skb);
+ error = -EFAULT;
+- goto out;
++ goto free_skb;
+ }
+ if (eff != size)
+ memset(skb->data + size, 0, eff-size);
++
++ if (vcc->dev->ops->pre_send) {
++ error = vcc->dev->ops->pre_send(vcc, skb);
++ if (error)
++ goto free_skb;
++ }
++
+ error = vcc->dev->ops->send(vcc, skb);
+ error = error ? error : size;
+ out:
+ release_sock(sk);
+ return error;
++free_skb:
++ atm_return_tx(vcc, skb);
++ kfree_skb(skb);
++ goto out;
+ }
+
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+--
+2.50.1
+
--- /dev/null
+From 71ee7d6d8a5e362507936a311f858e1885a745db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 22:00:32 +0530
+Subject: block: validate QoS before calling __rq_qos_done_bio()
+
+From: Nilay Shroff <nilay@linux.ibm.com>
+
+[ Upstream commit e3ef9445cd9d90e43de0bd3cd55d437773dfd139 ]
+
+If a bio has BIO_QOS_xxx set, it doesn't guarantee that q->rq_qos is
+also present at-least for stacked block devices. For instance, in case
+of NVMe when multipath is enabled, the bottom device may have QoS
+enabled but top device doesn't. So always validate QoS is enabled and
+q->rq_qos is present before calling __rq_qos_done_bio().
+
+Fixes: 370ac285f23a ("block: avoid cpu_hotplug_lock depedency on freeze_lock")
+Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Closes: https://lore.kernel.org/all/3a07b752-06a4-4eee-b302-f4669feb859d@linux.ibm.com/
+Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
+Link: https://lore.kernel.org/r/20250826163128.1952394-1-nilay@linux.ibm.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-rq-qos.h | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h
+index 1fe22000a3790..b538f2c0febc2 100644
+--- a/block/blk-rq-qos.h
++++ b/block/blk-rq-qos.h
+@@ -149,12 +149,15 @@ static inline void rq_qos_done_bio(struct bio *bio)
+ q = bdev_get_queue(bio->bi_bdev);
+
+ /*
+- * If a bio has BIO_QOS_xxx set, it implicitly implies that
+- * q->rq_qos is present. So, we skip re-checking q->rq_qos
+- * here as an extra optimization and directly call
+- * __rq_qos_done_bio().
++ * A BIO may carry BIO_QOS_* flags even if the associated request_queue
++ * does not have rq_qos enabled. This can happen with stacked block
++ * devices — for example, NVMe multipath, where it's possible that the
++ * bottom device has QoS enabled but the top device does not. Therefore,
++ * always verify that q->rq_qos is present and QoS is enabled before
++ * calling __rq_qos_done_bio().
+ */
+- __rq_qos_done_bio(q->rq_qos, bio);
++ if (test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags) && q->rq_qos)
++ __rq_qos_done_bio(q->rq_qos, bio);
+ }
+
+ static inline void rq_qos_throttle(struct request_queue *q, struct bio *bio)
+--
+2.50.1
+
--- /dev/null
+From dd7c40fab01a5e41e822b0b35d0d9fcb075a7e10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 13:40:18 -0400
+Subject: Bluetooth: hci_conn: Make unacked packet handling more robust
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 5d7eba62e5eb68347de59b31b347b24f304cf21c ]
+
+This attempts to make unacked packet handling more robust by detecting
+if there are no connections left then restore all buffers of the
+respective pool.
+
+Fixes: 5638d9ea9c01 ("Bluetooth: hci_conn: Fix not restoring ISO buffer count on disconnect")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_conn.c | 58 ++++++++++++++++++++++++++++------------
+ 1 file changed, 41 insertions(+), 17 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 6a064a6b0e431..ad5574e9a93ee 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -149,8 +149,6 @@ static void hci_conn_cleanup(struct hci_conn *conn)
+
+ hci_chan_list_flush(conn);
+
+- hci_conn_hash_del(hdev, conn);
+-
+ if (HCI_CONN_HANDLE_UNSET(conn->handle))
+ ida_free(&hdev->unset_handle_ida, conn->handle);
+
+@@ -1142,28 +1140,54 @@ void hci_conn_del(struct hci_conn *conn)
+ disable_delayed_work_sync(&conn->auto_accept_work);
+ disable_delayed_work_sync(&conn->idle_work);
+
+- if (conn->type == ACL_LINK) {
+- /* Unacked frames */
+- hdev->acl_cnt += conn->sent;
+- } else if (conn->type == LE_LINK) {
+- cancel_delayed_work(&conn->le_conn_timeout);
++ /* Remove the connection from the list so unacked logic can detect when
++ * a certain pool is not being utilized.
++ */
++ hci_conn_hash_del(hdev, conn);
+
+- if (hdev->le_pkts)
+- hdev->le_cnt += conn->sent;
++ /* Handle unacked frames:
++ *
++ * - In case there are no connection, or if restoring the buffers
++ * considered in transist would overflow, restore all buffers to the
++ * pool.
++ * - Otherwise restore just the buffers considered in transit for the
++ * hci_conn
++ */
++ switch (conn->type) {
++ case ACL_LINK:
++ if (!hci_conn_num(hdev, ACL_LINK) ||
++ hdev->acl_cnt + conn->sent > hdev->acl_pkts)
++ hdev->acl_cnt = hdev->acl_pkts;
+ else
+ hdev->acl_cnt += conn->sent;
+- } else {
+- /* Unacked ISO frames */
+- if (conn->type == CIS_LINK ||
+- conn->type == BIS_LINK ||
+- conn->type == PA_LINK) {
+- if (hdev->iso_pkts)
+- hdev->iso_cnt += conn->sent;
+- else if (hdev->le_pkts)
++ break;
++ case LE_LINK:
++ cancel_delayed_work(&conn->le_conn_timeout);
++
++ if (hdev->le_pkts) {
++ if (!hci_conn_num(hdev, LE_LINK) ||
++ hdev->le_cnt + conn->sent > hdev->le_pkts)
++ hdev->le_cnt = hdev->le_pkts;
++ else
+ hdev->le_cnt += conn->sent;
++ } else {
++ if ((!hci_conn_num(hdev, LE_LINK) &&
++ !hci_conn_num(hdev, ACL_LINK)) ||
++ hdev->acl_cnt + conn->sent > hdev->acl_pkts)
++ hdev->acl_cnt = hdev->acl_pkts;
+ else
+ hdev->acl_cnt += conn->sent;
+ }
++ break;
++ case CIS_LINK:
++ case BIS_LINK:
++ case PA_LINK:
++ if (!hci_iso_count(hdev) ||
++ hdev->iso_cnt + conn->sent > hdev->iso_pkts)
++ hdev->iso_cnt = hdev->iso_pkts;
++ else
++ hdev->iso_cnt += conn->sent;
++ break;
+ }
+
+ skb_queue_purge(&conn->data_q);
+--
+2.50.1
+
--- /dev/null
+From d392fd1d430b4afc49bb5cca6b24d1c56ea4f18e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index cadb53e21c0ef..02b2ef9a75746 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4404,7 +4404,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+ if (!conn)
+ continue;
+
+- conn->sent -= count;
++ /* Check if there is really enough packets outstanding before
++ * attempting to decrease the sent counter otherwise it could
++ * underflow..
++ */
++ if (conn->sent >= count) {
++ conn->sent -= count;
++ } else {
++ bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++ conn, conn->sent, count);
++ conn->sent = 0;
++ }
+
+ for (i = 0; i < count; ++i)
+ hci_conn_tx_dequeue(conn);
+--
+2.50.1
+
--- /dev/null
+From 4c447d1ff9b38451ca7fb1ec5f1f08e3364c0bb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 10:16:17 +0800
+Subject: Bluetooth: hci_event: Disconnect device when BIG sync is lost
+
+From: Yang Li <yang.li@amlogic.com>
+
+[ Upstream commit 55b9551fcdf6a2fe7f3422918d5697b56794da72 ]
+
+When a BIG sync is lost, the device should be set to "disconnected".
+This ensures symmetry with the ISO path setup, where the device is
+marked as "connected" once the path is established. Without this
+change, the device state remains inconsistent and may lead to a
+memory leak.
+
+Fixes: b2a5f2e1c127 ("Bluetooth: hci_event: Add support for handling LE BIG Sync Lost event")
+Signed-off-by: Yang Li <yang.li@amlogic.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 5 +++++
+ net/bluetooth/mgmt.c | 4 +++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 02b2ef9a75746..0ffdbe249f5d3 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -7019,6 +7019,7 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data,
+ {
+ struct hci_evt_le_big_sync_lost *ev = data;
+ struct hci_conn *bis, *conn;
++ bool mgmt_conn;
+
+ bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle);
+
+@@ -7037,6 +7038,10 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data,
+ while ((bis = hci_conn_hash_lookup_big_state(hdev, ev->handle,
+ BT_CONNECTED,
+ HCI_ROLE_SLAVE))) {
++ mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &bis->flags);
++ mgmt_device_disconnected(hdev, &bis->dst, bis->type, bis->dst_type,
++ ev->reason, mgmt_conn);
++
+ clear_bit(HCI_CONN_BIG_SYNC, &bis->flags);
+ hci_disconn_cfm(bis, ev->reason);
+ hci_conn_del(bis);
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 3166f5fb876b1..90e37ff2c85db 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -9705,7 +9705,9 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ if (!mgmt_connected)
+ return;
+
+- if (link_type != ACL_LINK && link_type != LE_LINK)
++ if (link_type != ACL_LINK &&
++ link_type != LE_LINK &&
++ link_type != BIS_LINK)
+ return;
+
+ bacpy(&ev.addr.bdaddr, bdaddr);
+--
+2.50.1
+
--- /dev/null
+From 674fe564ad11835bd72555e6e077103673811942 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:27 +0200
+Subject: Bluetooth: hci_event: Mark connection as closed during suspend
+ disconnect
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit b7fafbc499b5ee164018eb0eefe9027f5a6aaad2 ]
+
+When suspending, the disconnect command for an active Bluetooth
+connection could be issued, but the corresponding
+`HCI_EV_DISCONN_COMPLETE` event might not be received before the system
+completes the suspend process. This can lead to an inconsistent state.
+
+On resume, the controller may auto-accept reconnections from the same
+device (due to suspend event filters), but these new connections are
+rejected by the kernel which still has connection objects from before
+suspend. Resulting in errors like:
+```
+kernel: Bluetooth: hci0: ACL packet for unknown connection handle 1
+kernel: Bluetooth: hci0: Ignoring HCI_Connection_Complete for existing
+connection
+```
+
+This is a btmon snippet that shows the issue:
+```
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+ Handle: 1 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+ Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+ Disconnect (0x01|0x0006) ncmd 2
+ Status: Success (0x00)
+[...]
+// Host suspends with the event filter set for the device
+// On resume, the device tries to reconnect with a new handle
+
+> HCI Event: Connect Complete (0x03) plen 11
+ Status: Success (0x00)
+ Handle: 2
+ Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+
+// Kernel ignores this event because there is an existing connection
+with
+// handle 1
+```
+
+By explicitly setting the connection state to BT_CLOSED we can ensure a
+consistent state, even if we don't receive the disconnect complete event
+in time.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 1902982538da7..cadb53e21c0ef 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2718,6 +2718,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+ goto done;
+ }
+
++ /* During suspend, mark connection as closed immediately
++ * since we might not receive HCI_EV_DISCONN_COMPLETE
++ */
++ if (hdev->suspended)
++ conn->state = BT_CLOSED;
++
+ mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
+
+ if (conn->type == ACL_LINK) {
+--
+2.50.1
+
--- /dev/null
+From 57880a80e476d8e932ceadfa7d8a452562019ee0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:26 +0200
+Subject: Bluetooth: hci_event: Treat UNKNOWN_CONN_ID on disconnect as success
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit 2f050a5392b7a0928bf836d9891df4851463512c ]
+
+When the host sends an HCI_OP_DISCONNECT command, the controller may
+respond with the status HCI_ERROR_UNKNOWN_CONN_ID (0x02). E.g. this can
+happen on resume from suspend, if the link was terminated by the remote
+device before the event mask was correctly set.
+
+This is a btmon snippet that shows the issue:
+```
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+ L2CAP: Disconnection Request (0x06) ident 5 len 4
+ Destination CID: 65
+ Source CID: 72
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+ L2CAP: Disconnection Response (0x07) ident 5 len 4
+ Destination CID: 65
+ Source CID: 72
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+ L2CAP: Disconnection Request (0x06) ident 6 len 4
+ Destination CID: 64
+ Source CID: 71
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+ L2CAP: Disconnection Response (0x07) ident 6 len 4
+ Destination CID: 64
+ Source CID: 71
+< HCI Command: Set Event Mask (0x03|0x0001) plen 8
+ Mask: 0x3dbff807fffbffff
+ Inquiry Complete
+ Inquiry Result
+ Connection Complete
+ Connection Request
+ Disconnection Complete
+ Authentication Complete
+[...]
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+ Handle: 3 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+ Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+ Disconnect (0x01|0x0006) ncmd 1
+ Status: Unknown Connection Identifier (0x02)
+```
+
+Currently, the hci_cs_disconnect function treats any non-zero status
+as a command failure. This can be misleading because the connection is
+indeed being terminated and the controller is confirming that is has no
+knowledge of that connection handle. Meaning that the initial request of
+disconnecting a device should be treated as done.
+
+With this change we allow the function to proceed, following the success
+path, which correctly calls `mgmt_device_disconnected` and ensures a
+consistent state.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 5ef54853bc5eb..1902982538da7 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2703,7 +2703,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+ if (!conn)
+ goto unlock;
+
+- if (status) {
++ if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
+ mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+ conn->dst_type, status);
+
+--
+2.50.1
+
--- /dev/null
+From 7dbac4e2175ef7cdeab9b544e8fab30b66f50759 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 12:20:55 +0300
+Subject: Bluetooth: hci_sync: fix set_local_name race condition
+
+From: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+
+[ Upstream commit 6bbd0d3f0c23fc53c17409dd7476f38ae0ff0cd9 ]
+
+Function set_name_sync() uses hdev->dev_name field to send
+HCI_OP_WRITE_LOCAL_NAME command, but copying from data to hdev->dev_name
+is called after mgmt cmd was queued, so it is possible that function
+set_name_sync() will read old name value.
+
+This change adds name as a parameter for function hci_update_name_sync()
+to avoid race condition.
+
+Fixes: 6f6ff38a1e14 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LOCAL_NAME")
+Signed-off-by: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_sync.h | 2 +-
+ net/bluetooth/hci_sync.c | 6 +++---
+ net/bluetooth/mgmt.c | 5 ++++-
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 5224f57f6af2c..e352a4e0ef8d7 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -93,7 +93,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
+
+ int hci_update_eir_sync(struct hci_dev *hdev);
+ int hci_update_class_sync(struct hci_dev *hdev);
+-int hci_update_name_sync(struct hci_dev *hdev);
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
+ int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
+
+ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 115dc1cd99ce4..749bba1512eb1 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3481,13 +3481,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+ return hci_write_scan_enable_sync(hdev, scan);
+ }
+
+-int hci_update_name_sync(struct hci_dev *hdev)
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
+ {
+ struct hci_cp_write_local_name cp;
+
+ memset(&cp, 0, sizeof(cp));
+
+- memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
++ memcpy(cp.name, name, sizeof(cp.name));
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
+ sizeof(cp), &cp,
+@@ -3540,7 +3540,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
+ hci_write_fast_connectable_sync(hdev, false);
+ hci_update_scan_sync(hdev);
+ hci_update_class_sync(hdev);
+- hci_update_name_sync(hdev);
++ hci_update_name_sync(hdev, hdev->dev_name);
+ hci_update_eir_sync(hdev);
+ }
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 90e37ff2c85db..50634ef5c8b70 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3892,8 +3892,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
+
+ static int set_name_sync(struct hci_dev *hdev, void *data)
+ {
++ struct mgmt_pending_cmd *cmd = data;
++ struct mgmt_cp_set_local_name *cp = cmd->param;
++
+ if (lmp_bredr_capable(hdev)) {
+- hci_update_name_sync(hdev);
++ hci_update_name_sync(hdev, cp->name);
+ hci_update_eir_sync(hdev);
+ }
+
+--
+2.50.1
+
--- /dev/null
+From bd11dca44cf30511d4c2417c82320e9ef5ed8492 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:26 -0700
+Subject: bnxt_en: Adjust TX rings if reservation is less than requested
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit 1ee581c24dfdcbc6de25aac95a48c1f08e9a542c ]
+
+Before we accept an ethtool request to increase a resource (such as
+rings), we call the FW to check that the requested resource is likely
+available first before we commit. But it is still possible that
+the actual reservation or allocation can fail. The existing code
+is missing the logic to adjust the TX rings in case the reserved
+TX rings are less than requested. Add a warning message (a similar
+message for RX rings already exists) and add the logic to adjust
+the TX rings. Without this fix, the number of TX rings reported
+to the stack can exceed the actual TX rings and ethtool -l will
+report more than the actual TX rings.
+
+Fixes: 674f50a5b026 ("bnxt_en: Implement new method to reserve rings.")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-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 | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index a4f4d90caf5e9..5360c42ad409c 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -8017,6 +8017,11 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
+ hwr.rx = rx_rings << 1;
+ tx_cp = bnxt_num_tx_to_cp(bp, hwr.tx);
+ hwr.cp = sh ? max_t(int, tx_cp, rx_rings) : tx_cp + rx_rings;
++ if (hwr.tx != bp->tx_nr_rings) {
++ netdev_warn(bp->dev,
++ "Able to reserve only %d out of %d requested TX rings\n",
++ hwr.tx, bp->tx_nr_rings);
++ }
+ bp->tx_nr_rings = hwr.tx;
+
+ /* If we cannot reserve all the RX rings, reset the RSS map only
+@@ -12872,6 +12877,13 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
+ if (rc)
+ return rc;
+
++ /* Make adjustments if reserved TX rings are less than requested */
++ bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
++ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
++ if (bp->tx_nr_rings_xdp) {
++ bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
++ bp->tx_nr_rings += bp->tx_nr_rings_xdp;
++ }
+ rc = bnxt_alloc_mem(bp, irq_re_init);
+ if (rc) {
+ netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
+--
+2.50.1
+
--- /dev/null
+From 1028d4f3c65673898e39224f25372b8ca0f1eb55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:25 -0700
+Subject: bnxt_en: Fix memory corruption when FW resources change during ifdown
+
+From: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+
+[ Upstream commit 2747328ba2714f1a7454208dbbc1dc0631990b4a ]
+
+bnxt_set_dflt_rings() assumes that it is always called before any TC has
+been created. So it doesn't take bp->num_tc into account and assumes
+that it is always 0 or 1.
+
+In the FW resource or capability change scenario, the FW will return
+flags in bnxt_hwrm_if_change() that will cause the driver to
+reinitialize and call bnxt_cancel_reservations(). This will lead to
+bnxt_init_dflt_ring_mode() calling bnxt_set_dflt_rings() and bp->num_tc
+may be greater than 1. This will cause bp->tx_ring[] to be sized too
+small and cause memory corruption in bnxt_alloc_cp_rings().
+
+Fix it by properly scaling the TX rings by bp->num_tc in the code
+paths mentioned above. Add 2 helper functions to determine
+bp->tx_nr_rings and bp->tx_nr_rings_per_tc.
+
+Fixes: ec5d31e3c15d ("bnxt_en: Handle firmware reset status during IF_UP.")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
+Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-2-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 | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index ec8752c298e69..a4f4d90caf5e9 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -12844,6 +12844,17 @@ static int bnxt_set_xps_mapping(struct bnxt *bp)
+ return rc;
+ }
+
++static int bnxt_tx_nr_rings(struct bnxt *bp)
++{
++ return bp->num_tc ? bp->tx_nr_rings_per_tc * bp->num_tc :
++ bp->tx_nr_rings_per_tc;
++}
++
++static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
++{
++ return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings;
++}
++
+ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
+ {
+ int rc = 0;
+@@ -16338,7 +16349,7 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
+ bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings);
+ bp->rx_nr_rings = bp->cp_nr_rings;
+ bp->tx_nr_rings_per_tc = bp->cp_nr_rings;
+- bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
++ bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+ }
+
+ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+@@ -16370,7 +16381,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+ bnxt_trim_dflt_sh_rings(bp);
+ else
+ bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
+- bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
++ bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+
+ avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
+ if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
+@@ -16383,7 +16394,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+ rc = __bnxt_reserve_rings(bp);
+ if (rc && rc != -ENODEV)
+ netdev_warn(bp->dev, "Unable to reserve tx rings\n");
+- bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+ if (sh)
+ bnxt_trim_dflt_sh_rings(bp);
+
+@@ -16392,7 +16403,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
+ rc = __bnxt_reserve_rings(bp);
+ if (rc && rc != -ENODEV)
+ netdev_warn(bp->dev, "2nd rings reservation failed.\n");
+- bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+ }
+ if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
+ bp->rx_nr_rings++;
+@@ -16426,7 +16437,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
+ if (rc)
+ goto init_dflt_ring_err;
+
+- bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
++ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+
+ bnxt_set_dflt_rfs(bp);
+
+--
+2.50.1
+
--- /dev/null
+From daf38dbb8f1bfb0d57daa254b01b7f9912f79ac5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 10:59:27 -0700
+Subject: bnxt_en: Fix stats context reservation logic
+
+From: Michael Chan <michael.chan@broadcom.com>
+
+[ Upstream commit b4fc8faacfea2538184a1dbd616ae9447a361f3d ]
+
+The HW resource reservation logic allows the L2 driver to use the
+RoCE resources if the RoCE driver is not registered. When calculating
+the stats contexts available for L2, we should not blindly subtract
+the stats contexts reserved for RoCE unless the RoCE driver is
+registered. This bug may cause the L2 rings to be less than the
+number requested when we are close to running out of stats contexts.
+
+Fixes: 2e4592dc9bee ("bnxt_en: Change MSIX/NQs allocation policy")
+Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
+Signed-off-by: Michael Chan <michael.chan@broadcom.com>
+Link: https://patch.msgid.link/20250825175927.459987-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 | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 5360c42ad409c..cb76ab78904fc 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -8009,7 +8009,8 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
+ }
+ rx_rings = min_t(int, rx_rings, hwr.grp);
+ hwr.cp = min_t(int, hwr.cp, bp->cp_nr_rings);
+- if (hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
++ if (bnxt_ulp_registered(bp->edev) &&
++ hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
+ hwr.stat -= bnxt_get_ulp_stat_ctxs(bp);
+ hwr.cp = min_t(int, hwr.cp, hwr.stat);
+ rc = bnxt_trim_rings(bp, &rx_rings, &hwr.tx, hwr.cp, sh);
+--
+2.50.1
+
--- /dev/null
+From 643e0d64586d376b5871131c616949c76383bf5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Jul 2025 10:48:50 +0800
+Subject: drm/mediatek: Add error handling for old state CRTC in atomic_disable
+
+From: Jason-JH Lin <jason-jh.lin@mediatek.com>
+
+[ Upstream commit 0c6b24d70da21201ed009a2aca740d2dfddc7ab5 ]
+
+Introduce error handling to address an issue where, after a hotplug
+event, the cursor continues to update. This situation can lead to a
+kernel panic due to accessing the NULL `old_state->crtc`.
+
+E,g.
+Unable to handle kernel NULL pointer dereference at virtual address
+Call trace:
+ mtk_crtc_plane_disable+0x24/0x140
+ mtk_plane_atomic_update+0x8c/0xa8
+ drm_atomic_helper_commit_planes+0x114/0x2c8
+ drm_atomic_helper_commit_tail_rpm+0x4c/0x158
+ commit_tail+0xa0/0x168
+ drm_atomic_helper_commit+0x110/0x120
+ drm_atomic_commit+0x8c/0xe0
+ drm_atomic_helper_update_plane+0xd4/0x128
+ __setplane_atomic+0xcc/0x110
+ drm_mode_cursor_common+0x250/0x440
+ drm_mode_cursor_ioctl+0x44/0x70
+ drm_ioctl+0x264/0x5d8
+ __arm64_sys_ioctl+0xd8/0x510
+ invoke_syscall+0x6c/0xe0
+ do_el0_svc+0x68/0xe8
+ el0_svc+0x34/0x60
+ el0t_64_sync_handler+0x1c/0xf8
+ el0t_64_sync+0x180/0x188
+
+Adding NULL pointer checks to ensure stability by preventing operations
+on an invalid CRTC state.
+
+Fixes: d208261e9f7c ("drm/mediatek: Add wait_event_timeout when disabling plane")
+Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20250728025036.24953-1-jason-jh.lin@mediatek.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_plane.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c
+index cbc4f37da8ba8..02349bd440017 100644
+--- a/drivers/gpu/drm/mediatek/mtk_plane.c
++++ b/drivers/gpu/drm/mediatek/mtk_plane.c
+@@ -292,7 +292,8 @@ static void mtk_plane_atomic_disable(struct drm_plane *plane,
+ wmb(); /* Make sure the above parameter is set before update */
+ mtk_plane_state->pending.dirty = true;
+
+- mtk_crtc_plane_disable(old_state->crtc, plane);
++ if (old_state && old_state->crtc)
++ mtk_crtc_plane_disable(old_state->crtc, plane);
+ }
+
+ static void mtk_plane_atomic_update(struct drm_plane *plane,
+--
+2.50.1
+
--- /dev/null
+From 721777d3e398883c79ada0e27257f6787719fc62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Aug 2025 16:17:52 +0200
+Subject: drm/mediatek: mtk_hdmi: Fix inverted parameters in some
+ regmap_update_bits calls
+
+From: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+
+[ Upstream commit c34414883f773412964404d77cd2fea04c6f7d60 ]
+
+In mtk_hdmi driver, a recent change replaced custom register access
+function calls by regmap ones, but two replacements by regmap_update_bits
+were done incorrectly, because original offset and mask parameters were
+inverted, so fix them.
+
+Fixes: d6e25b3590a0 ("drm/mediatek: hdmi: Use regmap instead of iomem for main registers")
+Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+Reviewed-by: CK Hu <ck.hu@mediatek.com>
+Link: https://patchwork.kernel.org/project/dri-devel/patch/20250818-mt8173-fix-hdmi-issue-v1-1-55aff9b0295d@collabora.com/
+Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/mediatek/mtk_hdmi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+index 8803cd4a8bc9b..4404e1b527b52 100644
+--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+@@ -182,8 +182,8 @@ static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
+
+ static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black)
+ {
+- regmap_update_bits(hdmi->regs, VIDEO_SOURCE_SEL,
+- VIDEO_CFG_4, black ? GEN_RGB : NORMAL_PATH);
++ regmap_update_bits(hdmi->regs, VIDEO_CFG_4,
++ VIDEO_SOURCE_SEL, black ? GEN_RGB : NORMAL_PATH);
+ }
+
+ static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable)
+@@ -310,8 +310,8 @@ static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer,
+
+ static void mtk_hdmi_hw_send_aud_packet(struct mtk_hdmi *hdmi, bool enable)
+ {
+- regmap_update_bits(hdmi->regs, AUDIO_PACKET_OFF,
+- GRL_SHIFT_R2, enable ? 0 : AUDIO_PACKET_OFF);
++ regmap_update_bits(hdmi->regs, GRL_SHIFT_R2,
++ AUDIO_PACKET_OFF, enable ? 0 : AUDIO_PACKET_OFF);
+ }
+
+ static void mtk_hdmi_hw_config_sys(struct mtk_hdmi *hdmi)
+--
+2.50.1
+
--- /dev/null
+From cedc6de13668f5088bfc92adb4ff52aa728211bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jul 2025 13:28:22 -0700
+Subject: drm/msm: Defer fd_install in SUBMIT ioctl
+
+From: Rob Clark <robin.clark@oss.qualcomm.com>
+
+[ Upstream commit f22853435bbd1e9836d0dce7fd99c040b94c2bf1 ]
+
+Avoid fd_install() until there are no more potential error paths, to
+avoid put_unused_fd() after the fd is made visible to userspace.
+
+Fixes: 68dc6c2d5eec ("drm/msm: Fix submit error-path leaks")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/665363/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index d4f71bb54e84c..081d59979e31d 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -869,12 +869,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+
+ if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+ sync_file = sync_file_create(submit->user_fence);
+- if (!sync_file) {
++ if (!sync_file)
+ ret = -ENOMEM;
+- } else {
+- fd_install(out_fence_fd, sync_file->file);
+- args->fence_fd = out_fence_fd;
+- }
+ }
+
+ if (ret)
+@@ -902,10 +898,14 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+ out_unlock:
+ mutex_unlock(&queue->lock);
+ out_post_unlock:
+- if (ret && (out_fence_fd >= 0)) {
+- put_unused_fd(out_fence_fd);
++ if (ret) {
++ if (out_fence_fd >= 0)
++ put_unused_fd(out_fence_fd);
+ if (sync_file)
+ fput(sync_file->file);
++ } else if (sync_file) {
++ fd_install(out_fence_fd, sync_file->file);
++ args->fence_fd = out_fence_fd;
+ }
+
+ if (!IS_ERR_OR_NULL(submit)) {
+--
+2.50.1
+
--- /dev/null
+From 1085747a2621ee739c2b1840e757e3d381da2601 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jul 2025 16:17:40 -0500
+Subject: drm/msm/dpu: Add a null ptr check for dpu_encoder_needs_modeset
+
+From: Chenyuan Yang <chenyuan0y@gmail.com>
+
+[ Upstream commit abebfed208515726760d79cf4f9f1a76b9a10a84 ]
+
+The drm_atomic_get_new_connector_state() can return NULL if the
+connector is not part of the atomic state. Add a check to prevent
+a NULL pointer dereference.
+
+This follows the same pattern used in dpu_encoder_update_topology()
+within the same file, which checks for NULL before using conn_state.
+
+Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
+Fixes: 1ce69c265a53 ("drm/msm/dpu: move resource allocation to CRTC")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/665188/
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index c0ed110a7d30f..4bddb9504796b 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -729,6 +729,8 @@ bool dpu_encoder_needs_modeset(struct drm_encoder *drm_enc, struct drm_atomic_st
+ return false;
+
+ conn_state = drm_atomic_get_new_connector_state(state, connector);
++ if (!conn_state)
++ return false;
+
+ /**
+ * These checks are duplicated from dpu_encoder_update_topology() since
+--
+2.50.1
+
--- /dev/null
+From b6dd18ad11593feb8e60fdc32a51ede696151b3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jul 2025 20:28:18 +0300
+Subject: drm/msm/dpu: correct dpu_plane_virtual_atomic_check()
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 1a76b255eceb9c570c6228f6393e1d63d97a22ba ]
+
+Fix c&p error in dpu_plane_virtual_atomic_check(), compare CRTC width
+too, in addition to CRTC height.
+
+Fixes: 8c62a31607f6 ("drm/msm/dpu: allow using two SSPP blocks for a single plane")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202507150432.U0cALR6W-lkp@intel.com/
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Jessica Zhang <jessica.zhang@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/664170/
+Link: https://lore.kernel.org/r/20250715-msm-fix-virt-atomic-check-v1-1-9bab02c9f952@oss.qualcomm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+index 421138bc3cb77..28d42eade5ccb 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+@@ -1169,7 +1169,7 @@ static int dpu_plane_virtual_atomic_check(struct drm_plane *plane,
+ if (!old_plane_state || !old_plane_state->fb ||
+ old_plane_state->src_w != plane_state->src_w ||
+ old_plane_state->src_h != plane_state->src_h ||
+- old_plane_state->src_w != plane_state->src_w ||
++ old_plane_state->crtc_w != plane_state->crtc_w ||
+ old_plane_state->crtc_h != plane_state->crtc_h ||
+ msm_framebuffer_format(old_plane_state->fb) !=
+ msm_framebuffer_format(plane_state->fb))
+--
+2.50.1
+
--- /dev/null
+From 2cdaed6725c591a52bd5dede850f6d78049c647e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 15 Jul 2025 18:50:37 +0300
+Subject: drm/msm/kms: move snapshot init earlier in KMS init
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 553666f839b86545300773954df7426a45c169c4 ]
+
+Various parts of the display driver can be triggering the display
+snapshot (including the IOMMU fault handlers). Move the call to
+msm_disp_snapshot_init() before KMS initialization, otherwise it is
+possible to ocassionally trigger the kernel fault during init:
+
+ __lock_acquire+0x44/0x2798 (P)
+ lock_acquire+0x114/0x25c
+ _raw_spin_lock_irqsave+0x6c/0x90
+ kthread_queue_work+0x2c/0xac
+ msm_disp_snapshot_state+0x2c/0x4c
+ msm_kms_fault_handler+0x2c/0x74
+ msm_disp_fault_handler+0x30/0x48
+ report_iommu_fault+0x54/0x128
+ arm_smmu_context_fault+0x74/0x184
+ __handle_irq_event_percpu+0xa4/0x24c
+ handle_irq_event_percpu+0x20/0x5c
+ handle_irq_event+0x48/0x84
+ handle_fasteoi_irq+0xcc/0x170
+ generic_handle_domain_irq+0x48/0x70
+ gic_handle_irq+0x54/0x11c
+ call_on_irq_stack+0x3c/0x50
+ do_interrupt_handler+0x54/0x78
+ el1_interrupt+0x3c/0x5c
+ el1h_64_irq_handler+0x20/0x30
+ el1h_64_irq+0x6c/0x70
+ _raw_spin_unlock_irqrestore+0x44/0x68 (P)
+ klist_next+0xc4/0x124
+ bus_for_each_drv+0x9c/0xe8
+ __device_attach+0xfc/0x190
+ device_initial_probe+0x1c/0x2c
+ bus_probe_device+0x44/0xa0
+ device_add+0x204/0x3e4
+ platform_device_add+0x170/0x244
+ platform_device_register_full+0x130/0x138
+ drm_connector_hdmi_audio_init+0xc0/0x108
+ drm_bridge_connector_init+0x318/0x394
+ msm_dsi_manager_connector_init+0xac/0xdc
+ msm_dsi_modeset_init+0x78/0xc0
+ _dpu_kms_drm_obj_init+0x198/0x75c
+ dpu_kms_hw_init+0x2f8/0x494
+ msm_drm_kms_init+0xb0/0x230
+ msm_drm_init+0x218/0x250
+ msm_drm_bind+0x3c/0x4c
+ try_to_bring_up_aggregate_device+0x208/0x2a4
+ __component_add+0xa8/0x188
+ component_add+0x1c/0x2c
+ dsi_dev_attach+0x24/0x34
+ dsi_host_attach+0x68/0xa0
+ devm_mipi_dsi_attach+0x40/0xcc
+ lt9611_attach_dsi+0x94/0x118
+ lt9611_probe+0x368/0x3c8
+ i2c_device_probe+0x2d0/0x3d8
+ really_probe+0x130/0x354
+ __driver_probe_device+0xac/0x110
+ driver_probe_device+0x44/0x110
+ __device_attach_driver+0xb0/0x138
+ bus_for_each_drv+0x90/0xe8
+ __device_attach+0xfc/0x190
+ device_initial_probe+0x1c/0x2c
+ bus_probe_device+0x44/0xa0
+ deferred_probe_work_func+0xac/0x110
+ process_one_work+0x20c/0x51c
+ process_scheduled_works+0x58/0x88
+ worker_thread+0x1ec/0x304
+ kthread+0x194/0x1d4
+ ret_from_fork+0x10/0x20
+
+Reported-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Fixes: 98659487b845 ("drm/msm: add support to take dpu snapshot")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/664149/
+Link: https://lore.kernel.org/r/20250715-msm-move-snapshot-init-v1-1-f39c396192ab@oss.qualcomm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_kms.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_kms.c b/drivers/gpu/drm/msm/msm_kms.c
+index 35d5397e73b4c..f2c00716f9d1a 100644
+--- a/drivers/gpu/drm/msm/msm_kms.c
++++ b/drivers/gpu/drm/msm/msm_kms.c
+@@ -258,6 +258,12 @@ int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv)
+ if (ret)
+ return ret;
+
++ ret = msm_disp_snapshot_init(ddev);
++ if (ret) {
++ DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
++ return ret;
++ }
++
+ ret = priv->kms_init(ddev);
+ if (ret) {
+ DRM_DEV_ERROR(dev, "failed to load kms\n");
+@@ -310,10 +316,6 @@ int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv)
+ goto err_msm_uninit;
+ }
+
+- ret = msm_disp_snapshot_init(ddev);
+- if (ret)
+- DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
+-
+ drm_mode_config_reset(ddev);
+
+ return 0;
+--
+2.50.1
+
--- /dev/null
+From 79e96c1c52a349e29f628a54916a9dd796141faa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 30 Jul 2025 18:09:38 +0530
+Subject: drm/msm: update the high bitfield of certain DSI registers
+
+From: Ayushi Makhija <quic_amakhija@quicinc.com>
+
+[ Upstream commit 494045c561e68945b1183ff416b8db8e37a122d6 ]
+
+Currently, the high bitfield of certain DSI registers
+do not align with the configuration of the SWI registers
+description. This can lead to wrong programming these DSI
+registers, for example for 4k resloution where H_TOTAL is
+taking 13 bits but software is programming only 12 bits
+because of the incorrect bitmask for H_TOTAL bitfeild,
+this is causing DSI FIFO errors. To resolve this issue,
+increase the high bitfield of the DSI registers from 12 bits
+to 16 bits in dsi.xml to match the SWI register configuration.
+
+Signed-off-by: Ayushi Makhija <quic_amakhija@quicinc.com>
+Fixes: 4f52f5e63b62 ("drm/msm: import XML display registers database")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/666229/
+Link: https://lore.kernel.org/r/20250730123938.1038640-1-quic_amakhija@quicinc.com
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/registers/display/dsi.xml | 28 +++++++++----------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/registers/display/dsi.xml b/drivers/gpu/drm/msm/registers/display/dsi.xml
+index 501ffc585a9f6..c7a7b633d747b 100644
+--- a/drivers/gpu/drm/msm/registers/display/dsi.xml
++++ b/drivers/gpu/drm/msm/registers/display/dsi.xml
+@@ -159,28 +159,28 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+ <bitfield name="RGB_SWAP" low="12" high="14" type="dsi_rgb_swap"/>
+ </reg32>
+ <reg32 offset="0x00020" name="ACTIVE_H">
+- <bitfield name="START" low="0" high="11" type="uint"/>
+- <bitfield name="END" low="16" high="27" type="uint"/>
++ <bitfield name="START" low="0" high="15" type="uint"/>
++ <bitfield name="END" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x00024" name="ACTIVE_V">
+- <bitfield name="START" low="0" high="11" type="uint"/>
+- <bitfield name="END" low="16" high="27" type="uint"/>
++ <bitfield name="START" low="0" high="15" type="uint"/>
++ <bitfield name="END" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x00028" name="TOTAL">
+- <bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+- <bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
++ <bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
++ <bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x0002c" name="ACTIVE_HSYNC">
+- <bitfield name="START" low="0" high="11" type="uint"/>
+- <bitfield name="END" low="16" high="27" type="uint"/>
++ <bitfield name="START" low="0" high="15" type="uint"/>
++ <bitfield name="END" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x00030" name="ACTIVE_VSYNC_HPOS">
+- <bitfield name="START" low="0" high="11" type="uint"/>
+- <bitfield name="END" low="16" high="27" type="uint"/>
++ <bitfield name="START" low="0" high="15" type="uint"/>
++ <bitfield name="END" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x00034" name="ACTIVE_VSYNC_VPOS">
+- <bitfield name="START" low="0" high="11" type="uint"/>
+- <bitfield name="END" low="16" high="27" type="uint"/>
++ <bitfield name="START" low="0" high="15" type="uint"/>
++ <bitfield name="END" low="16" high="31" type="uint"/>
+ </reg32>
+
+ <reg32 offset="0x00038" name="CMD_DMA_CTRL">
+@@ -209,8 +209,8 @@ xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+ <bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x00058" name="CMD_MDP_STREAM0_TOTAL">
+- <bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+- <bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
++ <bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
++ <bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+ </reg32>
+ <reg32 offset="0x0005c" name="CMD_MDP_STREAM1_CTRL">
+ <bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+--
+2.50.1
+
--- /dev/null
+From cf92907fed69bcb375b4941ffd3285966c2f3939 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:03 -0500
+Subject: drm/nouveau: remove unused increment in gm200_flcn_pio_imem_wr
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit f529b8915543fb9ceb732cec5571f7fe12bc9530 ]
+
+The 'tag' parameter is passed by value and is not actually used after
+being incremented, so remove the increment. It's the function that calls
+gm200_flcn_pio_imem_wr that is supposed to (and does) increment 'tag'.
+
+Fixes: 0e44c2170876 ("drm/nouveau/flcn: new code to load+boot simple HS FWs (VPR scrubber)")
+Reviewed-by: Philipp Stanner <phasta@kernel.org>
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-2-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index b7da3ab44c277..6a004c6e67425 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -103,7 +103,7 @@ gm200_flcn_pio_imem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 i
+ static void
+ gm200_flcn_pio_imem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len, u16 tag)
+ {
+- nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag++);
++ nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag);
+ while (len >= 4) {
+ nvkm_falcon_wr32(falcon, 0x184 + (port * 0x10), *(u32 *)img);
+ img += 4;
+--
+2.50.1
+
--- /dev/null
+From 496f2e1354c28ecc1b2df9953eac47b7f76ee4be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:04 -0500
+Subject: drm/nouveau: remove unused memory target test
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit 64c722b5e7f6b909b0e448e580f64628a0d76208 ]
+
+The memory target check is a hold-over from a refactor. It's harmless
+but distracting, so just remove it.
+
+Fixes: 2541626cfb79 ("drm/nouveau/acr: use common falcon HS FW code for ACR FWs")
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-3-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index 6a004c6e67425..7c43397c19e61 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -249,9 +249,11 @@ int
+ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+ {
+ struct nvkm_falcon *falcon = fw->falcon;
+- int target, ret;
++ int ret;
+
+ if (fw->inst) {
++ int target;
++
+ nvkm_falcon_mask(falcon, 0x048, 0x00000001, 0x00000001);
+
+ switch (nvkm_memory_target(fw->inst)) {
+@@ -285,15 +287,6 @@ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+ }
+
+ if (fw->boot) {
+- switch (nvkm_memory_target(&fw->fw.mem.memory)) {
+- case NVKM_MEM_TARGET_VRAM: target = 4; break;
+- case NVKM_MEM_TARGET_HOST: target = 5; break;
+- case NVKM_MEM_TARGET_NCOH: target = 6; break;
+- default:
+- WARN_ON(1);
+- return -EINVAL;
+- }
+-
+ ret = nvkm_falcon_pio_wr(falcon, fw->boot, 0, 0,
+ IMEM, falcon->code.limit - fw->boot_size, fw->boot_size,
+ fw->boot_addr >> 8, false);
+--
+2.50.1
+
--- /dev/null
+From 5064a5a5da12f395cda17abd5fa598f63eff5443 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:28:41 -0700
+Subject: drm/xe: Don't trigger rebind on initial dma-buf validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthew Brost <matthew.brost@intel.com>
+
+[ Upstream commit 16ca06aa2c2218cb21907c0c45a746958c944def ]
+
+On the first validate of an imported dma-buf (initial bind), the device
+has no GPU mappings, so a rebind is unnecessary. Rebinding here is
+harmful in multi-GPU setups and for VMs using preempt-fence mode, as it
+would evict in-flight GPU work.
+
+v2:
+ - Drop dma_buf_validated, check for XE_PL_SYSTEM (Thomas)
+
+Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Link: https://lore.kernel.org/r/20250825152841.3837378-1-matthew.brost@intel.com
+(cherry picked from commit ffdf968762e4fb3cdae54e811ec3525e67440a60)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index e2c6493cb70d9..74635b444122d 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -796,7 +796,8 @@ static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
+ }
+
+ if (ttm_bo->type == ttm_bo_type_sg) {
+- ret = xe_bo_move_notify(bo, ctx);
++ if (new_mem->mem_type == XE_PL_SYSTEM)
++ ret = xe_bo_move_notify(bo, ctx);
+ if (!ret)
+ ret = xe_bo_move_dmabuf(ttm_bo, new_mem);
+ return ret;
+--
+2.50.1
+
--- /dev/null
+From 1850e2b00bbfd8a3c2a0b2bd6705101201cfe4a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 16:30:43 +0200
+Subject: drm/xe/vm: Don't pin the vm_resv during validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+
+[ Upstream commit 7551865cd12af2dc47e5a174eebcfb0b94b5449b ]
+
+The pinning has the odd side-effect that unlocking *any* resv
+during validation triggers an "unlocking pinned lock" warning.
+
+Cc: Matthew Brost <matthew.brost@intel.com>
+Fixes: 5cc3325584c4 ("drm/xe: Rework eviction rejection of bound external bos")
+Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://lore.kernel.org/r/20250821143045.106005-2-thomas.hellstrom@linux.intel.com
+(cherry picked from commit 0a51bf3e54dd8b77e6f1febbbb66def0660862d2)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c | 5 ++---
+ drivers/gpu/drm/xe/xe_vm.h | 15 ++-------------
+ 2 files changed, 4 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index 7aa2c17825da9..e2c6493cb70d9 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -2435,7 +2435,6 @@ int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict)
+ .no_wait_gpu = false,
+ .gfp_retry_mayfail = true,
+ };
+- struct pin_cookie cookie;
+ int ret;
+
+ if (vm) {
+@@ -2446,10 +2445,10 @@ int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict)
+ ctx.resv = xe_vm_resv(vm);
+ }
+
+- cookie = xe_vm_set_validating(vm, allow_res_evict);
++ xe_vm_set_validating(vm, allow_res_evict);
+ trace_xe_bo_validate(bo);
+ ret = ttm_bo_validate(&bo->ttm, &bo->placement, &ctx);
+- xe_vm_clear_validating(vm, allow_res_evict, cookie);
++ xe_vm_clear_validating(vm, allow_res_evict);
+
+ return ret;
+ }
+diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
+index 0158ec0ae3b23..e54ca835b5828 100644
+--- a/drivers/gpu/drm/xe/xe_vm.h
++++ b/drivers/gpu/drm/xe/xe_vm.h
+@@ -310,22 +310,14 @@ void xe_vm_snapshot_free(struct xe_vm_snapshot *snap);
+ * Register this task as currently making bos resident for the vm. Intended
+ * to avoid eviction by the same task of shared bos bound to the vm.
+ * Call with the vm's resv lock held.
+- *
+- * Return: A pin cookie that should be used for xe_vm_clear_validating().
+ */
+-static inline struct pin_cookie xe_vm_set_validating(struct xe_vm *vm,
+- bool allow_res_evict)
++static inline void xe_vm_set_validating(struct xe_vm *vm, bool allow_res_evict)
+ {
+- struct pin_cookie cookie = {};
+-
+ if (vm && !allow_res_evict) {
+ xe_vm_assert_held(vm);
+- cookie = lockdep_pin_lock(&xe_vm_resv(vm)->lock.base);
+ /* Pairs with READ_ONCE in xe_vm_is_validating() */
+ WRITE_ONCE(vm->validating, current);
+ }
+-
+- return cookie;
+ }
+
+ /**
+@@ -333,17 +325,14 @@ static inline struct pin_cookie xe_vm_set_validating(struct xe_vm *vm,
+ * @vm: Pointer to the vm or NULL
+ * @allow_res_evict: Eviction from @vm was allowed. Must be set to the same
+ * value as for xe_vm_set_validation().
+- * @cookie: Cookie obtained from xe_vm_set_validating().
+ *
+ * Register this task as currently making bos resident for the vm. Intended
+ * to avoid eviction by the same task of shared bos bound to the vm.
+ * Call with the vm's resv lock held.
+ */
+-static inline void xe_vm_clear_validating(struct xe_vm *vm, bool allow_res_evict,
+- struct pin_cookie cookie)
++static inline void xe_vm_clear_validating(struct xe_vm *vm, bool allow_res_evict)
+ {
+ if (vm && !allow_res_evict) {
+- lockdep_unpin_lock(&xe_vm_resv(vm)->lock.base, cookie);
+ /* Pairs with READ_ONCE in xe_vm_is_validating() */
+ WRITE_ONCE(vm->validating, NULL);
+ }
+--
+2.50.1
+
--- /dev/null
+From eee342b865862b49cca0f8370369fee7586cee59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 10:39:04 +0200
+Subject: drm/xe/xe_sync: avoid race during ufence signaling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
+
+[ Upstream commit 04e1f683cd28dc9407b238543871a6e09a570dc0 ]
+
+Marking ufence as signalled after copy_to_user() is too late.
+Worker thread which signals ufence by memory write might be raced
+with another userspace vm-bind call. In map/unmap scenario unmap
+may still see ufence is not signalled causing -EBUSY. Change the
+order of marking / write to user-fence fixes this issue.
+
+Fixes: 977e5b82e090 ("drm/xe: Expose user fence from xe_sync_entry")
+Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/5536
+Signed-off-by: Zbigniew Kempczyński <zbigniew.kempczynski@intel.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Matthew Auld <matthew.auld@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://lore.kernel.org/r/20250820083903.2109891-2-zbigniew.kempczynski@intel.com
+(cherry picked from commit 8ae04fe9ffc93d6bc3bc63ac08375427d69cee06)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_sync.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c
+index f87276df18f28..82872a51f0983 100644
+--- a/drivers/gpu/drm/xe/xe_sync.c
++++ b/drivers/gpu/drm/xe/xe_sync.c
+@@ -77,6 +77,7 @@ static void user_fence_worker(struct work_struct *w)
+ {
+ struct xe_user_fence *ufence = container_of(w, struct xe_user_fence, worker);
+
++ WRITE_ONCE(ufence->signalled, 1);
+ if (mmget_not_zero(ufence->mm)) {
+ kthread_use_mm(ufence->mm);
+ if (copy_to_user(ufence->addr, &ufence->value, sizeof(ufence->value)))
+@@ -91,7 +92,6 @@ static void user_fence_worker(struct work_struct *w)
+ * Wake up waiters only after updating the ufence state, allowing the UMD
+ * to safely reuse the same ufence without encountering -EBUSY errors.
+ */
+- WRITE_ONCE(ufence->signalled, 1);
+ wake_up_all(&ufence->xe->ufence_wq);
+ user_fence_put(ufence);
+ }
+--
+2.50.1
+
--- /dev/null
+From 7e1fb54cd5fd623cd674ad162637a4030e16bb1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Aug 2025 11:36:54 +0300
+Subject: dt-bindings: display/msm: qcom,mdp5: drop lut clock
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 7ab3b7579a6d2660a3425b9ea93b9a140b07f49c ]
+
+None of MDP5 platforms have a LUT clock on the display-controller, it
+was added by the mistake. Drop it, fixing DT warnings on MSM8976 /
+MSM8956 platforms. Technically it's an ABI break, but no other platforms
+are affected.
+
+Fixes: 385c8ac763b3 ("dt-bindings: display/msm: convert MDP5 schema to YAML format")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Patchwork: https://patchwork.freedesktop.org/patch/667822/
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+index e153f8d26e7aa..2735c78b0b67a 100644
+--- a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
++++ b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+@@ -60,7 +60,6 @@ properties:
+ - const: bus
+ - const: core
+ - const: vsync
+- - const: lut
+ - const: tbu
+ - const: tbu_rt
+ # MSM8996 has additional iommu clock
+--
+2.50.1
+
--- /dev/null
+From 261aecfdcd3d8a4cdf60881d3a717a72f006e1df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 18:07:10 +0200
+Subject: efi: stmm: Fix incorrect buffer allocation method
+
+From: Jan Kiszka <jan.kiszka@siemens.com>
+
+[ Upstream commit c5e81e672699e0c5557b2b755cc8f7a69aa92bff ]
+
+The communication buffer allocated by setup_mm_hdr() is later on passed
+to tee_shm_register_kernel_buf(). The latter expects those buffers to be
+contiguous pages, but setup_mm_hdr() just uses kmalloc(). That can cause
+various corruptions or BUGs, specifically since commit 9aec2fb0fd5e
+("slab: allocate frozen pages"), though it was broken before as well.
+
+Fix this by using alloc_pages_exact() instead of kmalloc().
+
+Fixes: c44b6be62e8d ("efi: Add tee-based EFI variable driver")
+Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
+Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
+Acked-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/stmm/tee_stmm_efi.c | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/firmware/efi/stmm/tee_stmm_efi.c b/drivers/firmware/efi/stmm/tee_stmm_efi.c
+index f741ca279052b..e15d11ed165ee 100644
+--- a/drivers/firmware/efi/stmm/tee_stmm_efi.c
++++ b/drivers/firmware/efi/stmm/tee_stmm_efi.c
+@@ -143,6 +143,10 @@ static efi_status_t mm_communicate(u8 *comm_buf, size_t payload_size)
+ return var_hdr->ret_status;
+ }
+
++#define COMM_BUF_SIZE(__payload_size) (MM_COMMUNICATE_HEADER_SIZE + \
++ MM_VARIABLE_COMMUNICATE_SIZE + \
++ (__payload_size))
++
+ /**
+ * setup_mm_hdr() - Allocate a buffer for StandAloneMM and initialize the
+ * header data.
+@@ -173,9 +177,8 @@ static void *setup_mm_hdr(u8 **dptr, size_t payload_size, size_t func,
+ return NULL;
+ }
+
+- comm_buf = kzalloc(MM_COMMUNICATE_HEADER_SIZE +
+- MM_VARIABLE_COMMUNICATE_SIZE + payload_size,
+- GFP_KERNEL);
++ comm_buf = alloc_pages_exact(COMM_BUF_SIZE(payload_size),
++ GFP_KERNEL | __GFP_ZERO);
+ if (!comm_buf) {
+ *ret = EFI_OUT_OF_RESOURCES;
+ return NULL;
+@@ -239,7 +242,7 @@ static efi_status_t get_max_payload(size_t *size)
+ */
+ *size -= 2;
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+@@ -282,7 +285,7 @@ static efi_status_t get_property_int(u16 *name, size_t name_size,
+ memcpy(var_property, &smm_property->property, sizeof(*var_property));
+
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+@@ -347,7 +350,7 @@ static efi_status_t tee_get_variable(u16 *name, efi_guid_t *vendor,
+ memcpy(data, (u8 *)var_acc->name + var_acc->name_size,
+ var_acc->data_size);
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+@@ -404,7 +407,7 @@ static efi_status_t tee_get_next_variable(unsigned long *name_size,
+ memcpy(name, var_getnext->name, var_getnext->name_size);
+
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+@@ -467,7 +470,7 @@ static efi_status_t tee_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ ret = mm_communicate(comm_buf, payload_size);
+ dev_dbg(pvt_data.dev, "Set Variable %s %d %lx\n", __FILE__, __LINE__, ret);
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+@@ -507,7 +510,7 @@ static efi_status_t tee_query_variable_info(u32 attributes,
+ *max_variable_size = mm_query_info->max_variable_size;
+
+ out:
+- kfree(comm_buf);
++ free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
+ return ret;
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 3bec7c0470fdba2b688af477fa7d1757698b677b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+ BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+ Call trace:
+ kasan_check_range+0xe8/0x190
+ __asan_loadN+0x1c/0x28
+ memcmp+0x98/0xd0
+ efivarfs_d_compare+0x68/0xd8
+ __d_lookup_rcu_op_compare+0x178/0x218
+ __d_lookup_rcu+0x1f8/0x228
+ d_alloc_parallel+0x150/0x648
+ lookup_open.isra.0+0x5f0/0x8d0
+ open_last_lookups+0x264/0x828
+ path_openat+0x130/0x3f8
+ do_filp_open+0x114/0x248
+ do_sys_openat2+0x340/0x3c0
+ __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+ T1 T2
+ lookup_open
+ ->lookup
+ simple_lookup
+ d_add
+ // invalid dentry is added to hash list
+
+ lookup_open
+ d_alloc_parallel
+ __d_lookup_rcu
+ __d_lookup_rcu_op_compare
+ hlist_bl_for_each_entry_rcu
+ // invalid dentry can be retrieved
+ ->d_compare
+ efivarfs_d_compare
+ // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 284d6dbba2ece..5c0d45cccc10e 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -152,6 +152,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+ int guid = len - EFI_VARIABLE_GUID_LEN;
+
++ /* Parallel lookups may produce a temporary invalid filename */
++ if (guid <= 0)
++ return 1;
++
+ if (name->len != len)
+ return 1;
+
+--
+2.50.1
+
--- /dev/null
+From 42537d367c4e534c42d1c8e149b80958ca1c994d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 15:56:13 -0700
+Subject: fbnic: Move phylink resume out of service_task and into open/close
+
+From: Alexander Duyck <alexanderduyck@fb.com>
+
+[ Upstream commit 6ede14a2c6365e7e5d855643c7c8390b5268c467 ]
+
+The fbnic driver was presenting with the following locking assert coming
+out of a PM resume:
+[ 42.208116][ T164] RTNL: assertion failed at drivers/net/phy/phylink.c (2611)
+[ 42.208492][ T164] WARNING: CPU: 1 PID: 164 at drivers/net/phy/phylink.c:2611 phylink_resume+0x190/0x1e0
+[ 42.208872][ T164] Modules linked in:
+[ 42.209140][ T164] CPU: 1 UID: 0 PID: 164 Comm: bash Not tainted 6.17.0-rc2-virtme #134 PREEMPT(full)
+[ 42.209496][ T164] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-5.fc42 04/01/2014
+[ 42.209861][ T164] RIP: 0010:phylink_resume+0x190/0x1e0
+[ 42.210057][ T164] Code: 83 e5 01 0f 85 b0 fe ff ff c6 05 1c cd 3e 02 01 90 ba 33 0a 00 00 48 c7 c6 20 3a 1d a5 48 c7 c7 e0 3e 1d a5 e8 21 b8 90 fe 90 <0f> 0b 90 90 e9 86 fe ff ff e8 42 ea 1f ff e9 e2 fe ff ff 48 89 ef
+[ 42.210708][ T164] RSP: 0018:ffffc90000affbd8 EFLAGS: 00010296
+[ 42.210983][ T164] RAX: 0000000000000000 RBX: ffff8880078d8400 RCX: 0000000000000000
+[ 42.211235][ T164] RDX: 0000000000000000 RSI: 1ffffffff4f10938 RDI: 0000000000000001
+[ 42.211466][ T164] RBP: 0000000000000000 R08: ffffffffa2ae79ea R09: fffffbfff4b3eb84
+[ 42.211707][ T164] R10: 0000000000000003 R11: 0000000000000000 R12: ffff888007ad8000
+[ 42.211997][ T164] R13: 0000000000000002 R14: ffff888006a18800 R15: ffffffffa34c59e0
+[ 42.212234][ T164] FS: 00007f0dc8e39740(0000) GS:ffff88808f51f000(0000) knlGS:0000000000000000
+[ 42.212505][ T164] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 42.212704][ T164] CR2: 00007f0dc8e9fe10 CR3: 000000000b56d003 CR4: 0000000000772ef0
+[ 42.213227][ T164] PKRU: 55555554
+[ 42.213366][ T164] Call Trace:
+[ 42.213483][ T164] <TASK>
+[ 42.213565][ T164] __fbnic_pm_attach.isra.0+0x8e/0xa0
+[ 42.213725][ T164] pci_reset_function+0x116/0x1d0
+[ 42.213895][ T164] reset_store+0xa0/0x100
+[ 42.214025][ T164] ? pci_dev_reset_attr_is_visible+0x50/0x50
+[ 42.214221][ T164] ? sysfs_file_kobj+0xc1/0x1e0
+[ 42.214374][ T164] ? sysfs_kf_write+0x65/0x160
+[ 42.214526][ T164] kernfs_fop_write_iter+0x2f8/0x4c0
+[ 42.214677][ T164] ? kernfs_vma_page_mkwrite+0x1f0/0x1f0
+[ 42.214836][ T164] new_sync_write+0x308/0x6f0
+[ 42.214987][ T164] ? __lock_acquire+0x34c/0x740
+[ 42.215135][ T164] ? new_sync_read+0x6f0/0x6f0
+[ 42.215288][ T164] ? lock_acquire.part.0+0xbc/0x260
+[ 42.215440][ T164] ? ksys_write+0xff/0x200
+[ 42.215590][ T164] ? perf_trace_sched_switch+0x6d0/0x6d0
+[ 42.215742][ T164] vfs_write+0x65e/0xbb0
+[ 42.215876][ T164] ksys_write+0xff/0x200
+[ 42.215994][ T164] ? __ia32_sys_read+0xc0/0xc0
+[ 42.216141][ T164] ? do_user_addr_fault+0x269/0x9f0
+[ 42.216292][ T164] ? rcu_is_watching+0x15/0xd0
+[ 42.216442][ T164] do_syscall_64+0xbb/0x360
+[ 42.216591][ T164] entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[ 42.216784][ T164] RIP: 0033:0x7f0dc8ea9986
+
+A bit of digging showed that we were invoking the phylink_resume as a part
+of the fbnic_up path when we were enabling the service task while not
+holding the RTNL lock. We should be enabling this sooner as a part of the
+ndo_open path and then just letting the service task come online later.
+This will help to enforce the correct locking and brings the phylink
+interface online at the same time as the network interface, instead of at a
+later time.
+
+I tested this on QEMU to verify this was working by putting the system to
+sleep using "echo mem > /sys/power/state" to put the system to sleep in the
+guest and then using the command "system_wakeup" in the QEMU monitor.
+
+Fixes: 69684376eed5 ("eth: fbnic: Add link detection")
+Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Link: https://patch.msgid.link/175616257316.1963577.12238158800417771119.stgit@ahduyck-xeon-server.home.arpa
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 4 ++++
+ drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 2 --
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+index 553bd8b8bb056..d3d1003df8314 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+@@ -52,6 +52,8 @@ int __fbnic_open(struct fbnic_net *fbn)
+ fbnic_bmc_rpc_init(fbd);
+ fbnic_rss_reinit(fbd, fbn);
+
++ phylink_resume(fbn->phylink);
++
+ return 0;
+ time_stop:
+ fbnic_time_stop(fbn);
+@@ -84,6 +86,8 @@ static int fbnic_stop(struct net_device *netdev)
+ {
+ struct fbnic_net *fbn = netdev_priv(netdev);
+
++ phylink_suspend(fbn->phylink, fbnic_bmc_present(fbn->fbd));
++
+ fbnic_down(fbn);
+ fbnic_pcs_free_irq(fbn->fbd);
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+index 249d3ef862d5a..38045cce38012 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+@@ -118,14 +118,12 @@ static void fbnic_service_task_start(struct fbnic_net *fbn)
+ struct fbnic_dev *fbd = fbn->fbd;
+
+ schedule_delayed_work(&fbd->service_task, HZ);
+- phylink_resume(fbn->phylink);
+ }
+
+ static void fbnic_service_task_stop(struct fbnic_net *fbn)
+ {
+ struct fbnic_dev *fbd = fbn->fbd;
+
+- phylink_suspend(fbn->phylink, fbnic_bmc_present(fbd));
+ cancel_delayed_work(&fbd->service_task);
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 7b4a69905042843249550d6467d8b7c6bd9b7161 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:39 +0200
+Subject: HID: input: rename hidinput_set_battery_charge_status()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit a82231b2a8712d0218fc286a9b0da328d419a3f4 ]
+
+In preparation for a patch fixing a bug affecting
+hidinput_set_battery_charge_status(), rename the function to
+hidinput_update_battery_charge_status() and move it up so it can be used
+by hidinput_update_battery().
+
+Refactor, no functional changes.
+
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Stable-dep-of: e94536e1d181 ("HID: input: report battery status changes immediately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input-test.c | 10 +++++-----
+ drivers/hid/hid-input.c | 38 ++++++++++++++++++------------------
+ 2 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c
+index 77c2d45ac62a7..6f5c71660d823 100644
+--- a/drivers/hid/hid-input-test.c
++++ b/drivers/hid/hid-input-test.c
+@@ -7,7 +7,7 @@
+
+ #include <kunit/test.h>
+
+-static void hid_test_input_set_battery_charge_status(struct kunit *test)
++static void hid_test_input_update_battery_charge_status(struct kunit *test)
+ {
+ struct hid_device *dev;
+ bool handled;
+@@ -15,15 +15,15 @@ static void hid_test_input_set_battery_charge_status(struct kunit *test)
+ dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
++ handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
+ KUNIT_EXPECT_FALSE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
++ handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
+ KUNIT_EXPECT_TRUE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
++ handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
+ KUNIT_EXPECT_TRUE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
+ }
+@@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
+ }
+
+ static struct kunit_case hid_input_tests[] = {
+- KUNIT_CASE(hid_test_input_set_battery_charge_status),
++ KUNIT_CASE(hid_test_input_update_battery_charge_status),
+ KUNIT_CASE(hid_test_input_get_battery_property),
+ { }
+ };
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index ff1784b5c2a47..262787e6eb204 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -595,6 +595,20 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ dev->battery = NULL;
+ }
+
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++ unsigned int usage, int value)
++{
++ switch (usage) {
++ case HID_BAT_CHARGING:
++ dev->battery_charge_status = value ?
++ POWER_SUPPLY_STATUS_CHARGING :
++ POWER_SUPPLY_STATUS_DISCHARGING;
++ return true;
++ }
++
++ return false;
++}
++
+ static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+ int capacity;
+@@ -617,20 +631,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
+ power_supply_changed(dev->battery);
+ }
+ }
+-
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
+-{
+- switch (usage) {
+- case HID_BAT_CHARGING:
+- dev->battery_charge_status = value ?
+- POWER_SUPPLY_STATUS_CHARGING :
+- POWER_SUPPLY_STATUS_DISCHARGING;
+- return true;
+- }
+-
+- return false;
+-}
+ #else /* !CONFIG_HID_BATTERY_STRENGTH */
+ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+ struct hid_field *field, bool is_percentage)
+@@ -642,14 +642,14 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++ unsigned int usage, int value)
+ {
++ return false;
+ }
+
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
++static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+- return false;
+ }
+ #endif /* CONFIG_HID_BATTERY_STRENGTH */
+
+@@ -1515,7 +1515,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+ return;
+
+ if (usage->type == EV_PWR) {
+- bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
++ bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+
+ if (!handled)
+ hidinput_update_battery(hid, value);
+--
+2.50.1
+
--- /dev/null
+From 647a17f9f643be926d6ac02e2bbf7b9d91073209 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:40 +0200
+Subject: HID: input: report battery status changes immediately
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit e94536e1d1818b0989aa19b443b7089f50133c35 ]
+
+Previously, the battery status (charging/discharging) was not reported
+immediately to user-space.
+
+For most input devices, this wasn't problematic because changing their
+battery status requires connecting them to a different bus.
+For example, a gamepad would report a discharging status while
+connected via Bluetooth and a charging status while connected via USB.
+
+However, certain devices are not connected or disconnected when their
+battery status changes. For example, a phone battery changes its status
+without connecting or disconnecting it.
+In these cases, the battery status was not reported immediately to user
+space.
+
+Report battery status changes immediately to user space to support
+these kinds of devices.
+
+Fixes: a608dc1c0639 ("HID: input: map battery system charging")
+Reported-by: 卢国宏 <luguohong@xiaomi.com>
+Closes: https://lore.kernel.org/linux-input/aI49Im0sGb6fpgc8@fedora/T/
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input.c | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 262787e6eb204..f45f856a127fe 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -609,13 +609,19 @@ static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+ return false;
+ }
+
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++ int value)
+ {
+ int capacity;
+
+ if (!dev->battery)
+ return;
+
++ if (hidinput_update_battery_charge_status(dev, usage, value)) {
++ power_supply_changed(dev->battery);
++ return;
++ }
++
+ if (value == 0 || value < dev->battery_min || value > dev->battery_max)
+ return;
+
+@@ -642,13 +648,8 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+
+-static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
+-{
+- return false;
+-}
+-
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++ int value)
+ {
+ }
+ #endif /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1515,11 +1516,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+ return;
+
+ if (usage->type == EV_PWR) {
+- bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+-
+- if (!handled)
+- hidinput_update_battery(hid, value);
+-
++ hidinput_update_battery(hid, usage->hid, value);
+ return;
+ }
+
+--
+2.50.1
+
--- /dev/null
+From f132ce581cb8a4d42085a9dba91d46ca9b0d7fc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Aug 2025 08:23:32 +0800
+Subject: HID: intel-thc-hid: Intel-quicki2c: Enhance driver re-install flow
+
+From: Even Xu <even.xu@intel.com>
+
+[ Upstream commit afa17a09c699410113199dc15256c6ea2b4133f7 ]
+
+After driver module is removed and during re-install stage, if there
+is continueous user touching on the screen, it is a risk impacting
+THC hardware initialization which causes driver installation failure.
+
+This patch enhances this flow by quiescing the external touch
+interrupt after driver is removed which keeps THC hardware
+ignore external interrupt during this remove and re-install stage.
+
+Signed-off-by: Even Xu <even.xu@intel.com>
+Tested-by: Rui Zhang <rui1.zhang@intel.com>
+Fixes: 66b59bfce6d9 ("HID: intel-thc-hid: intel-quicki2c: Complete THC QuickI2C driver")
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
+index 8a8c4a46f9270..142e5c40192ea 100644
+--- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
++++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
+@@ -406,6 +406,7 @@ static struct quicki2c_device *quicki2c_dev_init(struct pci_dev *pdev, void __io
+ */
+ static void quicki2c_dev_deinit(struct quicki2c_device *qcdev)
+ {
++ thc_interrupt_quiesce(qcdev->thc_hw, true);
+ thc_interrupt_enable(qcdev->thc_hw, false);
+ thc_ltr_unconfig(qcdev->thc_hw);
+
+--
+2.50.1
+
--- /dev/null
+From 13e9d367fbc2fc84a45b0457d3da5492ff70a1c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Aug 2025 14:57:25 +0800
+Subject: HID: intel-thc-hid: intel-quicki2c: Fix ACPI dsd ICRS/ISUB length
+
+From: Aaron Ma <aaron.ma@canonical.com>
+
+[ Upstream commit 1db9df89a213318a48d958385dc1b17b379dc32b ]
+
+The QuickI2C ACPI _DSD methods return ICRS and ISUB data with a
+trailing byte, making the actual length is one more byte than the
+structs defined.
+
+It caused stack-out-of-bounds and kernel crash:
+
+kernel: BUG: KASAN: stack-out-of-bounds in quicki2c_acpi_get_dsd_property.constprop.0+0x111/0x1b0 [intel_quicki2c]
+kernel: Write of size 12 at addr ffff888106d1f900 by task kworker/u33:2/75
+kernel:
+kernel: CPU: 3 UID: 0 PID: 75 Comm: kworker/u33:2 Not tainted 6.16.0+ #3 PREEMPT(voluntary)
+kernel: Workqueue: async async_run_entry_fn
+kernel: Call Trace:
+kernel: <TASK>
+kernel: dump_stack_lvl+0x76/0xa0
+kernel: print_report+0xd1/0x660
+kernel: ? __pfx__raw_spin_lock_irqsave+0x10/0x10
+kernel: ? __kasan_slab_free+0x5d/0x80
+kernel: ? kasan_addr_to_slab+0xd/0xb0
+kernel: kasan_report+0xe1/0x120
+kernel: ? quicki2c_acpi_get_dsd_property.constprop.0+0x111/0x1b0 [intel_quicki2c]
+kernel: ? quicki2c_acpi_get_dsd_property.constprop.0+0x111/0x1b0 [intel_quicki2c]
+kernel: kasan_check_range+0x11c/0x200
+kernel: __asan_memcpy+0x3b/0x80
+kernel: quicki2c_acpi_get_dsd_property.constprop.0+0x111/0x1b0 [intel_quicki2c]
+kernel: ? __pfx_quicki2c_acpi_get_dsd_property.constprop.0+0x10/0x10 [intel_quicki2c]
+kernel: quicki2c_get_acpi_resources+0x237/0x730 [intel_quicki2c]
+[...]
+kernel: </TASK>
+kernel:
+kernel: The buggy address belongs to stack of task kworker/u33:2/75
+kernel: and is located at offset 48 in frame:
+kernel: quicki2c_get_acpi_resources+0x0/0x730 [intel_quicki2c]
+kernel:
+kernel: This frame has 3 objects:
+kernel: [32, 36) 'hid_desc_addr'
+kernel: [48, 59) 'i2c_param'
+kernel: [80, 224) 'i2c_config'
+
+ACPI DSD methods return:
+
+\_SB.PC00.THC0.ICRS Buffer 000000003fdc947b 001 Len 0C = 0A 00 80 1A 06 00 00 00 00 00 00 00
+\_SB.PC00.THC0.ISUB Buffer 00000000f2fcbdc4 001 Len 91 = 00 00 00 00 00 00 00 00 00 00 00 00
+
+Adding reserved padding to quicki2c_subip_acpi_parameter/config.
+
+Fixes: 5282e45ccbfa9 ("HID: intel-thc-hid: intel-quicki2c: Add THC QuickI2C ACPI interfaces")
+Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
+Reviewed-by: Even Xu <even.xu@intel.com>
+Tested-by: Even Xu <even.xu@intel.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
+index 6ddb584bd6110..97085a6a7452d 100644
+--- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
++++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
+@@ -71,6 +71,7 @@ struct quicki2c_subip_acpi_parameter {
+ u16 device_address;
+ u64 connection_speed;
+ u8 addressing_mode;
++ u8 reserved;
+ } __packed;
+
+ /**
+@@ -120,6 +121,7 @@ struct quicki2c_subip_acpi_config {
+ u64 HMTD;
+ u64 HMRD;
+ u64 HMSL;
++ u8 reserved;
+ };
+
+ struct device;
+--
+2.50.1
+
--- /dev/null
+From 082e59fd3aeedb2ccd4475a4dbddb5aa8e9d27ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 3 Aug 2025 14:57:26 +0800
+Subject: HID: intel-thc-hid: intel-thc: Fix incorrect pointer arithmetic in
+ I2C regs save
+
+From: Aaron Ma <aaron.ma@canonical.com>
+
+[ Upstream commit a7fc15ed629be89e51e09b743277c53e0a0168f5 ]
+
+Improper use of secondary pointer (&dev->i2c_subip_regs) caused
+kernel crash and out-of-bounds error:
+
+ BUG: KASAN: slab-out-of-bounds in _regmap_bulk_read+0x449/0x510
+ Write of size 4 at addr ffff888136005dc0 by task kworker/u33:5/5107
+
+ CPU: 3 UID: 0 PID: 5107 Comm: kworker/u33:5 Not tainted 6.16.0+ #3 PREEMPT(voluntary)
+ Workqueue: async async_run_entry_fn
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0x76/0xa0
+ print_report+0xd1/0x660
+ ? __pfx__raw_spin_lock_irqsave+0x10/0x10
+ ? kasan_complete_mode_report_info+0x26/0x200
+ kasan_report+0xe1/0x120
+ ? _regmap_bulk_read+0x449/0x510
+ ? _regmap_bulk_read+0x449/0x510
+ __asan_report_store4_noabort+0x17/0x30
+ _regmap_bulk_read+0x449/0x510
+ ? __pfx__regmap_bulk_read+0x10/0x10
+ regmap_bulk_read+0x270/0x3d0
+ pio_complete+0x1ee/0x2c0 [intel_thc]
+ ? __pfx_pio_complete+0x10/0x10 [intel_thc]
+ ? __pfx_pio_wait+0x10/0x10 [intel_thc]
+ ? regmap_update_bits_base+0x13b/0x1f0
+ thc_i2c_subip_pio_read+0x117/0x270 [intel_thc]
+ thc_i2c_subip_regs_save+0xc2/0x140 [intel_thc]
+ ? __pfx_thc_i2c_subip_regs_save+0x10/0x10 [intel_thc]
+[...]
+ The buggy address belongs to the object at ffff888136005d00
+ which belongs to the cache kmalloc-rnd-12-192 of size 192
+ The buggy address is located 0 bytes to the right of
+ allocated 192-byte region [ffff888136005d00, ffff888136005dc0)
+
+Replaced with direct array indexing (&dev->i2c_subip_regs[i]) to ensure
+safe memory access.
+
+Fixes: 4228966def884 ("HID: intel-thc-hid: intel-thc: Add THC I2C config interfaces")
+Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
+Reviewed-by: Even Xu <even.xu@intel.com>
+Tested-by: Even Xu <even.xu@intel.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
+index c105df7f6c873..4698722e0d0a6 100644
+--- a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
++++ b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
+@@ -1539,7 +1539,7 @@ int thc_i2c_subip_regs_save(struct thc_device *dev)
+
+ for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
+ ret = thc_i2c_subip_pio_read(dev, i2c_subip_regs[i],
+- &read_size, (u32 *)&dev->i2c_subip_regs + i);
++ &read_size, &dev->i2c_subip_regs[i]);
+ if (ret < 0)
+ return ret;
+ }
+@@ -1562,7 +1562,7 @@ int thc_i2c_subip_regs_restore(struct thc_device *dev)
+
+ for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
+ ret = thc_i2c_subip_pio_write(dev, i2c_subip_regs[i],
+- write_size, (u32 *)&dev->i2c_subip_regs + i);
++ write_size, &dev->i2c_subip_regs[i]);
+ if (ret < 0)
+ return ret;
+ }
+--
+2.50.1
+
--- /dev/null
+From 7b6fe95a26cf79fc5770078e2223c940b89adb88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Jul 2025 09:57:09 -0700
+Subject: ice: don't leave device non-functional if Tx scheduler config fails
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 86aae43f21cf784c1d7f6a9af93e5116b0f232ab ]
+
+The ice_cfg_tx_topo function attempts to apply Tx scheduler topology
+configuration based on NVM parameters, selecting either a 5 or 9 layer
+topology.
+
+As part of this flow, the driver acquires the "Global Configuration Lock",
+which is a hardware resource associated with programming the DDP package
+to the device. This "lock" is implemented by firmware as a way to
+guarantee that only one PF can program the DDP for a device. Unlike a
+traditional lock, once a PF has acquired this lock, no other PF will be
+able to acquire it again (including that PF) until a CORER of the device.
+Future requests to acquire the lock report that global configuration has
+already completed.
+
+The following flow is used to program the Tx topology:
+
+ * Read the DDP package for scheduler configuration data
+ * Acquire the global configuration lock
+ * Program Tx scheduler topology according to DDP package data
+ * Trigger a CORER which clears the global configuration lock
+
+This is followed by the flow for programming the DDP package:
+
+ * Acquire the global configuration lock (again)
+ * Download the DDP package to the device
+ * Release the global configuration lock.
+
+However, if configuration of the Tx topology fails, (i.e.
+ice_get_set_tx_topo returns an error code), the driver exits
+ice_cfg_tx_topo() immediately, and fails to trigger CORER.
+
+While the global configuration lock is held, the firmware rejects most
+AdminQ commands, as it is waiting for the DDP package download (or Tx
+scheduler topology programming) to occur.
+
+The current driver flows assume that the global configuration lock has been
+reset by CORER after programming the Tx topology. Thus, the same PF
+attempts to acquire the global lock again, and fails. This results in the
+driver reporting "an unknown error occurred when loading the DDP package".
+It then attempts to enter safe mode, but ultimately fails to finish
+ice_probe() since nearly all AdminQ command report error codes, and the
+driver stops loading the device at some point during its initialization.
+
+The only currently known way that ice_get_set_tx_topo() can fail is with
+certain older DDP packages which contain invalid topology configuration, on
+firmware versions which strictly validate this data. The most recent
+releases of the DDP have resolved the invalid data. However, it is still
+poor practice to essentially brick the device, and prevent access to the
+device even through safe mode or recovery mode. It is also plausible that
+this command could fail for some other reason in the future.
+
+We cannot simply release the global lock after a failed call to
+ice_get_set_tx_topo(). Releasing the lock indicates to firmware that global
+configuration (downloading of the DDP) has completed. Future attempts by
+this or other PFs to load the DDP will fail with a report that the DDP
+package has already been downloaded. Then, PFs will enter safe mode as they
+realize that the package on the device does not meet the minimum version
+requirement to load. The reported error messages are confusing, as they
+indicate the version of the default "safe mode" package in the NVM, rather
+than the version of the file loaded from /lib/firmware.
+
+Instead, we need to trigger CORER to clear global configuration. This is
+the lowest level of hardware reset which clears the global configuration
+lock and related state. It also clears any already downloaded DDP.
+Crucially, it does *not* clear the Tx scheduler topology configuration.
+
+Refactor ice_cfg_tx_topo() to always trigger a CORER after acquiring the
+global lock, regardless of success or failure of the topology
+configuration.
+
+We need to re-initialize the HW structure when we trigger the CORER. Thus,
+it makes sense for this to be the responsibility of ice_cfg_tx_topo()
+rather than its caller, ice_init_tx_topology(). This avoids needless
+re-initialization in cases where we don't attempt to update the Tx
+scheduler topology, such as if it has already been programmed.
+
+There is one catch: failure to re-initialize the HW struct should stop
+ice_probe(). If this function fails, we won't have a valid HW structure and
+cannot ensure the device is functioning properly. To handle this, ensure
+ice_cfg_tx_topo() returns a limited set of error codes. Set aside one
+specifically, -ENODEV, to indicate that the ice_init_tx_topology() should
+fail and stop probe.
+
+Other error codes indicate failure to apply the Tx scheduler topology. This
+is treated as a non-fatal error, with an informational message informing
+the system administrator that the updated Tx topology did not apply. This
+allows the device to load and function with the default Tx scheduler
+topology, rather than failing to load entirely.
+
+Note that this use of CORER will not result in loops with future PFs
+attempting to also load the invalid Tx topology configuration. The first PF
+will acquire the global configuration lock as part of programming the DDP.
+Each PF after this will attempt to acquire the global lock as part of
+programming the Tx topology, and will fail with the indication from
+firmware that global configuration is already complete. Tx scheduler
+topology configuration is only performed during driver init (probe or
+devlink reload) and not during cleanup for a CORER that happens after probe
+completes.
+
+Fixes: 91427e6d9030 ("ice: Support 5 layer topology")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_ddp.c | 44 ++++++++++++++++-------
+ drivers/net/ethernet/intel/ice/ice_main.c | 16 ++++++---
+ 2 files changed, 43 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_ddp.c b/drivers/net/ethernet/intel/ice/ice_ddp.c
+index 351824dc3c624..1d3e1b188d22c 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ddp.c
++++ b/drivers/net/ethernet/intel/ice/ice_ddp.c
+@@ -2376,7 +2376,13 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,
+ * The function will apply the new Tx topology from the package buffer
+ * if available.
+ *
+- * Return: zero when update was successful, negative values otherwise.
++ * Return:
++ * * 0 - Successfully applied topology configuration.
++ * * -EBUSY - Failed to acquire global configuration lock.
++ * * -EEXIST - Topology configuration has already been applied.
++ * * -EIO - Unable to apply topology configuration.
++ * * -ENODEV - Failed to re-initialize device after applying configuration.
++ * * Other negative error codes indicate unexpected failures.
+ */
+ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+ {
+@@ -2409,7 +2415,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+
+ if (status) {
+ ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");
+- return status;
++ return -EIO;
+ }
+
+ /* Is default topology already applied ? */
+@@ -2496,31 +2502,45 @@ int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
+ ICE_GLOBAL_CFG_LOCK_TIMEOUT);
+ if (status) {
+ ice_debug(hw, ICE_DBG_INIT, "Failed to acquire global lock\n");
+- return status;
++ return -EBUSY;
+ }
+
+ /* Check if reset was triggered already. */
+ reg = rd32(hw, GLGEN_RSTAT);
+ if (reg & GLGEN_RSTAT_DEVSTATE_M) {
+- /* Reset is in progress, re-init the HW again */
+ ice_debug(hw, ICE_DBG_INIT, "Reset is in progress. Layer topology might be applied already\n");
+ ice_check_reset(hw);
+- return 0;
++ /* Reset is in progress, re-init the HW again */
++ goto reinit_hw;
+ }
+
+ /* Set new topology */
+ status = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true);
+ if (status) {
+- ice_debug(hw, ICE_DBG_INIT, "Failed setting Tx topology\n");
+- return status;
++ ice_debug(hw, ICE_DBG_INIT, "Failed to set Tx topology, status %pe\n",
++ ERR_PTR(status));
++ /* only report -EIO here as the caller checks the error value
++ * and reports an informational error message informing that
++ * the driver failed to program Tx topology.
++ */
++ status = -EIO;
+ }
+
+- /* New topology is updated, delay 1 second before issuing the CORER */
++ /* Even if Tx topology config failed, we need to CORE reset here to
++ * clear the global configuration lock. Delay 1 second to allow
++ * hardware to settle then issue a CORER
++ */
+ msleep(1000);
+ ice_reset(hw, ICE_RESET_CORER);
+- /* CORER will clear the global lock, so no explicit call
+- * required for release.
+- */
++ ice_check_reset(hw);
++
++reinit_hw:
++ /* Since we triggered a CORER, re-initialize hardware */
++ ice_deinit_hw(hw);
++ if (ice_init_hw(hw)) {
++ ice_debug(hw, ICE_DBG_INIT, "Failed to re-init hardware after setting Tx topology\n");
++ return -ENODEV;
++ }
+
+- return 0;
++ return status;
+ }
+diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
+index 0a11b4281092e..d42892c8c5a12 100644
+--- a/drivers/net/ethernet/intel/ice/ice_main.c
++++ b/drivers/net/ethernet/intel/ice/ice_main.c
+@@ -4532,17 +4532,23 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware)
+ dev_info(dev, "Tx scheduling layers switching feature disabled\n");
+ else
+ dev_info(dev, "Tx scheduling layers switching feature enabled\n");
+- /* if there was a change in topology ice_cfg_tx_topo triggered
+- * a CORER and we need to re-init hw
++ return 0;
++ } else if (err == -ENODEV) {
++ /* If we failed to re-initialize the device, we can no longer
++ * continue loading.
+ */
+- ice_deinit_hw(hw);
+- err = ice_init_hw(hw);
+-
++ dev_warn(dev, "Failed to initialize hardware after applying Tx scheduling configuration.\n");
+ return err;
+ } else if (err == -EIO) {
+ dev_info(dev, "DDP package does not support Tx scheduling layers switching feature - please update to the latest DDP package and try again\n");
++ return 0;
++ } else if (err == -EEXIST) {
++ return 0;
+ }
+
++ /* Do not treat this as a fatal error. */
++ dev_info(dev, "Failed to apply Tx scheduling configuration, err %pe\n",
++ ERR_PTR(err));
+ return 0;
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 5dc4ef77970f0bf5bdd95ce69e795fb29e76a9bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Aug 2025 17:53:10 +0200
+Subject: ice: fix incorrect counter for buffer allocation failures
+
+From: Michal Kubiak <michal.kubiak@intel.com>
+
+[ Upstream commit b1a0c977c6f1130f7dd125ee3db8c2435d7e3d41 ]
+
+Currently, the driver increments `alloc_page_failed` when buffer allocation fails
+in `ice_clean_rx_irq()`. However, this counter is intended for page allocation
+failures, not buffer allocation issues.
+
+This patch corrects the counter by incrementing `alloc_buf_failed` instead,
+ensuring accurate statistics reporting for buffer allocation failures.
+
+Fixes: 2fba7dc5157b ("ice: Add support for XDP multi-buffer on Rx side")
+Reported-by: Jacob Keller <jacob.e.keller@intel.com>
+Suggested-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Priya Singh <priyax.singh@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index 0e5107fe62ad5..c50cf3ad190e9 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -1295,7 +1295,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ skb = ice_construct_skb(rx_ring, xdp);
+ /* exit if we failed to retrieve a buffer */
+ if (!skb) {
+- rx_ring->ring_stats->rx_stats.alloc_page_failed++;
++ rx_ring->ring_stats->rx_stats.alloc_buf_failed++;
+ xdp_verdict = ICE_XDP_CONSUMED;
+ }
+ ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+--
+2.50.1
+
--- /dev/null
+From d76a3425c637dceb622a9a7e458ba6d762b395e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 24 Jun 2025 07:26:40 -0700
+Subject: ice: fix NULL pointer dereference in ice_unplug_aux_dev() on reset
+
+From: Emil Tantilov <emil.s.tantilov@intel.com>
+
+[ Upstream commit 60dfe2434eed13082f26eb7409665dfafb38fa51 ]
+
+Issuing a reset when the driver is loaded without RDMA support, will
+results in a crash as it attempts to remove RDMA's non-existent auxbus
+device:
+echo 1 > /sys/class/net/<if>/device/reset
+
+BUG: kernel NULL pointer dereference, address: 0000000000000008
+...
+RIP: 0010:ice_unplug_aux_dev+0x29/0x70 [ice]
+...
+Call Trace:
+<TASK>
+ice_prepare_for_reset+0x77/0x260 [ice]
+pci_dev_save_and_disable+0x2c/0x70
+pci_reset_function+0x88/0x130
+reset_store+0x5a/0xa0
+kernfs_fop_write_iter+0x15e/0x210
+vfs_write+0x273/0x520
+ksys_write+0x6b/0xe0
+do_syscall_64+0x79/0x3b0
+entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+ice_unplug_aux_dev() checks pf->cdev_info->adev for NULL pointer, but
+pf->cdev_info will also be NULL, leading to the deref in the trace above.
+
+Introduce a flag to be set when the creation of the auxbus device is
+successful, to avoid multiple NULL pointer checks in ice_unplug_aux_dev().
+
+Fixes: c24a65b6a27c7 ("iidc/ice/irdma: Update IDC to support multiple consumers")
+Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice.h | 1 +
+ drivers/net/ethernet/intel/ice/ice_idc.c | 10 ++++++----
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
+index ddd0ad68185b4..0ef11b7ab477e 100644
+--- a/drivers/net/ethernet/intel/ice/ice.h
++++ b/drivers/net/ethernet/intel/ice/ice.h
+@@ -509,6 +509,7 @@ enum ice_pf_flags {
+ ICE_FLAG_LINK_LENIENT_MODE_ENA,
+ ICE_FLAG_PLUG_AUX_DEV,
+ ICE_FLAG_UNPLUG_AUX_DEV,
++ ICE_FLAG_AUX_DEV_CREATED,
+ ICE_FLAG_MTU_CHANGED,
+ ICE_FLAG_GNSS, /* GNSS successfully initialized */
+ ICE_FLAG_DPLL, /* SyncE/PTP dplls initialized */
+diff --git a/drivers/net/ethernet/intel/ice/ice_idc.c b/drivers/net/ethernet/intel/ice/ice_idc.c
+index 6ab53e430f912..420d45c2558b6 100644
+--- a/drivers/net/ethernet/intel/ice/ice_idc.c
++++ b/drivers/net/ethernet/intel/ice/ice_idc.c
+@@ -336,6 +336,7 @@ int ice_plug_aux_dev(struct ice_pf *pf)
+ mutex_lock(&pf->adev_mutex);
+ cdev->adev = adev;
+ mutex_unlock(&pf->adev_mutex);
++ set_bit(ICE_FLAG_AUX_DEV_CREATED, pf->flags);
+
+ return 0;
+ }
+@@ -347,15 +348,16 @@ void ice_unplug_aux_dev(struct ice_pf *pf)
+ {
+ struct auxiliary_device *adev;
+
++ if (!test_and_clear_bit(ICE_FLAG_AUX_DEV_CREATED, pf->flags))
++ return;
++
+ mutex_lock(&pf->adev_mutex);
+ adev = pf->cdev_info->adev;
+ pf->cdev_info->adev = NULL;
+ mutex_unlock(&pf->adev_mutex);
+
+- if (adev) {
+- auxiliary_device_delete(adev);
+- auxiliary_device_uninit(adev);
+- }
++ auxiliary_device_delete(adev);
++ auxiliary_device_uninit(adev);
+ }
+
+ /**
+--
+2.50.1
+
--- /dev/null
+From bf4e8ccd3b905cfc321b00fa297589c80e071d1c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Aug 2025 15:27:12 -0700
+Subject: ice: use fixed adapter index for E825C embedded devices
+
+From: Jacob Keller <jacob.e.keller@intel.com>
+
+[ Upstream commit 5c5e5b52bf05c7fe88768318c041052c5fac36b8 ]
+
+The ice_adapter structure is used by the ice driver to connect multiple
+physical functions of a device in software. It was introduced by
+commit 0e2bddf9e5f9 ("ice: add ice_adapter for shared data across PFs on
+the same NIC") and is primarily used for PTP support, as well as for
+handling certain cross-PF synchronization.
+
+The original design of ice_adapter used PCI address information to
+determine which devices should be connected. This was extended to support
+E825C devices by commit fdb7f54700b1 ("ice: Initial support for E825C
+hardware in ice_adapter"), which used the device ID for E825C devices
+instead of the PCI address.
+
+Later, commit 0093cb194a75 ("ice: use DSN instead of PCI BDF for
+ice_adapter index") replaced the use of Bus/Device/Function addressing with
+use of the device serial number.
+
+E825C devices may appear in "Dual NAC" configuration which has multiple
+physical devices tied to the same clock source and which need to use the
+same ice_adapter. Unfortunately, each "NAC" has its own NVM which has its
+own unique Device Serial Number. Thus, use of the DSN for connecting
+ice_adapter does not work properly. It "worked" in the pre-production
+systems because the DSN was not initialized on the test NVMs and all the
+NACs had the same zero'd serial number.
+
+Since we cannot rely on the DSN, lets fall back to the logic in the
+original E825C support which used the device ID. This is safe for E825C
+only because of the embedded nature of the device. It isn't a discreet
+adapter that can be plugged into an arbitrary system. All E825C devices on
+a given system are connected to the same clock source and need to be
+configured through the same PTP clock.
+
+To make this separation clear, reserve bit 63 of the 64-bit index values as
+a "fixed index" indicator. Always clear this bit when using the device
+serial number as an index.
+
+For E825C, use a fixed value defined as the 0x579C E825C backplane device
+ID bitwise ORed with the fixed index indicator. This is slightly different
+than the original logic of just using the device ID directly. Doing so
+prevents a potential issue with systems where only one of the NACs is
+connected with an external PHY over SGMII. In that case, one NAC would
+have the E825C_SGMII device ID, but the other would not.
+
+Separate the determination of the full 64-bit index from the 32-bit
+reduction logic. Provide both ice_adapter_index() and a wrapping
+ice_adapter_xa_index() which handles reducing the index to a long on 32-bit
+systems. As before, cache the full index value in the adapter structure to
+warn about collisions.
+
+This fixes issues with E825C not initializing PTP on both NACs, due to
+failure to connect the appropriate devices to the same ice_adapter.
+
+Fixes: 0093cb194a75 ("ice: use DSN instead of PCI BDF for ice_adapter index")
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_adapter.c | 49 +++++++++++++++-----
+ drivers/net/ethernet/intel/ice/ice_adapter.h | 4 +-
+ 2 files changed, 40 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.c b/drivers/net/ethernet/intel/ice/ice_adapter.c
+index 66e070095d1bb..10285995c9edd 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.c
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.c
+@@ -13,16 +13,45 @@
+ static DEFINE_XARRAY(ice_adapters);
+ static DEFINE_MUTEX(ice_adapters_mutex);
+
+-static unsigned long ice_adapter_index(u64 dsn)
++#define ICE_ADAPTER_FIXED_INDEX BIT_ULL(63)
++
++#define ICE_ADAPTER_INDEX_E825C \
++ (ICE_DEV_ID_E825C_BACKPLANE | ICE_ADAPTER_FIXED_INDEX)
++
++static u64 ice_adapter_index(struct pci_dev *pdev)
+ {
++ switch (pdev->device) {
++ case ICE_DEV_ID_E825C_BACKPLANE:
++ case ICE_DEV_ID_E825C_QSFP:
++ case ICE_DEV_ID_E825C_SFP:
++ case ICE_DEV_ID_E825C_SGMII:
++ /* E825C devices have multiple NACs which are connected to the
++ * same clock source, and which must share the same
++ * ice_adapter structure. We can't use the serial number since
++ * each NAC has its own NVM generated with its own unique
++ * Device Serial Number. Instead, rely on the embedded nature
++ * of the E825C devices, and use a fixed index. This relies on
++ * the fact that all E825C physical functions in a given
++ * system are part of the same overall device.
++ */
++ return ICE_ADAPTER_INDEX_E825C;
++ default:
++ return pci_get_dsn(pdev) & ~ICE_ADAPTER_FIXED_INDEX;
++ }
++}
++
++static unsigned long ice_adapter_xa_index(struct pci_dev *pdev)
++{
++ u64 index = ice_adapter_index(pdev);
++
+ #if BITS_PER_LONG == 64
+- return dsn;
++ return index;
+ #else
+- return (u32)dsn ^ (u32)(dsn >> 32);
++ return (u32)index ^ (u32)(index >> 32);
+ #endif
+ }
+
+-static struct ice_adapter *ice_adapter_new(u64 dsn)
++static struct ice_adapter *ice_adapter_new(struct pci_dev *pdev)
+ {
+ struct ice_adapter *adapter;
+
+@@ -30,7 +59,7 @@ static struct ice_adapter *ice_adapter_new(u64 dsn)
+ if (!adapter)
+ return NULL;
+
+- adapter->device_serial_number = dsn;
++ adapter->index = ice_adapter_index(pdev);
+ spin_lock_init(&adapter->ptp_gltsyn_time_lock);
+ refcount_set(&adapter->refcount, 1);
+
+@@ -63,24 +92,23 @@ static void ice_adapter_free(struct ice_adapter *adapter)
+ */
+ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
+ {
+- u64 dsn = pci_get_dsn(pdev);
+ struct ice_adapter *adapter;
+ unsigned long index;
+ int err;
+
+- index = ice_adapter_index(dsn);
++ index = ice_adapter_xa_index(pdev);
+ scoped_guard(mutex, &ice_adapters_mutex) {
+ err = xa_insert(&ice_adapters, index, NULL, GFP_KERNEL);
+ if (err == -EBUSY) {
+ adapter = xa_load(&ice_adapters, index);
+ refcount_inc(&adapter->refcount);
+- WARN_ON_ONCE(adapter->device_serial_number != dsn);
++ WARN_ON_ONCE(adapter->index != ice_adapter_index(pdev));
+ return adapter;
+ }
+ if (err)
+ return ERR_PTR(err);
+
+- adapter = ice_adapter_new(dsn);
++ adapter = ice_adapter_new(pdev);
+ if (!adapter)
+ return ERR_PTR(-ENOMEM);
+ xa_store(&ice_adapters, index, adapter, GFP_KERNEL);
+@@ -99,11 +127,10 @@ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev)
+ */
+ void ice_adapter_put(struct pci_dev *pdev)
+ {
+- u64 dsn = pci_get_dsn(pdev);
+ struct ice_adapter *adapter;
+ unsigned long index;
+
+- index = ice_adapter_index(dsn);
++ index = ice_adapter_xa_index(pdev);
+ scoped_guard(mutex, &ice_adapters_mutex) {
+ adapter = xa_load(&ice_adapters, index);
+ if (WARN_ON(!adapter))
+diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.h b/drivers/net/ethernet/intel/ice/ice_adapter.h
+index ac15c0d2bc1a4..409467847c753 100644
+--- a/drivers/net/ethernet/intel/ice/ice_adapter.h
++++ b/drivers/net/ethernet/intel/ice/ice_adapter.h
+@@ -32,7 +32,7 @@ struct ice_port_list {
+ * @refcount: Reference count. struct ice_pf objects hold the references.
+ * @ctrl_pf: Control PF of the adapter
+ * @ports: Ports list
+- * @device_serial_number: DSN cached for collision detection on 32bit systems
++ * @index: 64-bit index cached for collision detection on 32bit systems
+ */
+ struct ice_adapter {
+ refcount_t refcount;
+@@ -41,7 +41,7 @@ struct ice_adapter {
+
+ struct ice_pf *ctrl_pf;
+ struct ice_port_list ports;
+- u64 device_serial_number;
++ u64 index;
+ };
+
+ struct ice_adapter *ice_adapter_get(struct pci_dev *pdev);
+--
+2.50.1
+
--- /dev/null
+From cf3ac9bc83ae584e60d711360dba3efd7ed75909 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jul 2025 11:42:18 -0700
+Subject: idpf: add support for Tx refillqs in flow scheduling mode
+
+From: Joshua Hay <joshua.a.hay@intel.com>
+
+[ Upstream commit cb83b559bea39f207ee214ee2972657e8576ed18 ]
+
+In certain production environments, it is possible for completion tags
+to collide, meaning N packets with the same completion tag are in flight
+at the same time. In this environment, any given Tx queue is effectively
+used to send both slower traffic and higher throughput traffic
+simultaneously. This is the result of a customer's specific
+configuration in the device pipeline, the details of which Intel cannot
+provide. This configuration results in a small number of out-of-order
+completions, i.e., a small number of packets in flight. The existing
+guardrails in the driver only protect against a large number of packets
+in flight. The slower flow completions are delayed which causes the
+out-of-order completions. The fast flow will continue sending traffic
+and generating tags. Because tags are generated on the fly, the fast
+flow eventually uses the same tag for a packet that is still in flight
+from the slower flow. The driver has no idea which packet it should
+clean when it processes the completion with that tag, but it will look
+for the packet on the buffer ring before the hash table. If the slower
+flow packet completion is processed first, it will end up cleaning the
+fast flow packet on the ring prematurely. This leaves the descriptor
+ring in a bad state resulting in a crash or Tx timeout.
+
+In summary, generating a tag when a packet is sent can lead to the same
+tag being associated with multiple packets. This can lead to resource
+leaks, crashes, and/or Tx timeouts.
+
+Before we can replace the tag generation, we need a new mechanism for
+the send path to know what tag to use next. The driver will allocate and
+initialize a refillq for each TxQ with all of the possible free tag
+values. During send, the driver grabs the next free tag from the refillq
+from next_to_clean. While cleaning the packet, the clean routine posts
+the tag back to the refillq's next_to_use to indicate that it is now
+free to use.
+
+This mechanism works exactly the same way as the existing Rx refill
+queues, which post the cleaned buffer IDs back to the buffer queue to be
+reposted to HW. Since we're using the refillqs for both Rx and Tx now,
+genericize some of the existing refillq support.
+
+Note: the refillqs will not be used yet. This is only demonstrating how
+they will be used to pass free tags back to the send path.
+
+Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
+Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: b61dfa9bc443 ("idpf: simplify and fix splitq Tx packet rollback error path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf_txrx.c | 93 +++++++++++++++++++--
+ drivers/net/ethernet/intel/idpf/idpf_txrx.h | 8 +-
+ 2 files changed, 91 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+index 89185d1b8485e..b26d054013354 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+@@ -139,6 +139,9 @@ static void idpf_tx_desc_rel(struct idpf_tx_queue *txq)
+ if (!txq->desc_ring)
+ return;
+
++ if (txq->refillq)
++ kfree(txq->refillq->ring);
++
+ dmam_free_coherent(txq->dev, txq->size, txq->desc_ring, txq->dma);
+ txq->desc_ring = NULL;
+ txq->next_to_use = 0;
+@@ -244,6 +247,7 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
+ struct idpf_tx_queue *tx_q)
+ {
+ struct device *dev = tx_q->dev;
++ struct idpf_sw_queue *refillq;
+ int err;
+
+ err = idpf_tx_buf_alloc_all(tx_q);
+@@ -267,6 +271,29 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
+ tx_q->next_to_clean = 0;
+ idpf_queue_set(GEN_CHK, tx_q);
+
++ if (!idpf_queue_has(FLOW_SCH_EN, tx_q))
++ return 0;
++
++ refillq = tx_q->refillq;
++ refillq->desc_count = tx_q->desc_count;
++ refillq->ring = kcalloc(refillq->desc_count, sizeof(u32),
++ GFP_KERNEL);
++ if (!refillq->ring) {
++ err = -ENOMEM;
++ goto err_alloc;
++ }
++
++ for (unsigned int i = 0; i < refillq->desc_count; i++)
++ refillq->ring[i] =
++ FIELD_PREP(IDPF_RFL_BI_BUFID_M, i) |
++ FIELD_PREP(IDPF_RFL_BI_GEN_M,
++ idpf_queue_has(GEN_CHK, refillq));
++
++ /* Go ahead and flip the GEN bit since this counts as filling
++ * up the ring, i.e. we already ring wrapped.
++ */
++ idpf_queue_change(GEN_CHK, refillq);
++
+ return 0;
+
+ err_alloc:
+@@ -603,18 +630,18 @@ static int idpf_rx_hdr_buf_alloc_all(struct idpf_buf_queue *bufq)
+ }
+
+ /**
+- * idpf_rx_post_buf_refill - Post buffer id to refill queue
++ * idpf_post_buf_refill - Post buffer id to refill queue
+ * @refillq: refill queue to post to
+ * @buf_id: buffer id to post
+ */
+-static void idpf_rx_post_buf_refill(struct idpf_sw_queue *refillq, u16 buf_id)
++static void idpf_post_buf_refill(struct idpf_sw_queue *refillq, u16 buf_id)
+ {
+ u32 nta = refillq->next_to_use;
+
+ /* store the buffer ID and the SW maintained GEN bit to the refillq */
+ refillq->ring[nta] =
+- FIELD_PREP(IDPF_RX_BI_BUFID_M, buf_id) |
+- FIELD_PREP(IDPF_RX_BI_GEN_M,
++ FIELD_PREP(IDPF_RFL_BI_BUFID_M, buf_id) |
++ FIELD_PREP(IDPF_RFL_BI_GEN_M,
+ idpf_queue_has(GEN_CHK, refillq));
+
+ if (unlikely(++nta == refillq->desc_count)) {
+@@ -995,6 +1022,11 @@ static void idpf_txq_group_rel(struct idpf_vport *vport)
+ struct idpf_txq_group *txq_grp = &vport->txq_grps[i];
+
+ for (j = 0; j < txq_grp->num_txq; j++) {
++ if (flow_sch_en) {
++ kfree(txq_grp->txqs[j]->refillq);
++ txq_grp->txqs[j]->refillq = NULL;
++ }
++
+ kfree(txq_grp->txqs[j]);
+ txq_grp->txqs[j] = NULL;
+ }
+@@ -1414,6 +1446,13 @@ static int idpf_txq_group_alloc(struct idpf_vport *vport, u16 num_txq)
+ }
+
+ idpf_queue_set(FLOW_SCH_EN, q);
++
++ q->refillq = kzalloc(sizeof(*q->refillq), GFP_KERNEL);
++ if (!q->refillq)
++ goto err_alloc;
++
++ idpf_queue_set(GEN_CHK, q->refillq);
++ idpf_queue_set(RFL_GEN_CHK, q->refillq);
+ }
+
+ if (!split)
+@@ -2005,6 +2044,8 @@ static void idpf_tx_handle_rs_completion(struct idpf_tx_queue *txq,
+
+ compl_tag = le16_to_cpu(desc->q_head_compl_tag.compl_tag);
+
++ idpf_post_buf_refill(txq->refillq, compl_tag);
++
+ /* If we didn't clean anything on the ring, this packet must be
+ * in the hash table. Go clean it there.
+ */
+@@ -2364,6 +2405,37 @@ static unsigned int idpf_tx_splitq_bump_ntu(struct idpf_tx_queue *txq, u16 ntu)
+ return ntu;
+ }
+
++/**
++ * idpf_tx_get_free_buf_id - get a free buffer ID from the refill queue
++ * @refillq: refill queue to get buffer ID from
++ * @buf_id: return buffer ID
++ *
++ * Return: true if a buffer ID was found, false if not
++ */
++static bool idpf_tx_get_free_buf_id(struct idpf_sw_queue *refillq,
++ u16 *buf_id)
++{
++ u32 ntc = refillq->next_to_clean;
++ u32 refill_desc;
++
++ refill_desc = refillq->ring[ntc];
++
++ if (unlikely(idpf_queue_has(RFL_GEN_CHK, refillq) !=
++ !!(refill_desc & IDPF_RFL_BI_GEN_M)))
++ return false;
++
++ *buf_id = FIELD_GET(IDPF_RFL_BI_BUFID_M, refill_desc);
++
++ if (unlikely(++ntc == refillq->desc_count)) {
++ idpf_queue_change(RFL_GEN_CHK, refillq);
++ ntc = 0;
++ }
++
++ refillq->next_to_clean = ntc;
++
++ return true;
++}
++
+ /**
+ * idpf_tx_splitq_map - Build the Tx flex descriptor
+ * @tx_q: queue to send buffer on
+@@ -2912,6 +2984,13 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+ }
+
+ if (idpf_queue_has(FLOW_SCH_EN, tx_q)) {
++ if (unlikely(!idpf_tx_get_free_buf_id(tx_q->refillq,
++ &tx_params.compl_tag))) {
++ u64_stats_update_begin(&tx_q->stats_sync);
++ u64_stats_inc(&tx_q->q_stats.q_busy);
++ u64_stats_update_end(&tx_q->stats_sync);
++ }
++
+ tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_FLOW_SCHE;
+ tx_params.eop_cmd = IDPF_TXD_FLEX_FLOW_CMD_EOP;
+ /* Set the RE bit to catch any packets that may have not been
+@@ -3464,7 +3543,7 @@ static int idpf_rx_splitq_clean(struct idpf_rx_queue *rxq, int budget)
+ skip_data:
+ rx_buf->page = NULL;
+
+- idpf_rx_post_buf_refill(refillq, buf_id);
++ idpf_post_buf_refill(refillq, buf_id);
+ IDPF_RX_BUMP_NTC(rxq, ntc);
+
+ /* skip if it is non EOP desc */
+@@ -3572,10 +3651,10 @@ static void idpf_rx_clean_refillq(struct idpf_buf_queue *bufq,
+ bool failure;
+
+ if (idpf_queue_has(RFL_GEN_CHK, refillq) !=
+- !!(refill_desc & IDPF_RX_BI_GEN_M))
++ !!(refill_desc & IDPF_RFL_BI_GEN_M))
+ break;
+
+- buf_id = FIELD_GET(IDPF_RX_BI_BUFID_M, refill_desc);
++ buf_id = FIELD_GET(IDPF_RFL_BI_BUFID_M, refill_desc);
+ failure = idpf_rx_update_bufq_desc(bufq, buf_id, buf_desc);
+ if (failure)
+ break;
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+index 36a0f828a6f80..6924bee6ff5bd 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+@@ -107,8 +107,8 @@ do { \
+ */
+ #define IDPF_TX_SPLITQ_RE_MIN_GAP 64
+
+-#define IDPF_RX_BI_GEN_M BIT(16)
+-#define IDPF_RX_BI_BUFID_M GENMASK(15, 0)
++#define IDPF_RFL_BI_GEN_M BIT(16)
++#define IDPF_RFL_BI_BUFID_M GENMASK(15, 0)
+
+ #define IDPF_RXD_EOF_SPLITQ VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_EOF_M
+ #define IDPF_RXD_EOF_SINGLEQ VIRTCHNL2_RX_BASE_DESC_STATUS_EOF_M
+@@ -621,6 +621,7 @@ libeth_cacheline_set_assert(struct idpf_rx_queue, 64,
+ * @cleaned_pkts: Number of packets cleaned for the above said case
+ * @tx_max_bufs: Max buffers that can be transmitted with scatter-gather
+ * @stash: Tx buffer stash for Flow-based scheduling mode
++ * @refillq: Pointer to refill queue
+ * @compl_tag_bufid_m: Completion tag buffer id mask
+ * @compl_tag_cur_gen: Used to keep track of current completion tag generation
+ * @compl_tag_gen_max: To determine when compl_tag_cur_gen should be reset
+@@ -670,6 +671,7 @@ struct idpf_tx_queue {
+
+ u16 tx_max_bufs;
+ struct idpf_txq_stash *stash;
++ struct idpf_sw_queue *refillq;
+
+ u16 compl_tag_bufid_m;
+ u16 compl_tag_cur_gen;
+@@ -691,7 +693,7 @@ struct idpf_tx_queue {
+ __cacheline_group_end_aligned(cold);
+ };
+ libeth_cacheline_set_assert(struct idpf_tx_queue, 64,
+- 112 + sizeof(struct u64_stats_sync),
++ 120 + sizeof(struct u64_stats_sync),
+ 24);
+
+ /**
+--
+2.50.1
+
--- /dev/null
+From a7154cdd667ee1957f44f24f1f88e5da13a9c495 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jul 2025 11:42:21 -0700
+Subject: idpf: replace flow scheduling buffer ring with buffer pool
+
+From: Joshua Hay <joshua.a.hay@intel.com>
+
+[ Upstream commit 5f417d551324d2894168b362f2429d120ab06243 ]
+
+Replace the TxQ buffer ring with one large pool/array of buffers (only
+for flow scheduling). This eliminates the tag generation and makes it
+impossible for a tag to be associated with more than one packet.
+
+The completion tag passed to HW through the descriptor is the index into
+the array. That same completion tag is posted back to the driver in the
+completion descriptor, and used to index into the array to quickly
+retrieve the buffer during cleaning. In this way, the tags are treated
+as a fix sized resource. If all tags are in use, no more packets can be
+sent on that particular queue (until some are freed up). The tag pool
+size is 64K since the completion tag width is 16 bits.
+
+For each packet, the driver pulls a free tag from the refillq to get the
+next free buffer index. When cleaning is complete, the tag is posted
+back to the refillq. A multi-frag packet spans multiple buffers in the
+driver, therefore it uses multiple buffer indexes/tags from the pool.
+Each frag pulls from the refillq to get the next free buffer index.
+These are tracked in a next_buf field that replaces the completion tag
+field in the buffer struct. This chains the buffers together so that the
+packet can be cleaned from the starting completion tag taken from the
+completion descriptor, then from the next_buf field for each subsequent
+buffer.
+
+In case of a dma_mapping_error occurs or the refillq runs out of free
+buf_ids, the packet will execute the rollback error path. This unmaps
+any buffers previously mapped for the packet. Since several free
+buf_ids could have already been pulled from the refillq, we need to
+restore its original state as well. Otherwise, the buf_ids/tags
+will be leaked and not used again until the queue is reallocated.
+
+Descriptor completions only advance the descriptor ring index to "clean"
+the descriptors. The packet completions only clean the buffers
+associated with the given packet completion tag and do not update the
+descriptor ring index.
+
+When operating in queue based scheduling mode, the array still acts as a
+ring and will only have TxQ descriptor count entries. The tx_bufs are
+still associated 1:1 with the descriptor ring entries and we can use the
+conventional indexing mechanisms.
+
+Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
+Signed-off-by: Luigi Rizzo <lrizzo@google.com>
+Signed-off-by: Brian Vazquez <brianvv@google.com>
+Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
+Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/idpf/idpf_txrx.c | 204 +++++++++-----------
+ drivers/net/ethernet/intel/idpf/idpf_txrx.h | 10 +-
+ 2 files changed, 103 insertions(+), 111 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+index 7c758e7281ab5..89fedc2ef247b 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+@@ -13,6 +13,7 @@ struct idpf_tx_stash {
+ struct libeth_sqe buf;
+ };
+
++#define idpf_tx_buf_next(buf) (*(u32 *)&(buf)->priv)
+ #define idpf_tx_buf_compl_tag(buf) (*(u32 *)&(buf)->priv)
+ LIBETH_SQE_CHECK_PRIV(u32);
+
+@@ -91,7 +92,7 @@ static void idpf_tx_buf_rel_all(struct idpf_tx_queue *txq)
+ return;
+
+ /* Free all the Tx buffer sk_buffs */
+- for (i = 0; i < txq->desc_count; i++)
++ for (i = 0; i < txq->buf_pool_size; i++)
+ libeth_tx_complete(&txq->tx_buf[i], &cp);
+
+ kfree(txq->tx_buf);
+@@ -199,14 +200,17 @@ static void idpf_tx_desc_rel_all(struct idpf_vport *vport)
+ static int idpf_tx_buf_alloc_all(struct idpf_tx_queue *tx_q)
+ {
+ struct idpf_buf_lifo *buf_stack;
+- int buf_size;
+ int i;
+
+ /* Allocate book keeping buffers only. Buffers to be supplied to HW
+ * are allocated by kernel network stack and received as part of skb
+ */
+- buf_size = sizeof(struct idpf_tx_buf) * tx_q->desc_count;
+- tx_q->tx_buf = kzalloc(buf_size, GFP_KERNEL);
++ if (idpf_queue_has(FLOW_SCH_EN, tx_q))
++ tx_q->buf_pool_size = U16_MAX;
++ else
++ tx_q->buf_pool_size = tx_q->desc_count;
++ tx_q->tx_buf = kcalloc(tx_q->buf_pool_size, sizeof(*tx_q->tx_buf),
++ GFP_KERNEL);
+ if (!tx_q->tx_buf)
+ return -ENOMEM;
+
+@@ -275,7 +279,7 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
+ return 0;
+
+ refillq = tx_q->refillq;
+- refillq->desc_count = tx_q->desc_count;
++ refillq->desc_count = tx_q->buf_pool_size;
+ refillq->ring = kcalloc(refillq->desc_count, sizeof(u32),
+ GFP_KERNEL);
+ if (!refillq->ring) {
+@@ -1867,6 +1871,12 @@ static bool idpf_tx_splitq_clean(struct idpf_tx_queue *tx_q, u16 end,
+ struct idpf_tx_buf *tx_buf;
+ bool clean_complete = true;
+
++ if (descs_only) {
++ /* Bump ring index to mark as cleaned. */
++ tx_q->next_to_clean = end;
++ return true;
++ }
++
+ tx_desc = &tx_q->flex_tx[ntc];
+ next_pending_desc = &tx_q->flex_tx[end];
+ tx_buf = &tx_q->tx_buf[ntc];
+@@ -1933,87 +1943,43 @@ do { \
+ } while (0)
+
+ /**
+- * idpf_tx_clean_buf_ring - clean flow scheduling TX queue buffers
++ * idpf_tx_clean_bufs - clean flow scheduling TX queue buffers
+ * @txq: queue to clean
+- * @compl_tag: completion tag of packet to clean (from completion descriptor)
++ * @buf_id: packet's starting buffer ID, from completion descriptor
+ * @cleaned: pointer to stats struct to track cleaned packets/bytes
+ * @budget: Used to determine if we are in netpoll
+ *
+- * Cleans all buffers associated with the input completion tag either from the
+- * TX buffer ring or from the hash table if the buffers were previously
+- * stashed. Returns the byte/segment count for the cleaned packet associated
+- * this completion tag.
++ * Clean all buffers associated with the packet starting at buf_id. Returns the
++ * byte/segment count for the cleaned packet.
+ */
+-static bool idpf_tx_clean_buf_ring(struct idpf_tx_queue *txq, u16 compl_tag,
+- struct libeth_sq_napi_stats *cleaned,
+- int budget)
++static bool idpf_tx_clean_bufs(struct idpf_tx_queue *txq, u32 buf_id,
++ struct libeth_sq_napi_stats *cleaned,
++ int budget)
+ {
+- u16 idx = compl_tag & txq->compl_tag_bufid_m;
+ struct idpf_tx_buf *tx_buf = NULL;
+ struct libeth_cq_pp cp = {
+ .dev = txq->dev,
+ .ss = cleaned,
+ .napi = budget,
+ };
+- u16 ntc, orig_idx = idx;
+-
+- tx_buf = &txq->tx_buf[idx];
+-
+- if (unlikely(tx_buf->type <= LIBETH_SQE_CTX ||
+- idpf_tx_buf_compl_tag(tx_buf) != compl_tag))
+- return false;
+
++ tx_buf = &txq->tx_buf[buf_id];
+ if (tx_buf->type == LIBETH_SQE_SKB) {
+ if (skb_shinfo(tx_buf->skb)->tx_flags & SKBTX_IN_PROGRESS)
+ idpf_tx_read_tstamp(txq, tx_buf->skb);
+
+ libeth_tx_complete(tx_buf, &cp);
++ idpf_post_buf_refill(txq->refillq, buf_id);
+ }
+
+- idpf_tx_clean_buf_ring_bump_ntc(txq, idx, tx_buf);
++ while (idpf_tx_buf_next(tx_buf) != IDPF_TXBUF_NULL) {
++ buf_id = idpf_tx_buf_next(tx_buf);
+
+- while (idpf_tx_buf_compl_tag(tx_buf) == compl_tag) {
++ tx_buf = &txq->tx_buf[buf_id];
+ libeth_tx_complete(tx_buf, &cp);
+- idpf_tx_clean_buf_ring_bump_ntc(txq, idx, tx_buf);
++ idpf_post_buf_refill(txq->refillq, buf_id);
+ }
+
+- /*
+- * It's possible the packet we just cleaned was an out of order
+- * completion, which means we can stash the buffers starting from
+- * the original next_to_clean and reuse the descriptors. We need
+- * to compare the descriptor ring next_to_clean packet's "first" buffer
+- * to the "first" buffer of the packet we just cleaned to determine if
+- * this is the case. Howevever, next_to_clean can point to either a
+- * reserved buffer that corresponds to a context descriptor used for the
+- * next_to_clean packet (TSO packet) or the "first" buffer (single
+- * packet). The orig_idx from the packet we just cleaned will always
+- * point to the "first" buffer. If next_to_clean points to a reserved
+- * buffer, let's bump ntc once and start the comparison from there.
+- */
+- ntc = txq->next_to_clean;
+- tx_buf = &txq->tx_buf[ntc];
+-
+- if (tx_buf->type == LIBETH_SQE_CTX)
+- idpf_tx_clean_buf_ring_bump_ntc(txq, ntc, tx_buf);
+-
+- /*
+- * If ntc still points to a different "first" buffer, clean the
+- * descriptor ring and stash all of the buffers for later cleaning. If
+- * we cannot stash all of the buffers, next_to_clean will point to the
+- * "first" buffer of the packet that could not be stashed and cleaning
+- * will start there next time.
+- */
+- if (unlikely(tx_buf != &txq->tx_buf[orig_idx] &&
+- !idpf_tx_splitq_clean(txq, orig_idx, budget, cleaned,
+- true)))
+- return true;
+-
+- /*
+- * Otherwise, update next_to_clean to reflect the cleaning that was
+- * done above.
+- */
+- txq->next_to_clean = idx;
+-
+ return true;
+ }
+
+@@ -2044,12 +2010,10 @@ static void idpf_tx_handle_rs_completion(struct idpf_tx_queue *txq,
+
+ compl_tag = le16_to_cpu(desc->q_head_compl_tag.compl_tag);
+
+- idpf_post_buf_refill(txq->refillq, compl_tag);
+-
+ /* If we didn't clean anything on the ring, this packet must be
+ * in the hash table. Go clean it there.
+ */
+- if (!idpf_tx_clean_buf_ring(txq, compl_tag, cleaned, budget))
++ if (!idpf_tx_clean_bufs(txq, compl_tag, cleaned, budget))
+ idpf_tx_clean_stashed_bufs(txq, compl_tag, cleaned, budget);
+ }
+
+@@ -2362,7 +2326,7 @@ static unsigned int idpf_tx_splitq_bump_ntu(struct idpf_tx_queue *txq, u16 ntu)
+ * Return: true if a buffer ID was found, false if not
+ */
+ static bool idpf_tx_get_free_buf_id(struct idpf_sw_queue *refillq,
+- u16 *buf_id)
++ u32 *buf_id)
+ {
+ u32 ntc = refillq->next_to_clean;
+ u32 refill_desc;
+@@ -2395,25 +2359,34 @@ static void idpf_tx_splitq_pkt_err_unmap(struct idpf_tx_queue *txq,
+ struct idpf_tx_splitq_params *params,
+ struct idpf_tx_buf *first)
+ {
++ struct idpf_sw_queue *refillq = txq->refillq;
+ struct libeth_sq_napi_stats ss = { };
+ struct idpf_tx_buf *tx_buf = first;
+ struct libeth_cq_pp cp = {
+ .dev = txq->dev,
+ .ss = &ss,
+ };
+- u32 idx = 0;
+
+ u64_stats_update_begin(&txq->stats_sync);
+ u64_stats_inc(&txq->q_stats.dma_map_errs);
+ u64_stats_update_end(&txq->stats_sync);
+
+- do {
++ libeth_tx_complete(tx_buf, &cp);
++ while (idpf_tx_buf_next(tx_buf) != IDPF_TXBUF_NULL) {
++ tx_buf = &txq->tx_buf[idpf_tx_buf_next(tx_buf)];
+ libeth_tx_complete(tx_buf, &cp);
+- idpf_tx_clean_buf_ring_bump_ntc(txq, idx, tx_buf);
+- } while (idpf_tx_buf_compl_tag(tx_buf) == params->compl_tag);
++ }
+
+ /* Update tail in case netdev_xmit_more was previously true. */
+ idpf_tx_buf_hw_update(txq, params->prev_ntu, false);
++
++ if (!refillq)
++ return;
++
++ /* Restore refillq state to avoid leaking tags. */
++ if (params->prev_refill_gen != idpf_queue_has(RFL_GEN_CHK, refillq))
++ idpf_queue_change(RFL_GEN_CHK, refillq);
++ refillq->next_to_clean = params->prev_refill_ntc;
+ }
+
+ /**
+@@ -2437,6 +2410,7 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+ struct netdev_queue *nq;
+ struct sk_buff *skb;
+ skb_frag_t *frag;
++ u32 next_buf_id;
+ u16 td_cmd = 0;
+ dma_addr_t dma;
+
+@@ -2454,18 +2428,16 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+ tx_buf = first;
+ first->nr_frags = 0;
+
+- params->compl_tag =
+- (tx_q->compl_tag_cur_gen << tx_q->compl_tag_gen_s) | i;
+-
+ for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
+ unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED;
+
+- if (unlikely(dma_mapping_error(tx_q->dev, dma)))
++ if (unlikely(dma_mapping_error(tx_q->dev, dma))) {
++ idpf_tx_buf_next(tx_buf) = IDPF_TXBUF_NULL;
+ return idpf_tx_splitq_pkt_err_unmap(tx_q, params,
+ first);
++ }
+
+ first->nr_frags++;
+- idpf_tx_buf_compl_tag(tx_buf) = params->compl_tag;
+ tx_buf->type = LIBETH_SQE_FRAG;
+
+ /* record length, and DMA address */
+@@ -2521,29 +2493,14 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+ max_data);
+
+ if (unlikely(++i == tx_q->desc_count)) {
+- tx_buf = tx_q->tx_buf;
+ tx_desc = &tx_q->flex_tx[0];
+ i = 0;
+ tx_q->compl_tag_cur_gen =
+ IDPF_TX_ADJ_COMPL_TAG_GEN(tx_q);
+ } else {
+- tx_buf++;
+ tx_desc++;
+ }
+
+- /* Since this packet has a buffer that is going to span
+- * multiple descriptors, it's going to leave holes in
+- * to the TX buffer ring. To ensure these holes do not
+- * cause issues in the cleaning routines, we will clear
+- * them of any stale data and assign them the same
+- * completion tag as the current packet. Then when the
+- * packet is being cleaned, the cleaning routines will
+- * simply pass over these holes and finish cleaning the
+- * rest of the packet.
+- */
+- tx_buf->type = LIBETH_SQE_EMPTY;
+- idpf_tx_buf_compl_tag(tx_buf) = params->compl_tag;
+-
+ /* Adjust the DMA offset and the remaining size of the
+ * fragment. On the first iteration of this loop,
+ * max_data will be >= 12K and <= 16K-1. On any
+@@ -2568,15 +2525,26 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+ idpf_tx_splitq_build_desc(tx_desc, params, td_cmd, size);
+
+ if (unlikely(++i == tx_q->desc_count)) {
+- tx_buf = tx_q->tx_buf;
+ tx_desc = &tx_q->flex_tx[0];
+ i = 0;
+ tx_q->compl_tag_cur_gen = IDPF_TX_ADJ_COMPL_TAG_GEN(tx_q);
+ } else {
+- tx_buf++;
+ tx_desc++;
+ }
+
++ if (idpf_queue_has(FLOW_SCH_EN, tx_q)) {
++ if (unlikely(!idpf_tx_get_free_buf_id(tx_q->refillq,
++ &next_buf_id))) {
++ idpf_tx_buf_next(tx_buf) = IDPF_TXBUF_NULL;
++ return idpf_tx_splitq_pkt_err_unmap(tx_q, params,
++ first);
++ }
++ } else {
++ next_buf_id = i;
++ }
++ idpf_tx_buf_next(tx_buf) = next_buf_id;
++ tx_buf = &tx_q->tx_buf[next_buf_id];
++
+ size = skb_frag_size(frag);
+ data_len -= size;
+
+@@ -2591,6 +2559,7 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+
+ /* write last descriptor with RS and EOP bits */
+ first->rs_idx = i;
++ idpf_tx_buf_next(tx_buf) = IDPF_TXBUF_NULL;
+ td_cmd |= params->eop_cmd;
+ idpf_tx_splitq_build_desc(tx_desc, params, td_cmd, size);
+ i = idpf_tx_splitq_bump_ntu(tx_q, i);
+@@ -2799,8 +2768,6 @@ idpf_tx_splitq_get_ctx_desc(struct idpf_tx_queue *txq)
+ union idpf_flex_tx_ctx_desc *desc;
+ int i = txq->next_to_use;
+
+- txq->tx_buf[i].type = LIBETH_SQE_CTX;
+-
+ /* grab the next descriptor */
+ desc = &txq->flex_ctx[i];
+ txq->next_to_use = idpf_tx_splitq_bump_ntu(txq, i);
+@@ -2910,6 +2877,7 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+ struct idpf_tx_buf *first;
+ unsigned int count;
+ int tso, idx;
++ u32 buf_id;
+
+ count = idpf_tx_desc_count_required(tx_q, skb);
+ if (unlikely(!count))
+@@ -2953,26 +2921,28 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+ idpf_tx_set_tstamp_desc(ctx_desc, idx);
+ }
+
+- /* record the location of the first descriptor for this packet */
+- first = &tx_q->tx_buf[tx_q->next_to_use];
+- first->skb = skb;
++ if (idpf_queue_has(FLOW_SCH_EN, tx_q)) {
++ struct idpf_sw_queue *refillq = tx_q->refillq;
+
+- if (tso) {
+- first->packets = tx_params.offload.tso_segs;
+- first->bytes = skb->len +
+- ((first->packets - 1) * tx_params.offload.tso_hdr_len);
+- } else {
+- first->packets = 1;
+- first->bytes = max_t(unsigned int, skb->len, ETH_ZLEN);
+- }
++ /* Save refillq state in case of a packet rollback. Otherwise,
++ * the tags will be leaked since they will be popped from the
++ * refillq but never reposted during cleaning.
++ */
++ tx_params.prev_refill_gen =
++ idpf_queue_has(RFL_GEN_CHK, refillq);
++ tx_params.prev_refill_ntc = refillq->next_to_clean;
+
+- if (idpf_queue_has(FLOW_SCH_EN, tx_q)) {
+ if (unlikely(!idpf_tx_get_free_buf_id(tx_q->refillq,
+- &tx_params.compl_tag))) {
+- u64_stats_update_begin(&tx_q->stats_sync);
+- u64_stats_inc(&tx_q->q_stats.q_busy);
+- u64_stats_update_end(&tx_q->stats_sync);
++ &buf_id))) {
++ if (tx_params.prev_refill_gen !=
++ idpf_queue_has(RFL_GEN_CHK, refillq))
++ idpf_queue_change(RFL_GEN_CHK, refillq);
++ refillq->next_to_clean = tx_params.prev_refill_ntc;
++
++ tx_q->next_to_use = tx_params.prev_ntu;
++ return idpf_tx_drop_skb(tx_q, skb);
+ }
++ tx_params.compl_tag = buf_id;
+
+ tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_FLOW_SCHE;
+ tx_params.eop_cmd = IDPF_TXD_FLEX_FLOW_CMD_EOP;
+@@ -2990,6 +2960,8 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+ tx_params.offload.td_cmd |= IDPF_TXD_FLEX_FLOW_CMD_CS_EN;
+
+ } else {
++ buf_id = tx_q->next_to_use;
++
+ tx_params.dtype = IDPF_TX_DESC_DTYPE_FLEX_L2TAG1_L2TAG2;
+ tx_params.eop_cmd = IDPF_TXD_LAST_DESC_CMD;
+
+@@ -2997,6 +2969,18 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+ tx_params.offload.td_cmd |= IDPF_TX_FLEX_DESC_CMD_CS_EN;
+ }
+
++ first = &tx_q->tx_buf[buf_id];
++ first->skb = skb;
++
++ if (tso) {
++ first->packets = tx_params.offload.tso_segs;
++ first->bytes = skb->len +
++ ((first->packets - 1) * tx_params.offload.tso_hdr_len);
++ } else {
++ first->packets = 1;
++ first->bytes = max_t(unsigned int, skb->len, ETH_ZLEN);
++ }
++
+ idpf_tx_splitq_map(tx_q, &tx_params, first);
+
+ return NETDEV_TX_OK;
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+index c4070806be05c..a30b68504d73c 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+@@ -136,6 +136,8 @@ do { \
+ ((++(txq)->compl_tag_cur_gen) >= (txq)->compl_tag_gen_max ? \
+ 0 : (txq)->compl_tag_cur_gen)
+
++#define IDPF_TXBUF_NULL U32_MAX
++
+ #define IDPF_TXD_LAST_DESC_CMD (IDPF_TX_DESC_CMD_EOP | IDPF_TX_DESC_CMD_RS)
+
+ #define IDPF_TX_FLAGS_TSO BIT(0)
+@@ -196,6 +198,8 @@ struct idpf_tx_offload_params {
+ * @td_tag: Descriptor tunneling tag
+ * @offload: Offload parameters
+ * @prev_ntu: stored TxQ next_to_use in case of rollback
++ * @prev_refill_ntc: stored refillq next_to_clean in case of packet rollback
++ * @prev_refill_gen: stored refillq generation bit in case of packet rollback
+ */
+ struct idpf_tx_splitq_params {
+ enum idpf_tx_desc_dtype_value dtype;
+@@ -208,6 +212,8 @@ struct idpf_tx_splitq_params {
+ struct idpf_tx_offload_params offload;
+
+ u16 prev_ntu;
++ u16 prev_refill_ntc;
++ bool prev_refill_gen;
+ };
+
+ enum idpf_tx_ctx_desc_eipt_offload {
+@@ -636,6 +642,7 @@ libeth_cacheline_set_assert(struct idpf_rx_queue, 64,
+ * @size: Length of descriptor ring in bytes
+ * @dma: Physical address of ring
+ * @q_vector: Backreference to associated vector
++ * @buf_pool_size: Total number of idpf_tx_buf
+ */
+ struct idpf_tx_queue {
+ __cacheline_group_begin_aligned(read_mostly);
+@@ -693,11 +700,12 @@ struct idpf_tx_queue {
+ dma_addr_t dma;
+
+ struct idpf_q_vector *q_vector;
++ u32 buf_pool_size;
+ __cacheline_group_end_aligned(cold);
+ };
+ libeth_cacheline_set_assert(struct idpf_tx_queue, 64,
+ 120 + sizeof(struct u64_stats_sync),
+- 24);
++ 32);
+
+ /**
+ * struct idpf_buf_queue - software structure representing a buffer queue
+--
+2.50.1
+
--- /dev/null
+From dca28759d10ab4cbc9756cb1d4d866d7ac99a427 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jul 2025 11:42:20 -0700
+Subject: idpf: simplify and fix splitq Tx packet rollback error path
+
+From: Joshua Hay <joshua.a.hay@intel.com>
+
+[ Upstream commit b61dfa9bc4430ad82b96d3a7c1c485350f91b467 ]
+
+Move (and rename) the existing rollback logic to singleq.c since that
+will be the only consumer. Create a simplified splitq specific rollback
+function to loop through and unmap tx_bufs based on the completion tag.
+This is critical before replacing the Tx buffer ring with the buffer
+pool since the previous rollback indexing will not work to unmap the
+chained buffers from the pool.
+
+Cache the next_to_use index before any portion of the packet is put on
+the descriptor ring. In case of an error, the rollback will bump tail to
+the correct next_to_use value. Because the splitq path now supports
+different types of context descriptors (and potentially multiple in the
+future), this will take care of rolling back any and all context
+descriptors encoded on the ring for the erroneous packet. The previous
+rollback logic was broken for PTP packets since it would not account for
+the PTP context descriptor.
+
+Fixes: 1a49cf814fe1 ("idpf: add Tx timestamp flows")
+Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
+Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/intel/idpf/idpf_singleq_txrx.c | 57 +++++++++++-
+ drivers/net/ethernet/intel/idpf/idpf_txrx.c | 91 ++++++++-----------
+ drivers/net/ethernet/intel/idpf/idpf_txrx.h | 5 +-
+ 3 files changed, 95 insertions(+), 58 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+index 993c354aa27ad..a3b3261bbdfa7 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+@@ -179,6 +179,58 @@ static int idpf_tx_singleq_csum(struct sk_buff *skb,
+ return 1;
+ }
+
++/**
++ * idpf_tx_singleq_dma_map_error - handle TX DMA map errors
++ * @txq: queue to send buffer on
++ * @skb: send buffer
++ * @first: original first buffer info buffer for packet
++ * @idx: starting point on ring to unwind
++ */
++static void idpf_tx_singleq_dma_map_error(struct idpf_tx_queue *txq,
++ struct sk_buff *skb,
++ struct idpf_tx_buf *first, u16 idx)
++{
++ struct libeth_sq_napi_stats ss = { };
++ struct libeth_cq_pp cp = {
++ .dev = txq->dev,
++ .ss = &ss,
++ };
++
++ u64_stats_update_begin(&txq->stats_sync);
++ u64_stats_inc(&txq->q_stats.dma_map_errs);
++ u64_stats_update_end(&txq->stats_sync);
++
++ /* clear dma mappings for failed tx_buf map */
++ for (;;) {
++ struct idpf_tx_buf *tx_buf;
++
++ tx_buf = &txq->tx_buf[idx];
++ libeth_tx_complete(tx_buf, &cp);
++ if (tx_buf == first)
++ break;
++ if (idx == 0)
++ idx = txq->desc_count;
++ idx--;
++ }
++
++ if (skb_is_gso(skb)) {
++ union idpf_tx_flex_desc *tx_desc;
++
++ /* If we failed a DMA mapping for a TSO packet, we will have
++ * used one additional descriptor for a context
++ * descriptor. Reset that here.
++ */
++ tx_desc = &txq->flex_tx[idx];
++ memset(tx_desc, 0, sizeof(*tx_desc));
++ if (idx == 0)
++ idx = txq->desc_count;
++ idx--;
++ }
++
++ /* Update tail in case netdev_xmit_more was previously true */
++ idpf_tx_buf_hw_update(txq, idx, false);
++}
++
+ /**
+ * idpf_tx_singleq_map - Build the Tx base descriptor
+ * @tx_q: queue to send buffer on
+@@ -219,8 +271,9 @@ static void idpf_tx_singleq_map(struct idpf_tx_queue *tx_q,
+ for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
+ unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED;
+
+- if (dma_mapping_error(tx_q->dev, dma))
+- return idpf_tx_dma_map_error(tx_q, skb, first, i);
++ if (unlikely(dma_mapping_error(tx_q->dev, dma)))
++ return idpf_tx_singleq_dma_map_error(tx_q, skb,
++ first, i);
+
+ /* record length, and DMA address */
+ dma_unmap_len_set(tx_buf, len, size);
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+index b26d054013354..7c758e7281ab5 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+@@ -2337,57 +2337,6 @@ unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
+ return count;
+ }
+
+-/**
+- * idpf_tx_dma_map_error - handle TX DMA map errors
+- * @txq: queue to send buffer on
+- * @skb: send buffer
+- * @first: original first buffer info buffer for packet
+- * @idx: starting point on ring to unwind
+- */
+-void idpf_tx_dma_map_error(struct idpf_tx_queue *txq, struct sk_buff *skb,
+- struct idpf_tx_buf *first, u16 idx)
+-{
+- struct libeth_sq_napi_stats ss = { };
+- struct libeth_cq_pp cp = {
+- .dev = txq->dev,
+- .ss = &ss,
+- };
+-
+- u64_stats_update_begin(&txq->stats_sync);
+- u64_stats_inc(&txq->q_stats.dma_map_errs);
+- u64_stats_update_end(&txq->stats_sync);
+-
+- /* clear dma mappings for failed tx_buf map */
+- for (;;) {
+- struct idpf_tx_buf *tx_buf;
+-
+- tx_buf = &txq->tx_buf[idx];
+- libeth_tx_complete(tx_buf, &cp);
+- if (tx_buf == first)
+- break;
+- if (idx == 0)
+- idx = txq->desc_count;
+- idx--;
+- }
+-
+- if (skb_is_gso(skb)) {
+- union idpf_tx_flex_desc *tx_desc;
+-
+- /* If we failed a DMA mapping for a TSO packet, we will have
+- * used one additional descriptor for a context
+- * descriptor. Reset that here.
+- */
+- tx_desc = &txq->flex_tx[idx];
+- memset(tx_desc, 0, sizeof(*tx_desc));
+- if (idx == 0)
+- idx = txq->desc_count;
+- idx--;
+- }
+-
+- /* Update tail in case netdev_xmit_more was previously true */
+- idpf_tx_buf_hw_update(txq, idx, false);
+-}
+-
+ /**
+ * idpf_tx_splitq_bump_ntu - adjust NTU and generation
+ * @txq: the tx ring to wrap
+@@ -2436,6 +2385,37 @@ static bool idpf_tx_get_free_buf_id(struct idpf_sw_queue *refillq,
+ return true;
+ }
+
++/**
++ * idpf_tx_splitq_pkt_err_unmap - Unmap buffers and bump tail in case of error
++ * @txq: Tx queue to unwind
++ * @params: pointer to splitq params struct
++ * @first: starting buffer for packet to unmap
++ */
++static void idpf_tx_splitq_pkt_err_unmap(struct idpf_tx_queue *txq,
++ struct idpf_tx_splitq_params *params,
++ struct idpf_tx_buf *first)
++{
++ struct libeth_sq_napi_stats ss = { };
++ struct idpf_tx_buf *tx_buf = first;
++ struct libeth_cq_pp cp = {
++ .dev = txq->dev,
++ .ss = &ss,
++ };
++ u32 idx = 0;
++
++ u64_stats_update_begin(&txq->stats_sync);
++ u64_stats_inc(&txq->q_stats.dma_map_errs);
++ u64_stats_update_end(&txq->stats_sync);
++
++ do {
++ libeth_tx_complete(tx_buf, &cp);
++ idpf_tx_clean_buf_ring_bump_ntc(txq, idx, tx_buf);
++ } while (idpf_tx_buf_compl_tag(tx_buf) == params->compl_tag);
++
++ /* Update tail in case netdev_xmit_more was previously true. */
++ idpf_tx_buf_hw_update(txq, params->prev_ntu, false);
++}
++
+ /**
+ * idpf_tx_splitq_map - Build the Tx flex descriptor
+ * @tx_q: queue to send buffer on
+@@ -2480,8 +2460,9 @@ static void idpf_tx_splitq_map(struct idpf_tx_queue *tx_q,
+ for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
+ unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED;
+
+- if (dma_mapping_error(tx_q->dev, dma))
+- return idpf_tx_dma_map_error(tx_q, skb, first, i);
++ if (unlikely(dma_mapping_error(tx_q->dev, dma)))
++ return idpf_tx_splitq_pkt_err_unmap(tx_q, params,
++ first);
+
+ first->nr_frags++;
+ idpf_tx_buf_compl_tag(tx_buf) = params->compl_tag;
+@@ -2922,7 +2903,9 @@ static void idpf_tx_set_tstamp_desc(union idpf_flex_tx_ctx_desc *ctx_desc,
+ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+ struct idpf_tx_queue *tx_q)
+ {
+- struct idpf_tx_splitq_params tx_params = { };
++ struct idpf_tx_splitq_params tx_params = {
++ .prev_ntu = tx_q->next_to_use,
++ };
+ union idpf_flex_tx_ctx_desc *ctx_desc;
+ struct idpf_tx_buf *first;
+ unsigned int count;
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+index 6924bee6ff5bd..c4070806be05c 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+@@ -195,6 +195,7 @@ struct idpf_tx_offload_params {
+ * @compl_tag: Associated tag for completion
+ * @td_tag: Descriptor tunneling tag
+ * @offload: Offload parameters
++ * @prev_ntu: stored TxQ next_to_use in case of rollback
+ */
+ struct idpf_tx_splitq_params {
+ enum idpf_tx_desc_dtype_value dtype;
+@@ -205,6 +206,8 @@ struct idpf_tx_splitq_params {
+ };
+
+ struct idpf_tx_offload_params offload;
++
++ u16 prev_ntu;
+ };
+
+ enum idpf_tx_ctx_desc_eipt_offload {
+@@ -1039,8 +1042,6 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val,
+ bool xmit_more);
+ unsigned int idpf_size_to_txd_count(unsigned int size);
+ netdev_tx_t idpf_tx_drop_skb(struct idpf_tx_queue *tx_q, struct sk_buff *skb);
+-void idpf_tx_dma_map_error(struct idpf_tx_queue *txq, struct sk_buff *skb,
+- struct idpf_tx_buf *first, u16 ring_idx);
+ unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
+ struct sk_buff *skb);
+ void idpf_tx_timeout(struct net_device *netdev, unsigned int txqueue);
+--
+2.50.1
+
--- /dev/null
+From 2cadb2bfbdf6ed29b3948a66eb3a87f12a4991bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Jul 2025 11:42:22 -0700
+Subject: idpf: stop Tx if there are insufficient buffer resources
+
+From: Joshua Hay <joshua.a.hay@intel.com>
+
+[ Upstream commit 0c3f135e840d4a2ba4253e15d530ec61bc30718e ]
+
+The Tx refillq logic will cause packets to be silently dropped if there
+are not enough buffer resources available to send a packet in flow
+scheduling mode. Instead, determine how many buffers are needed along
+with number of descriptors. Make sure there are enough of both resources
+to send the packet, and stop the queue if not.
+
+Fixes: 7292af042bcf ("idpf: fix a race in txq wakeup")
+Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
+Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
+Tested-by: Samuel Salin <Samuel.salin@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/intel/idpf/idpf_singleq_txrx.c | 4 +-
+ drivers/net/ethernet/intel/idpf/idpf_txrx.c | 47 +++++++++++++------
+ drivers/net/ethernet/intel/idpf/idpf_txrx.h | 15 +++++-
+ 3 files changed, 47 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+index a3b3261bbdfa7..bf9b820c83303 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+@@ -415,11 +415,11 @@ netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb,
+ {
+ struct idpf_tx_offload_params offload = { };
+ struct idpf_tx_buf *first;
++ u32 count, buf_count = 1;
+ int csum, tso, needed;
+- unsigned int count;
+ __be16 protocol;
+
+- count = idpf_tx_desc_count_required(tx_q, skb);
++ count = idpf_tx_res_count_required(tx_q, skb, &buf_count);
+ if (unlikely(!count))
+ return idpf_tx_drop_skb(tx_q, skb);
+
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+index 89fedc2ef247b..cd83243e7c765 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+@@ -2189,15 +2189,22 @@ void idpf_tx_splitq_build_flow_desc(union idpf_tx_flex_desc *desc,
+ desc->flow.qw1.compl_tag = cpu_to_le16(params->compl_tag);
+ }
+
+-/* Global conditions to tell whether the txq (and related resources)
+- * has room to allow the use of "size" descriptors.
++/**
++ * idpf_tx_splitq_has_room - check if enough Tx splitq resources are available
++ * @tx_q: the queue to be checked
++ * @descs_needed: number of descriptors required for this packet
++ * @bufs_needed: number of Tx buffers required for this packet
++ *
++ * Return: 0 if no room available, 1 otherwise
+ */
+-static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 size)
++static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 descs_needed,
++ u32 bufs_needed)
+ {
+- if (IDPF_DESC_UNUSED(tx_q) < size ||
++ if (IDPF_DESC_UNUSED(tx_q) < descs_needed ||
+ IDPF_TX_COMPLQ_PENDING(tx_q->txq_grp) >
+ IDPF_TX_COMPLQ_OVERFLOW_THRESH(tx_q->txq_grp->complq) ||
+- IDPF_TX_BUF_RSV_LOW(tx_q))
++ IDPF_TX_BUF_RSV_LOW(tx_q) ||
++ idpf_tx_splitq_get_free_bufs(tx_q->refillq) < bufs_needed)
+ return 0;
+ return 1;
+ }
+@@ -2206,14 +2213,21 @@ static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 size)
+ * idpf_tx_maybe_stop_splitq - 1st level check for Tx splitq stop conditions
+ * @tx_q: the queue to be checked
+ * @descs_needed: number of descriptors required for this packet
++ * @bufs_needed: number of buffers needed for this packet
+ *
+- * Returns 0 if stop is not needed
++ * Return: 0 if stop is not needed
+ */
+ static int idpf_tx_maybe_stop_splitq(struct idpf_tx_queue *tx_q,
+- unsigned int descs_needed)
++ u32 descs_needed,
++ u32 bufs_needed)
+ {
++ /* Since we have multiple resources to check for splitq, our
++ * start,stop_thrs becomes a boolean check instead of a count
++ * threshold.
++ */
+ if (netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx,
+- idpf_txq_has_room(tx_q, descs_needed),
++ idpf_txq_has_room(tx_q, descs_needed,
++ bufs_needed),
+ 1, 1))
+ return 0;
+
+@@ -2255,14 +2269,16 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val,
+ }
+
+ /**
+- * idpf_tx_desc_count_required - calculate number of Tx descriptors needed
++ * idpf_tx_res_count_required - get number of Tx resources needed for this pkt
+ * @txq: queue to send buffer on
+ * @skb: send buffer
++ * @bufs_needed: (output) number of buffers needed for this skb.
+ *
+- * Returns number of data descriptors needed for this skb.
++ * Return: number of data descriptors and buffers needed for this skb.
+ */
+-unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
+- struct sk_buff *skb)
++unsigned int idpf_tx_res_count_required(struct idpf_tx_queue *txq,
++ struct sk_buff *skb,
++ u32 *bufs_needed)
+ {
+ const struct skb_shared_info *shinfo;
+ unsigned int count = 0, i;
+@@ -2273,6 +2289,7 @@ unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
+ return count;
+
+ shinfo = skb_shinfo(skb);
++ *bufs_needed += shinfo->nr_frags;
+ for (i = 0; i < shinfo->nr_frags; i++) {
+ unsigned int size;
+
+@@ -2875,11 +2892,11 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+ };
+ union idpf_flex_tx_ctx_desc *ctx_desc;
+ struct idpf_tx_buf *first;
+- unsigned int count;
++ u32 count, buf_count = 1;
+ int tso, idx;
+ u32 buf_id;
+
+- count = idpf_tx_desc_count_required(tx_q, skb);
++ count = idpf_tx_res_count_required(tx_q, skb, &buf_count);
+ if (unlikely(!count))
+ return idpf_tx_drop_skb(tx_q, skb);
+
+@@ -2889,7 +2906,7 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
+
+ /* Check for splitq specific TX resources */
+ count += (IDPF_TX_DESCS_PER_CACHE_LINE + tso);
+- if (idpf_tx_maybe_stop_splitq(tx_q, count)) {
++ if (idpf_tx_maybe_stop_splitq(tx_q, count, buf_count)) {
+ idpf_tx_buf_hw_update(tx_q, tx_q->next_to_use, false);
+
+ return NETDEV_TX_BUSY;
+diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.h b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+index a30b68504d73c..54b314ceee738 100644
+--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
++++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+@@ -1023,6 +1023,17 @@ static inline void idpf_vport_intr_set_wb_on_itr(struct idpf_q_vector *q_vector)
+ reg->dyn_ctl);
+ }
+
++/**
++ * idpf_tx_splitq_get_free_bufs - get number of free buf_ids in refillq
++ * @refillq: pointer to refillq containing buf_ids
++ */
++static inline u32 idpf_tx_splitq_get_free_bufs(struct idpf_sw_queue *refillq)
++{
++ return (refillq->next_to_use > refillq->next_to_clean ?
++ 0 : refillq->desc_count) +
++ refillq->next_to_use - refillq->next_to_clean - 1;
++}
++
+ int idpf_vport_singleq_napi_poll(struct napi_struct *napi, int budget);
+ void idpf_vport_init_num_qs(struct idpf_vport *vport,
+ struct virtchnl2_create_vport *vport_msg);
+@@ -1050,8 +1061,8 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val,
+ bool xmit_more);
+ unsigned int idpf_size_to_txd_count(unsigned int size);
+ netdev_tx_t idpf_tx_drop_skb(struct idpf_tx_queue *tx_q, struct sk_buff *skb);
+-unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
+- struct sk_buff *skb);
++unsigned int idpf_tx_res_count_required(struct idpf_tx_queue *txq,
++ struct sk_buff *skb, u32 *buf_count);
+ void idpf_tx_timeout(struct net_device *netdev, unsigned int txqueue);
+ netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb,
+ struct idpf_tx_queue *tx_q);
+--
+2.50.1
+
--- /dev/null
+From da5bd9f66dc7d690893f04e767e861e3027f0cc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:27:30 -0600
+Subject: io_uring/kbuf: always use READ_ONCE() to read ring provided buffer
+ lengths
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit 98b6fa62c84f2e129161e976a5b9b3cb4ccd117b ]
+
+Since the buffers are mapped from userspace, it is prudent to use
+READ_ONCE() to read the value into a local variable, and use that for
+any other actions taken. Having a stable read of the buffer length
+avoids worrying about it changing after checking, or being read multiple
+times.
+
+Similarly, the buffer may well change in between it being picked and
+being committed. Ensure the looping for incremental ring buffer commit
+stops if it hits a zero sized buffer, as no further progress can be made
+at that point.
+
+Fixes: ae98dbf43d75 ("io_uring/kbuf: add support for incremental buffer consumption")
+Link: https://lore.kernel.org/io-uring/tencent_000C02641F6250C856D0C26228DE29A3D30A@qq.com/
+Reported-by: Qingyue Zhang <chunzhennn@qq.com>
+Reported-by: Suoxing Zhang <aftern00n@qq.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/kbuf.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
+index 81a13338dfab3..19a8bde5e1e1c 100644
+--- a/io_uring/kbuf.c
++++ b/io_uring/kbuf.c
+@@ -36,15 +36,19 @@ static bool io_kbuf_inc_commit(struct io_buffer_list *bl, int len)
+ {
+ while (len) {
+ struct io_uring_buf *buf;
+- u32 this_len;
++ u32 buf_len, this_len;
+
+ buf = io_ring_head_to_buf(bl->buf_ring, bl->head, bl->mask);
+- this_len = min_t(u32, len, buf->len);
+- buf->len -= this_len;
+- if (buf->len) {
++ buf_len = READ_ONCE(buf->len);
++ this_len = min_t(u32, len, buf_len);
++ buf_len -= this_len;
++ /* Stop looping for invalid buffer length of 0 */
++ if (buf_len || !this_len) {
+ buf->addr += this_len;
++ buf->len = buf_len;
+ return false;
+ }
++ buf->len = 0;
+ bl->head++;
+ len -= this_len;
+ }
+@@ -159,6 +163,7 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
+ __u16 tail, head = bl->head;
+ struct io_uring_buf *buf;
+ void __user *ret;
++ u32 buf_len;
+
+ tail = smp_load_acquire(&br->tail);
+ if (unlikely(tail == head))
+@@ -168,8 +173,9 @@ static void __user *io_ring_buffer_select(struct io_kiocb *req, size_t *len,
+ req->flags |= REQ_F_BL_EMPTY;
+
+ buf = io_ring_head_to_buf(br, head, bl->mask);
+- if (*len == 0 || *len > buf->len)
+- *len = buf->len;
++ buf_len = READ_ONCE(buf->len);
++ if (*len == 0 || *len > buf_len)
++ *len = buf_len;
+ req->flags |= REQ_F_BUFFER_RING | REQ_F_BUFFERS_COMMIT;
+ req->buf_list = bl;
+ req->buf_index = buf->bid;
+@@ -265,7 +271,7 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg,
+
+ req->buf_index = buf->bid;
+ do {
+- u32 len = buf->len;
++ u32 len = READ_ONCE(buf->len);
+
+ /* truncate end piece, if needed, for non partial buffers */
+ if (len > arg->max_len) {
+--
+2.50.1
+
--- /dev/null
+From 421bf961a2272005ac98df29928415485679707c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 19:43:39 +0800
+Subject: io_uring/kbuf: fix signedness in this_len calculation
+
+From: Qingyue Zhang <chunzhennn@qq.com>
+
+[ Upstream commit c64eff368ac676e8540344d27a3de47e0ad90d21 ]
+
+When importing and using buffers, buf->len is considered unsigned.
+However, buf->len is converted to signed int when committing. This can
+lead to unexpected behavior if the buffer is large enough to be
+interpreted as a negative value. Make min_t calculation unsigned.
+
+Fixes: ae98dbf43d75 ("io_uring/kbuf: add support for incremental buffer consumption")
+Co-developed-by: Suoxing Zhang <aftern00n@qq.com>
+Signed-off-by: Suoxing Zhang <aftern00n@qq.com>
+Signed-off-by: Qingyue Zhang <chunzhennn@qq.com>
+Link: https://lore.kernel.org/r/tencent_4DBB3674C0419BEC2C0C525949DA410CA307@qq.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/kbuf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
+index f2d2cc319faac..81a13338dfab3 100644
+--- a/io_uring/kbuf.c
++++ b/io_uring/kbuf.c
+@@ -39,7 +39,7 @@ static bool io_kbuf_inc_commit(struct io_buffer_list *bl, int len)
+ u32 this_len;
+
+ buf = io_ring_head_to_buf(bl->buf_ring, bl->head, bl->mask);
+- this_len = min_t(int, len, buf->len);
++ this_len = min_t(u32, len, buf->len);
+ buf->len -= this_len;
+ if (buf->len) {
+ buf->addr += this_len;
+--
+2.50.1
+
--- /dev/null
+From 18b6731550c67fe1a8e40dc0250f7f94588a8a3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 31 Jul 2025 14:45:33 +0200
+Subject: ixgbe: fix ixgbe_orom_civd_info struct layout
+
+From: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+
+[ Upstream commit ed913b343dcf9f623e7436fa1a153c89b22d109b ]
+
+The current layout of struct ixgbe_orom_civd_info causes incorrect data
+storage due to compiler-inserted padding. This results in issues when
+writing OROM data into the structure.
+
+Add the __packed attribute to ensure the structure layout matches the
+expected binary format without padding.
+
+Fixes: 70db0788a262 ("ixgbe: read the OROM version information")
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c | 2 +-
+ drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+index 71ea25de1bac7..754c176fd4a7a 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c
+@@ -3123,7 +3123,7 @@ static int ixgbe_get_orom_ver_info(struct ixgbe_hw *hw,
+ if (err)
+ return err;
+
+- combo_ver = le32_to_cpu(civd.combo_ver);
++ combo_ver = get_unaligned_le32(&civd.combo_ver);
+
+ orom->major = (u8)FIELD_GET(IXGBE_OROM_VER_MASK, combo_ver);
+ orom->patch = (u8)FIELD_GET(IXGBE_OROM_VER_PATCH_MASK, combo_ver);
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h
+index 09df67f03cf47..38a41d81de0fa 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type_e610.h
+@@ -1150,7 +1150,7 @@ struct ixgbe_orom_civd_info {
+ __le32 combo_ver; /* Combo Image Version number */
+ u8 combo_name_len; /* Length of the unicode combo image version string, max of 32 */
+ __le16 combo_name[32]; /* Unicode string representing the Combo Image version */
+-};
++} __packed;
+
+ /* Function specific capabilities */
+ struct ixgbe_hw_func_caps {
+--
+2.50.1
+
--- /dev/null
+From 38d1b038f519229ebb42c1ea1affc52ac3a7191b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 13:44:35 +0000
+Subject: l2tp: do not use sock_hold() in pppol2tp_session_get_sock()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 9b8c88f875c04d4cb9111bd5dd9291c7e9691bf5 ]
+
+pppol2tp_session_get_sock() is using RCU, it must be ready
+for sk_refcnt being zero.
+
+Commit ee40fb2e1eb5 ("l2tp: protect sock pointer of
+struct pppol2tp_session with RCU") was correct because it
+had a call_rcu(..., pppol2tp_put_sk) which was later removed in blamed commit.
+
+pppol2tp_recv() can use pppol2tp_session_get_sock() as well.
+
+Fixes: c5cbaef992d6 ("l2tp: refactor ppp socket/session relationship")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: James Chapman <jchapman@katalix.com>
+Reviewed-by: Guillaume Nault <gnault@redhat.com>
+Link: https://patch.msgid.link/20250826134435.1683435-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/l2tp/l2tp_ppp.c | 25 ++++++++-----------------
+ 1 file changed, 8 insertions(+), 17 deletions(-)
+
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index fc5c2fd8f34c7..5e12e7ce17d8a 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -129,22 +129,12 @@ static const struct ppp_channel_ops pppol2tp_chan_ops = {
+
+ static const struct proto_ops pppol2tp_ops;
+
+-/* Retrieves the pppol2tp socket associated to a session.
+- * A reference is held on the returned socket, so this function must be paired
+- * with sock_put().
+- */
++/* Retrieves the pppol2tp socket associated to a session. */
+ static struct sock *pppol2tp_session_get_sock(struct l2tp_session *session)
+ {
+ struct pppol2tp_session *ps = l2tp_session_priv(session);
+- struct sock *sk;
+-
+- rcu_read_lock();
+- sk = rcu_dereference(ps->sk);
+- if (sk)
+- sock_hold(sk);
+- rcu_read_unlock();
+
+- return sk;
++ return rcu_dereference(ps->sk);
+ }
+
+ /* Helpers to obtain tunnel/session contexts from sockets.
+@@ -206,14 +196,13 @@ static int pppol2tp_recvmsg(struct socket *sock, struct msghdr *msg,
+
+ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
+ {
+- struct pppol2tp_session *ps = l2tp_session_priv(session);
+- struct sock *sk = NULL;
++ struct sock *sk;
+
+ /* If the socket is bound, send it in to PPP's input queue. Otherwise
+ * queue it on the session socket.
+ */
+ rcu_read_lock();
+- sk = rcu_dereference(ps->sk);
++ sk = pppol2tp_session_get_sock(session);
+ if (!sk)
+ goto no_sock;
+
+@@ -510,13 +499,14 @@ static void pppol2tp_show(struct seq_file *m, void *arg)
+ struct l2tp_session *session = arg;
+ struct sock *sk;
+
++ rcu_read_lock();
+ sk = pppol2tp_session_get_sock(session);
+ if (sk) {
+ struct pppox_sock *po = pppox_sk(sk);
+
+ seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan));
+- sock_put(sk);
+ }
++ rcu_read_unlock();
+ }
+
+ static void pppol2tp_session_init(struct l2tp_session *session)
+@@ -1530,6 +1520,7 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
+ port = ntohs(inet->inet_sport);
+ }
+
++ rcu_read_lock();
+ sk = pppol2tp_session_get_sock(session);
+ if (sk) {
+ state = sk->sk_state;
+@@ -1565,8 +1556,8 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
+ struct pppox_sock *po = pppox_sk(sk);
+
+ seq_printf(m, " interface %s\n", ppp_dev_name(&po->chan));
+- sock_put(sk);
+ }
++ rcu_read_unlock();
+ }
+
+ static int pppol2tp_seq_show(struct seq_file *m, void *v)
+--
+2.50.1
+
--- /dev/null
+From 1829c7b209ea7661fd39c8d960e072ec6060acd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 20:11:36 +0200
+Subject: mISDN: hfcpci: Fix warning when deleting uninitialized timer
+
+From: Vladimir Riabchun <ferr.lambarginio@gmail.com>
+
+[ Upstream commit 97766512a9951b9fd6fc97f1b93211642bb0b220 ]
+
+With CONFIG_DEBUG_OBJECTS_TIMERS unloading hfcpci module leads
+to the following splat:
+
+[ 250.215892] ODEBUG: assert_init not available (active state 0) object: ffffffffc01a3dc0 object type: timer_list hint: 0x0
+[ 250.217520] WARNING: CPU: 0 PID: 233 at lib/debugobjects.c:612 debug_print_object+0x1b6/0x2c0
+[ 250.218775] Modules linked in: hfcpci(-) mISDN_core
+[ 250.219537] CPU: 0 UID: 0 PID: 233 Comm: rmmod Not tainted 6.17.0-rc2-g6f713187ac98 #2 PREEMPT(voluntary)
+[ 250.220940] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 250.222377] RIP: 0010:debug_print_object+0x1b6/0x2c0
+[ 250.223131] Code: fc ff df 48 89 fa 48 c1 ea 03 80 3c 02 00 75 4f 41 56 48 8b 14 dd a0 4e 01 9f 48 89 ee 48 c7 c7 20 46 01 9f e8 cb 84d
+[ 250.225805] RSP: 0018:ffff888015ea7c08 EFLAGS: 00010286
+[ 250.226608] RAX: 0000000000000000 RBX: 0000000000000005 RCX: ffffffff9be93a95
+[ 250.227708] RDX: 1ffff1100d945138 RSI: 0000000000000008 RDI: ffff88806ca289c0
+[ 250.228993] RBP: ffffffff9f014a00 R08: 0000000000000001 R09: ffffed1002bd4f39
+[ 250.230043] R10: ffff888015ea79cf R11: 0000000000000001 R12: 0000000000000001
+[ 250.231185] R13: ffffffff9eea0520 R14: 0000000000000000 R15: ffff888015ea7cc8
+[ 250.232454] FS: 00007f3208f01540(0000) GS:ffff8880caf5a000(0000) knlGS:0000000000000000
+[ 250.233851] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 250.234856] CR2: 00007f32090a7421 CR3: 0000000004d63000 CR4: 00000000000006f0
+[ 250.236117] Call Trace:
+[ 250.236599] <TASK>
+[ 250.236967] ? trace_irq_enable.constprop.0+0xd4/0x130
+[ 250.237920] debug_object_assert_init+0x1f6/0x310
+[ 250.238762] ? __pfx_debug_object_assert_init+0x10/0x10
+[ 250.239658] ? __lock_acquire+0xdea/0x1c70
+[ 250.240369] __try_to_del_timer_sync+0x69/0x140
+[ 250.241172] ? __pfx___try_to_del_timer_sync+0x10/0x10
+[ 250.242058] ? __timer_delete_sync+0xc6/0x120
+[ 250.242842] ? lock_acquire+0x30/0x80
+[ 250.243474] ? __timer_delete_sync+0xc6/0x120
+[ 250.244262] __timer_delete_sync+0x98/0x120
+[ 250.245015] HFC_cleanup+0x10/0x20 [hfcpci]
+[ 250.245704] __do_sys_delete_module+0x348/0x510
+[ 250.246461] ? __pfx___do_sys_delete_module+0x10/0x10
+[ 250.247338] do_syscall_64+0xc1/0x360
+[ 250.247924] entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fix this by initializing hfc_tl timer with DEFINE_TIMER macro.
+Also, use mod_timer instead of manual timeout update.
+
+Fixes: 87c5fa1bb426 ("mISDN: Add different different timer settings for hfc-pci")
+Fixes: 175302f6b79e ("mISDN: hfcpci: Fix use-after-free bug in hfcpci_softirq")
+Signed-off-by: Vladimir Riabchun <ferr.lambarginio@gmail.com>
+Link: https://patch.msgid.link/aKiy2D_LiWpQ5kXq@vova-pc
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/isdn/hardware/mISDN/hfcpci.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
+index 2b05722d4dbe8..ea8a0ab47afd8 100644
+--- a/drivers/isdn/hardware/mISDN/hfcpci.c
++++ b/drivers/isdn/hardware/mISDN/hfcpci.c
+@@ -39,12 +39,13 @@
+
+ #include "hfc_pci.h"
+
++static void hfcpci_softirq(struct timer_list *unused);
+ static const char *hfcpci_revision = "2.0";
+
+ static int HFC_cnt;
+ static uint debug;
+ static uint poll, tics;
+-static struct timer_list hfc_tl;
++static DEFINE_TIMER(hfc_tl, hfcpci_softirq);
+ static unsigned long hfc_jiffies;
+
+ MODULE_AUTHOR("Karsten Keil");
+@@ -2305,8 +2306,7 @@ hfcpci_softirq(struct timer_list *unused)
+ hfc_jiffies = jiffies + 1;
+ else
+ hfc_jiffies += tics;
+- hfc_tl.expires = hfc_jiffies;
+- add_timer(&hfc_tl);
++ mod_timer(&hfc_tl, hfc_jiffies);
+ }
+
+ static int __init
+@@ -2332,10 +2332,8 @@ HFC_init(void)
+ if (poll != HFCPCI_BTRANS_THRESHOLD) {
+ printk(KERN_INFO "%s: Using alternative poll value of %d\n",
+ __func__, poll);
+- timer_setup(&hfc_tl, hfcpci_softirq, 0);
+- hfc_tl.expires = jiffies + tics;
+- hfc_jiffies = hfc_tl.expires;
+- add_timer(&hfc_tl);
++ hfc_jiffies = jiffies + tics;
++ mod_timer(&hfc_tl, hfc_jiffies);
+ } else
+ tics = 0; /* indicate the use of controller's timer */
+
+--
+2.50.1
+
--- /dev/null
+From 6b0c1bc755a9956062fe94d5bd766251e6c28769 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index da9b7715df050..f828f38cd7682 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1091,7 +1091,7 @@ get_stats (struct net_device *dev)
+ dev->stats.rx_bytes += dr32(OctetRcvOk);
+ dev->stats.tx_bytes += dr32(OctetXmtOk);
+
+- dev->stats.multicast = dr32(McstFramesRcvdOk);
++ dev->stats.multicast += dr32(McstFramesRcvdOk);
+ dev->stats.collisions += dr32(SingleColFrames)
+ + dr32(MultiColFrames);
+
+--
+2.50.1
+
--- /dev/null
+From b91ffc09095d33e7d0ed1e1375b91bb7f9ea3892 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 04:56:27 -0700
+Subject: net: hv_netvsc: fix loss of early receive events from host during
+ channel open.
+
+From: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+
+[ Upstream commit 9448ccd853368582efa9db05db344f8bb9dffe0f ]
+
+The hv_netvsc driver currently enables NAPI after opening the primary and
+subchannels. This ordering creates a race: if the Hyper-V host places data
+in the host -> guest ring buffer and signals the channel before
+napi_enable() has been called, the channel callback will run but
+napi_schedule_prep() will return false. As a result, the NAPI poller never
+gets scheduled, the data in the ring buffer is not consumed, and the
+receive queue may remain permanently stuck until another interrupt happens
+to arrive.
+
+Fix this by enabling NAPI and registering it with the RX/TX queues before
+vmbus channel is opened. This guarantees that any early host signal after
+open will correctly trigger NAPI scheduling and the ring buffer will be
+drained.
+
+Fixes: 76bb5db5c749d ("netvsc: fix use after free on module removal")
+Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
+Link: https://patch.msgid.link/20250825115627.GA32189@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/hyperv/netvsc.c | 17 ++++++++---------
+ drivers/net/hyperv/rndis_filter.c | 23 ++++++++++++++++-------
+ 2 files changed, 24 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+index 720104661d7f2..60a4629fe6ba7 100644
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -1812,6 +1812,11 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+
+ /* Enable NAPI handler before init callbacks */
+ netif_napi_add(ndev, &net_device->chan_table[0].napi, netvsc_poll);
++ napi_enable(&net_device->chan_table[0].napi);
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
++ &net_device->chan_table[0].napi);
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
++ &net_device->chan_table[0].napi);
+
+ /* Open the channel */
+ device->channel->next_request_id_callback = vmbus_next_request_id;
+@@ -1831,12 +1836,6 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+ /* Channel is opened */
+ netdev_dbg(ndev, "hv_netvsc channel opened successfully\n");
+
+- napi_enable(&net_device->chan_table[0].napi);
+- netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX,
+- &net_device->chan_table[0].napi);
+- netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX,
+- &net_device->chan_table[0].napi);
+-
+ /* Connect with the NetVsp */
+ ret = netvsc_connect_vsp(device, net_device, device_info);
+ if (ret != 0) {
+@@ -1854,14 +1853,14 @@ struct netvsc_device *netvsc_device_add(struct hv_device *device,
+
+ close:
+ RCU_INIT_POINTER(net_device_ctx->nvdev, NULL);
+- netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
+- netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
+- napi_disable(&net_device->chan_table[0].napi);
+
+ /* Now, we can close the channel safely */
+ vmbus_close(device->channel);
+
+ cleanup:
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_TX, NULL);
++ netif_queue_set_napi(ndev, 0, NETDEV_QUEUE_TYPE_RX, NULL);
++ napi_disable(&net_device->chan_table[0].napi);
+ netif_napi_del(&net_device->chan_table[0].napi);
+
+ cleanup2:
+diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
+index 9e73959e61ee0..c35f9685b6bf0 100644
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -1252,17 +1252,26 @@ static void netvsc_sc_open(struct vmbus_channel *new_sc)
+ new_sc->rqstor_size = netvsc_rqstor_size(netvsc_ring_bytes);
+ new_sc->max_pkt_size = NETVSC_MAX_PKT_SIZE;
+
++ /* Enable napi before opening the vmbus channel to avoid races
++ * as the host placing data on the host->guest ring may be left
++ * out if napi was not enabled.
++ */
++ napi_enable(&nvchan->napi);
++ netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++ &nvchan->napi);
++ netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++ &nvchan->napi);
++
+ ret = vmbus_open(new_sc, netvsc_ring_bytes,
+ netvsc_ring_bytes, NULL, 0,
+ netvsc_channel_cb, nvchan);
+- if (ret == 0) {
+- napi_enable(&nvchan->napi);
+- netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
+- &nvchan->napi);
+- netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
+- &nvchan->napi);
+- } else {
++ if (ret != 0) {
+ netdev_notice(ndev, "sub channel open failed: %d\n", ret);
++ netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_TX,
++ NULL);
++ netif_queue_set_napi(ndev, chn_index, NETDEV_QUEUE_TYPE_RX,
++ NULL);
++ napi_disable(&nvchan->napi);
+ }
+
+ if (atomic_inc_return(&nvscdev->open_chn) == nvscdev->num_chn)
+--
+2.50.1
+
--- /dev/null
+From d9782636188e1f62d4cd5d8dbe706dfc2d95bec0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 7b8e80c4f1d98..bf82434c3541b 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2573,12 +2573,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+ !netif_is_l3_master(dev_out))
+ return ERR_PTR(-EINVAL);
+
+- if (ipv4_is_lbcast(fl4->daddr))
++ if (ipv4_is_lbcast(fl4->daddr)) {
+ type = RTN_BROADCAST;
+- else if (ipv4_is_multicast(fl4->daddr))
++
++ /* reset fi to prevent gateway resolution */
++ fi = NULL;
++ } else if (ipv4_is_multicast(fl4->daddr)) {
+ type = RTN_MULTICAST;
+- else if (ipv4_is_zeronet(fl4->daddr))
++ } else if (ipv4_is_zeronet(fl4->daddr)) {
+ return ERR_PTR(-EINVAL);
++ }
+
+ if (dev_out->flags & IFF_LOOPBACK)
+ flags |= RTCF_LOCAL;
+--
+2.50.1
+
--- /dev/null
+From b703a736b8f2b12f097cb66b5dafb77ebd64086b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 10:30:22 -0400
+Subject: net: macb: Disable clocks once
+
+From: Neil Mandir <neil.mandir@seco.com>
+
+[ Upstream commit dac978e51cce0c1f00a14c4a82f81d387f79b2d4 ]
+
+When the driver is removed the clocks are disabled twice: once in
+macb_remove and a second time by runtime pm. Disable wakeup in remove so
+all the clocks are disabled and skip the second call to macb_clks_disable.
+Always suspend the device as we always set it active in probe.
+
+Fixes: d54f89af6cc4 ("net: macb: Add pm runtime support")
+Signed-off-by: Neil Mandir <neil.mandir@seco.com>
+Co-developed-by: Sean Anderson <sean.anderson@linux.dev>
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Link: https://patch.msgid.link/20250826143022.935521-1-sean.anderson@linux.dev
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index 3cb50e5385d49..d949d2ba6cb9f 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -5396,14 +5396,11 @@ static void macb_remove(struct platform_device *pdev)
+ mdiobus_unregister(bp->mii_bus);
+ mdiobus_free(bp->mii_bus);
+
++ device_set_wakeup_enable(&bp->pdev->dev, 0);
+ cancel_work_sync(&bp->hresp_err_bh_work);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+- if (!pm_runtime_suspended(&pdev->dev)) {
+- macb_clks_disable(bp->pclk, bp->hclk, bp->tx_clk,
+- bp->rx_clk, bp->tsu_clk);
+- pm_runtime_set_suspended(&pdev->dev);
+- }
++ pm_runtime_set_suspended(&pdev->dev);
+ phylink_destroy(bp->phylink);
+ free_netdev(dev);
+ }
+--
+2.50.1
+
--- /dev/null
+From 8b9d06182a3f8a7376da2ab4a399368497d5e016 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 13:21:34 -0400
+Subject: net: macb: Fix offset error in gem_update_stats
+
+From: Sean Anderson <sean.anderson@linux.dev>
+
+[ Upstream commit 16c8a3a67ec799fc731919e3e51be9af6cdf541d ]
+
+hw_stats now has only one variable for tx_octets/rx_octets, so we should
+only increment p once, not twice. This would cause the statistics to be
+reported under the wrong categories in `ethtool -S --all-groups` (which
+uses hw_stats) but not `ethtool -S` (which uses ethtool_stats).
+
+Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
+Fixes: f6af690a295a ("net: cadence: macb: Report standard stats")
+Link: https://patch.msgid.link/20250825172134.681861-1-sean.anderson@linux.dev
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index c1e904e4a01f4..3cb50e5385d49 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -3090,7 +3090,7 @@ static void gem_update_stats(struct macb *bp)
+ /* Add GEM_OCTTXH, GEM_OCTRXH */
+ val = bp->macb_reg_readl(bp, offset + 4);
+ bp->ethtool_stats[i] += ((u64)val) << 32;
+- *(p++) += ((u64)val) << 32;
++ *p += ((u64)val) << 32;
+ }
+ }
+
+--
+2.50.1
+
--- /dev/null
+From d010a9d7bef5b40cf6489d517fabf1c4257e548d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Aug 2025 07:25:27 +0800
+Subject: net: macb: fix unregister_netdev call order in macb_remove()
+
+From: luoguangfei <15388634752@163.com>
+
+[ Upstream commit 01b9128c5db1b470575d07b05b67ffa3cb02ebf1 ]
+
+When removing a macb device, the driver calls phy_exit() before
+unregister_netdev(). This leads to a WARN from kernfs:
+
+ ------------[ cut here ]------------
+ kernfs: can not remove 'attached_dev', no directory
+ WARNING: CPU: 1 PID: 27146 at fs/kernfs/dir.c:1683
+ Call trace:
+ kernfs_remove_by_name_ns+0xd8/0xf0
+ sysfs_remove_link+0x24/0x58
+ phy_detach+0x5c/0x168
+ phy_disconnect+0x4c/0x70
+ phylink_disconnect_phy+0x6c/0xc0 [phylink]
+ macb_close+0x6c/0x170 [macb]
+ ...
+ macb_remove+0x60/0x168 [macb]
+ platform_remove+0x5c/0x80
+ ...
+
+The warning happens because the PHY is being exited while the netdev
+is still registered. The correct order is to unregister the netdev
+before shutting down the PHY and cleaning up the MDIO bus.
+
+Fix this by moving unregister_netdev() ahead of phy_exit() in
+macb_remove().
+
+Fixes: 8b73fa3ae02b ("net: macb: Added ZynqMP-specific initialization")
+Signed-off-by: luoguangfei <15388634752@163.com>
+Link: https://patch.msgid.link/20250818232527.1316-1-15388634752@163.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/cadence/macb_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index d1f1ae5ea161c..c1e904e4a01f4 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -5391,11 +5391,11 @@ static void macb_remove(struct platform_device *pdev)
+
+ if (dev) {
+ bp = netdev_priv(dev);
++ unregister_netdev(dev);
+ phy_exit(bp->sgmii_phy);
+ mdiobus_unregister(bp->mii_bus);
+ mdiobus_free(bp->mii_bus);
+
+- unregister_netdev(dev);
+ cancel_work_sync(&bp->hresp_err_bh_work);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
+--
+2.50.1
+
--- /dev/null
+From 281d01b35caaf4e893362835eee2e4855dbbd0ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:29 +0300
+Subject: net/mlx5: Fix lockdep assertion on sync reset unload event
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 902a8bc23a24882200f57cadc270e15a2cfaf2bb ]
+
+Fix lockdep assertion triggered during sync reset unload event. When the
+sync reset flow is initiated using the devlink reload fw_activate
+option, the PF already holds the devlink lock while handling unload
+event. In this case, delegate sync reset unload event handling back to
+the devlink callback process to avoid double-locking and resolve the
+lockdep warning.
+
+Kernel log:
+WARNING: CPU: 9 PID: 1578 at devl_assert_locked+0x31/0x40
+[...]
+Call Trace:
+<TASK>
+ mlx5_unload_one_devl_locked+0x2c/0xc0 [mlx5_core]
+ mlx5_sync_reset_unload_event+0xaf/0x2f0 [mlx5_core]
+ process_one_work+0x222/0x640
+ worker_thread+0x199/0x350
+ kthread+0x10b/0x230
+ ? __pfx_worker_thread+0x10/0x10
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x8e/0x100
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+</TASK>
+
+Fixes: 7a9770f1bfea ("net/mlx5: Handle sync reset unload event")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-7-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ .../ethernet/mellanox/mlx5/core/fw_reset.c | 120 ++++++++++--------
+ .../ethernet/mellanox/mlx5/core/fw_reset.h | 1 +
+ 3 files changed, 69 insertions(+), 54 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 42c70862095e9..ca03dbcb07da0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+ if (err)
+ return err;
+
+- mlx5_unload_one_devl_locked(dev, false);
++ mlx5_sync_reset_unload_flow(dev, true);
+ err = mlx5_health_wait_pci_up(dev);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 69933addd921e..38b9b184ae01b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -12,7 +12,8 @@ enum {
+ MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
+ MLX5_FW_RESET_FLAGS_PENDING_COMP,
+ MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
+- MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
++ MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
++ MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
+ };
+
+ struct mlx5_fw_reset {
+@@ -219,7 +220,7 @@ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev)
+ return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false);
+ }
+
+-static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unloaded)
++static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+ {
+ struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
+ struct devlink *devlink = priv_to_devlink(dev);
+@@ -228,8 +229,7 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unload
+ if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) {
+ complete(&fw_reset->done);
+ } else {
+- if (!unloaded)
+- mlx5_unload_one(dev, false);
++ mlx5_sync_reset_unload_flow(dev, false);
+ if (mlx5_health_wait_pci_up(dev))
+ mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
+ else
+@@ -272,7 +272,7 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work)
+
+ mlx5_sync_reset_clear_reset_requested(dev, false);
+ mlx5_enter_error_state(dev, true);
+- mlx5_fw_reset_complete_reload(dev, false);
++ mlx5_fw_reset_complete_reload(dev);
+ }
+
+ #define MLX5_RESET_POLL_INTERVAL (HZ / 10)
+@@ -586,6 +586,65 @@ static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method)
+ return err;
+ }
+
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked)
++{
++ struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
++ unsigned long timeout;
++ int poll_freq = 20;
++ bool reset_action;
++ u8 rst_state;
++ int err;
++
++ if (locked)
++ mlx5_unload_one_devl_locked(dev, false);
++ else
++ mlx5_unload_one(dev, false);
++
++ if (!test_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags))
++ return;
++
++ mlx5_set_fw_rst_ack(dev);
++ mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
++
++ reset_action = false;
++ timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
++ do {
++ rst_state = mlx5_get_fw_rst_state(dev);
++ if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
++ rst_state == MLX5_FW_RST_STATE_IDLE) {
++ reset_action = true;
++ break;
++ }
++ if (rst_state == MLX5_FW_RST_STATE_DROP_MODE) {
++ mlx5_core_info(dev, "Sync Reset Drop mode ack\n");
++ mlx5_set_fw_rst_ack(dev);
++ poll_freq = 1000;
++ }
++ msleep(poll_freq);
++ } while (!time_after(jiffies, timeout));
++
++ if (!reset_action) {
++ mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
++ rst_state);
++ fw_reset->ret = -ETIMEDOUT;
++ goto done;
++ }
++
++ mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n",
++ rst_state);
++ if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
++ err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
++ if (err) {
++ mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n",
++ err);
++ fw_reset->ret = err;
++ }
++ }
++
++done:
++ clear_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
++}
++
+ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ {
+ struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+@@ -613,17 +672,13 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ mlx5_enter_error_state(dev, true);
+ done:
+ fw_reset->ret = err;
+- mlx5_fw_reset_complete_reload(dev, false);
++ mlx5_fw_reset_complete_reload(dev);
+ }
+
+ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ {
+ struct mlx5_fw_reset *fw_reset;
+ struct mlx5_core_dev *dev;
+- unsigned long timeout;
+- int poll_freq = 20;
+- bool reset_action;
+- u8 rst_state;
+ int err;
+
+ fw_reset = container_of(work, struct mlx5_fw_reset, reset_unload_work);
+@@ -632,6 +687,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ if (mlx5_sync_reset_clear_reset_requested(dev, false))
+ return;
+
++ set_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
+ mlx5_core_warn(dev, "Sync Reset Unload. Function is forced down.\n");
+
+ err = mlx5_cmd_fast_teardown_hca(dev);
+@@ -640,49 +696,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ else
+ mlx5_enter_error_state(dev, true);
+
+- if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
+- mlx5_unload_one_devl_locked(dev, false);
+- else
+- mlx5_unload_one(dev, false);
+-
+- mlx5_set_fw_rst_ack(dev);
+- mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
+-
+- reset_action = false;
+- timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
+- do {
+- rst_state = mlx5_get_fw_rst_state(dev);
+- if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
+- rst_state == MLX5_FW_RST_STATE_IDLE) {
+- reset_action = true;
+- break;
+- }
+- if (rst_state == MLX5_FW_RST_STATE_DROP_MODE) {
+- mlx5_core_info(dev, "Sync Reset Drop mode ack\n");
+- mlx5_set_fw_rst_ack(dev);
+- poll_freq = 1000;
+- }
+- msleep(poll_freq);
+- } while (!time_after(jiffies, timeout));
+-
+- if (!reset_action) {
+- mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
+- rst_state);
+- fw_reset->ret = -ETIMEDOUT;
+- goto done;
+- }
+-
+- mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state);
+- if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
+- err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+- if (err) {
+- mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", err);
+- fw_reset->ret = err;
+- }
+- }
+-
+-done:
+- mlx5_fw_reset_complete_reload(dev, true);
++ mlx5_fw_reset_complete_reload(dev);
+ }
+
+ static void mlx5_sync_reset_abort_event(struct work_struct *work)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+index ea527d06a85f0..d5b28525c960d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+@@ -12,6 +12,7 @@ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel,
+ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
+
+ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
+ int mlx5_fw_reset_verify_fw_complete(struct mlx5_core_dev *dev,
+ struct netlink_ext_ack *extack);
+ void mlx5_fw_reset_events_start(struct mlx5_core_dev *dev);
+--
+2.50.1
+
--- /dev/null
+From 33771cea1d889a84185b92f2898522d15ff9be36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:25 +0300
+Subject: net/mlx5: HWS, Fix memory leak in hws_action_get_shared_stc_nic error
+ flow
+
+From: Lama Kayal <lkayal@nvidia.com>
+
+[ Upstream commit a630f83592cdad1253523a1b760cfe78fef6cd9c ]
+
+When an invalid stc_type is provided, the function allocates memory for
+shared_stc but jumps to unlock_and_out without freeing it, causing a
+memory leak.
+
+Fix by jumping to free_shared_stc label instead to ensure proper cleanup.
+
+Fixes: 504e536d9010 ("net/mlx5: HWS, added actions handling")
+Signed-off-by: Lama Kayal <lkayal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-3-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c
+index 447ea3f8722ce..8e4a085f4a2ec 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c
+@@ -117,7 +117,7 @@ static int hws_action_get_shared_stc_nic(struct mlx5hws_context *ctx,
+ mlx5hws_err(ctx, "No such stc_type: %d\n", stc_type);
+ pr_warn("HWS: Invalid stc_type: %d\n", stc_type);
+ ret = -EINVAL;
+- goto unlock_and_out;
++ goto free_shared_stc;
+ }
+
+ ret = mlx5hws_action_alloc_single_stc(ctx, &stc_attr, tbl_type,
+--
+2.50.1
+
--- /dev/null
+From e9ade0be9921b5663a464f3185d1ead12186db04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:24 +0300
+Subject: net/mlx5: HWS, Fix memory leak in hws_pool_buddy_init error path
+
+From: Lama Kayal <lkayal@nvidia.com>
+
+[ Upstream commit 2c0a959bebdc1ada13cf9a8242f177c5400299e6 ]
+
+In the error path of hws_pool_buddy_init(), the buddy allocator cleanup
+doesn't free the allocator structure itself, causing a memory leak.
+
+Add the missing kfree() to properly release all allocated memory.
+
+Fixes: c61afff94373 ("net/mlx5: HWS, added memory management handling")
+Signed-off-by: Lama Kayal <lkayal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-2-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c
+index 7e37d6e9eb836..7b5071c3df368 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c
+@@ -124,6 +124,7 @@ static int hws_pool_buddy_init(struct mlx5hws_pool *pool)
+ mlx5hws_err(pool->ctx, "Failed to create resource type: %d size %zu\n",
+ pool->type, pool->alloc_log_sz);
+ mlx5hws_buddy_cleanup(buddy);
++ kfree(buddy);
+ return -ENOMEM;
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 5bab21b73b609b4281b26bfaf50c90fd54eabd62 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:27 +0300
+Subject: net/mlx5: HWS, Fix pattern destruction in mlx5hws_pat_get_pattern
+ error path
+
+From: Lama Kayal <lkayal@nvidia.com>
+
+[ Upstream commit 00a50e4e8974cbf5d6a1dc91cfa5cce4aa7af05a ]
+
+In mlx5hws_pat_get_pattern(), when mlx5hws_pat_add_pattern_to_cache()
+fails, the function attempts to clean up the pattern created by
+mlx5hws_cmd_header_modify_pattern_create(). However, it incorrectly
+uses *pattern_id which hasn't been set yet, instead of the local
+ptrn_id variable that contains the actual pattern ID.
+
+This results in attempting to destroy a pattern using uninitialized
+data from the output parameter, rather than the valid pattern ID
+returned by the firmware.
+
+Use ptrn_id instead of *pattern_id in the cleanup path to properly
+destroy the created pattern.
+
+Fixes: aefc15a0fa1c ("net/mlx5: HWS, added modify header pattern and args handling")
+Signed-off-by: Lama Kayal <lkayal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-5-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
+index 622fd579f1407..d56271a9e4f01 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
+@@ -279,7 +279,7 @@ int mlx5hws_pat_get_pattern(struct mlx5hws_context *ctx,
+ return ret;
+
+ clean_pattern:
+- mlx5hws_cmd_header_modify_pattern_destroy(ctx->mdev, *pattern_id);
++ mlx5hws_cmd_header_modify_pattern_destroy(ctx->mdev, ptrn_id);
+ out_unlock:
+ mutex_unlock(&ctx->pattern_cache->lock);
+ return ret;
+--
+2.50.1
+
--- /dev/null
+From b52c3d3d4495e8a6f23fbe6aa141d7a38f758288 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:26 +0300
+Subject: net/mlx5: HWS, Fix uninitialized variables in mlx5hws_pat_calc_nop
+ error flow
+
+From: Lama Kayal <lkayal@nvidia.com>
+
+[ Upstream commit 24b6e53140475b56cadcccd4e82a93aa5bacf1eb ]
+
+In mlx5hws_pat_calc_nop(), src_field and dst_field are passed to
+hws_action_modify_get_target_fields() which should set their values.
+However, if an invalid action type is encountered, these variables
+remain uninitialized and are later used to update prev_src_field
+and prev_dst_field.
+
+Initialize both variables to INVALID_FIELD to ensure they have
+defined values in all code paths.
+
+Fixes: 01e035fd0380 ("net/mlx5: HWS, handle modify header actions dependency")
+Signed-off-by: Lama Kayal <lkayal@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-4-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
+index 51e4c551e0efd..622fd579f1407 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
+@@ -527,7 +527,6 @@ int mlx5hws_pat_calc_nop(__be64 *pattern, size_t num_actions,
+ u32 *nop_locations, __be64 *new_pat)
+ {
+ u16 prev_src_field = INVALID_FIELD, prev_dst_field = INVALID_FIELD;
+- u16 src_field, dst_field;
+ u8 action_type;
+ bool dependent;
+ size_t i, j;
+@@ -539,6 +538,9 @@ int mlx5hws_pat_calc_nop(__be64 *pattern, size_t num_actions,
+ return 0;
+
+ for (i = 0, j = 0; i < num_actions; i++, j++) {
++ u16 src_field = INVALID_FIELD;
++ u16 dst_field = INVALID_FIELD;
++
+ if (j >= max_actions)
+ return -EINVAL;
+
+--
+2.50.1
+
--- /dev/null
+From 05d9daaf424c0a3fd15abd814a683e4f5889a7d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:30 +0300
+Subject: net/mlx5: Nack sync reset when SFs are present
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 26e42ec7712d392d561964514b1f253b1a96f42d ]
+
+If PF (Physical Function) has SFs (Sub-Functions), since the SFs are not
+taking part in the synchronization flow, sync reset can lead to fatal
+error on the SFs, as the function will be closed unexpectedly from the
+SF point of view.
+
+Add a check to prevent sync reset when there are SFs on a PF device
+which is not ECPF, as ECPF is teardowned gracefully before reset.
+
+Fixes: 92501fa6e421 ("net/mlx5: Ack on sync_reset_request only if PF can do reset_now")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Parav Pandit <parav@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-8-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 6 ++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c | 10 ++++++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h | 6 ++++++
+ 3 files changed, 22 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 38b9b184ae01b..22995131824a0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -6,6 +6,7 @@
+ #include "fw_reset.h"
+ #include "diag/fw_tracer.h"
+ #include "lib/tout.h"
++#include "sf/sf.h"
+
+ enum {
+ MLX5_FW_RESET_FLAGS_RESET_REQUESTED,
+@@ -428,6 +429,11 @@ static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev,
+ return false;
+ }
+
++ if (!mlx5_core_is_ecpf(dev) && !mlx5_sf_table_empty(dev)) {
++ mlx5_core_warn(dev, "SFs should be removed before reset\n");
++ return false;
++ }
++
+ #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)
+ if (reset_method != MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET) {
+ err = mlx5_check_hotplug_interrupt(dev, bridge);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index 0864ba625c07d..3304f25cc8055 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -518,3 +518,13 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+ WARN_ON(!xa_empty(&table->function_ids));
+ kfree(table);
+ }
++
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++ struct mlx5_sf_table *table = dev->priv.sf_table;
++
++ if (!table)
++ return true;
++
++ return xa_empty(&table->function_ids);
++}
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+index 860f9ddb7107b..89559a37997ad 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+@@ -17,6 +17,7 @@ void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev);
+
+ int mlx5_sf_table_init(struct mlx5_core_dev *dev);
+ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev);
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev);
+
+ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+ const struct devlink_port_new_attrs *add_attr,
+@@ -61,6 +62,11 @@ static inline void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+ {
+ }
+
++static inline bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++ return true;
++}
++
+ #endif
+
+ #endif
+--
+2.50.1
+
--- /dev/null
+From d879216ed12f956d2f9bedd42664259713764d4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:31 +0300
+Subject: net/mlx5: Prevent flow steering mode changes in switchdev mode
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit cf9a8627b9a369ba01d37be6f71b297beb688faa ]
+
+Changing flow steering modes is not allowed when eswitch is in switchdev
+mode. This fix ensures that any steering mode change, including to
+firmware steering, is correctly blocked while eswitch mode is switchdev.
+
+Fixes: e890acd5ff18 ("net/mlx5: Add devlink flow_steering_mode parameter")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-9-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+index 3dd9a6f407092..29ce09af59aef 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+@@ -3706,6 +3706,13 @@ static int mlx5_fs_mode_validate(struct devlink *devlink, u32 id,
+ char *value = val.vstr;
+ u8 eswitch_mode;
+
++ eswitch_mode = mlx5_eswitch_mode(dev);
++ if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
++ NL_SET_ERR_MSG_FMT_MOD(extack,
++ "Changing fs mode is not supported when eswitch offloads enabled.");
++ return -EOPNOTSUPP;
++ }
++
+ if (!strcmp(value, "dmfs"))
+ return 0;
+
+@@ -3731,14 +3738,6 @@ static int mlx5_fs_mode_validate(struct devlink *devlink, u32 id,
+ return -EINVAL;
+ }
+
+- eswitch_mode = mlx5_eswitch_mode(dev);
+- if (eswitch_mode == MLX5_ESWITCH_OFFLOADS) {
+- NL_SET_ERR_MSG_FMT_MOD(extack,
+- "Moving to %s is not supported when eswitch offloads enabled.",
+- value);
+- return -EOPNOTSUPP;
+- }
+-
+ return 0;
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 310697ae325b9272c640c1a2dd619dc6f61f11ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:28 +0300
+Subject: net/mlx5: Reload auxiliary drivers on fw_activate
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 34cc6a54914f478c93e176450fae6313404f9f74 ]
+
+The devlink reload fw_activate command performs firmware activation
+followed by driver reload, while devlink reload driver_reinit triggers
+only driver reload. However, the driver reload logic differs between the
+two modes, as on driver_reinit mode mlx5 also reloads auxiliary drivers,
+while in fw_activate mode the auxiliary drivers are suspended where
+applicable.
+
+Additionally, following the cited commit, if the device has multiple PFs,
+the behavior during fw_activate may vary between PFs: one PF may suspend
+auxiliary drivers, while another reloads them.
+
+Align devlink dev reload fw_activate behavior with devlink dev reload
+driver_reinit, to reload all auxiliary drivers.
+
+Fixes: 72ed5d5624af ("net/mlx5: Suspend auxiliary devices only in case of PCI device suspend")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-6-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 73cd746443788..42c70862095e9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+ if (err)
+ return err;
+
+- mlx5_unload_one_devl_locked(dev, true);
++ mlx5_unload_one_devl_locked(dev, false);
+ err = mlx5_health_wait_pci_up(dev);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+--
+2.50.1
+
--- /dev/null
+From 1a5f7b91dfb061c7f29c4ef835799f17b393c8e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@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/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index 3efa8bf1d14ef..4720523813b97 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -575,7 +575,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ if (err)
+ return err;
+ }
+- priv->dcbx.xoff = xoff;
+
+ /* Apply the settings */
+ if (update_buffer) {
+@@ -584,6 +583,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ return err;
+ }
+
++ priv->dcbx.xoff = xoff;
++
+ if (update_prio2buffer)
+ err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+
+--
+2.50.1
+
--- /dev/null
+From 784a79caec6b854bee33120df11512feea4c406c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+index f4a19ffbb641c..66d276a1be836 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -66,11 +66,23 @@ struct mlx5e_port_buffer {
+ struct mlx5e_bufferx_reg buffer[MLX5E_MAX_NETWORK_BUFFER];
+ };
+
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ u32 change, unsigned int mtu,
+ struct ieee_pfc *pfc,
+ u32 *buffer_size,
+ u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++ u32 change, unsigned int mtu,
++ void *pfc,
++ u32 *buffer_size,
++ u8 *prio2buffer)
++{
++ return 0;
++}
++#endif
+
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+ struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 16d818943487b..f0142d32b648f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -48,6 +48,7 @@
+ #include "en.h"
+ #include "en/dim.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2985,9 +2986,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ struct mlx5e_params *params = &priv->channels.params;
+ struct net_device *netdev = priv->netdev;
+ struct mlx5_core_dev *mdev = priv->mdev;
+- u16 mtu;
++ u16 mtu, prev_mtu;
+ int err;
+
++ mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+ err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+ if (err)
+ return err;
+@@ -2997,6 +3000,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+ __func__, mtu, params->sw_mtu);
+
++ if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++ err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++ NULL, NULL, NULL);
++ if (err) {
++ netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++ __func__, mtu, err, prev_mtu);
++
++ mlx5e_set_mtu(mdev, params, prev_mtu);
++ return err;
++ }
++ }
++
+ params->sw_mtu = mtu;
+ return 0;
+ }
+--
+2.50.1
+
--- /dev/null
+From 0f30b7f9a5dfe4a88629518119b3fa45cfaaa66f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@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_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index f0142d32b648f..e39c51cfc8e6c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -136,6 +136,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+ if (up) {
+ netdev_info(priv->netdev, "Link up\n");
+ netif_carrier_on(priv->netdev);
++ mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++ NULL, NULL, NULL);
+ } else {
+ netdev_info(priv->netdev, "Link down\n");
+ netif_carrier_off(priv->netdev);
+--
+2.50.1
+
--- /dev/null
+From ef9af2c7c72b0ddc7509ef210721ac47284b540d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:56 +0900
+Subject: net: rose: convert 'use' field to refcount_t
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit d860d1faa6b2ce3becfdb8b0c2b048ad31800061 ]
+
+The 'use' field in struct rose_neigh is used as a reference counter but
+lacks atomicity. This can lead to race conditions where a rose_neigh
+structure is freed while still being referenced by other code paths.
+
+For example, when rose_neigh->use becomes zero during an ioctl operation
+via rose_rt_ioctl(), the structure may be removed while its timer is
+still active, potentially causing use-after-free issues.
+
+This patch changes the type of 'use' from unsigned short to refcount_t and
+updates all code paths to use rose_neigh_hold() and rose_neigh_put() which
+operate reference counts atomically.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-3-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h | 18 +++++++++++++-----
+ net/rose/af_rose.c | 13 +++++++------
+ net/rose/rose_in.c | 12 ++++++------
+ net/rose/rose_route.c | 33 ++++++++++++++++++---------------
+ net/rose/rose_timer.c | 2 +-
+ 5 files changed, 45 insertions(+), 33 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 174b4f605d849..2b5491bbf39ab 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -8,6 +8,7 @@
+ #ifndef _ROSE_H
+ #define _ROSE_H
+
++#include <linux/refcount.h>
+ #include <linux/rose.h>
+ #include <net/ax25.h>
+ #include <net/sock.h>
+@@ -96,7 +97,7 @@ struct rose_neigh {
+ ax25_cb *ax25;
+ struct net_device *dev;
+ unsigned short count;
+- unsigned short use;
++ refcount_t use;
+ unsigned int number;
+ char restarted;
+ char dce_mode;
+@@ -151,12 +152,19 @@ struct rose_sock {
+
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
+
++static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
++{
++ refcount_inc(&rose_neigh->use);
++}
++
+ static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
+ {
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
++ if (refcount_dec_and_test(&rose_neigh->use)) {
++ if (rose_neigh->ax25)
++ ax25_cb_put(rose_neigh->ax25);
++ kfree(rose_neigh->digipeat);
++ kfree(rose_neigh);
++ }
+ }
+
+ /* af_rose.c */
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index 4e72b636a46a5..543f9e8ebb693 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -170,7 +170,7 @@ void rose_kill_by_neigh(struct rose_neigh *neigh)
+
+ if (rose->neighbour == neigh) {
+ rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose->neighbour = NULL;
+ }
+ }
+@@ -212,7 +212,7 @@ static void rose_kill_by_device(struct net_device *dev)
+ if (rose->device == dev) {
+ rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+ if (rose->neighbour)
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ netdev_put(rose->device, &rose->dev_tracker);
+ rose->device = NULL;
+ }
+@@ -655,7 +655,7 @@ static int rose_release(struct socket *sock)
+ break;
+
+ case ROSE_STATE_2:
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ release_sock(sk);
+ rose_disconnect(sk, 0, -1, -1);
+ lock_sock(sk);
+@@ -823,6 +823,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ rose->lci = rose_new_lci(rose->neighbour);
+ if (!rose->lci) {
+ err = -ENETUNREACH;
++ rose_neigh_put(rose->neighbour);
+ goto out_release;
+ }
+
+@@ -834,12 +835,14 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ dev = rose_dev_first();
+ if (!dev) {
+ err = -ENETUNREACH;
++ rose_neigh_put(rose->neighbour);
+ goto out_release;
+ }
+
+ user = ax25_findbyuid(current_euid());
+ if (!user) {
+ err = -EINVAL;
++ rose_neigh_put(rose->neighbour);
+ dev_put(dev);
+ goto out_release;
+ }
+@@ -874,8 +877,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+
+ rose->state = ROSE_STATE_1;
+
+- rose->neighbour->use++;
+-
+ rose_write_internal(sk, ROSE_CALL_REQUEST);
+ rose_start_heartbeat(sk);
+ rose_start_t1timer(sk);
+@@ -1077,7 +1078,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
+ GFP_ATOMIC);
+ make_rose->facilities = facilities;
+
+- make_rose->neighbour->use++;
++ rose_neigh_hold(make_rose->neighbour);
+
+ if (rose_sk(sk)->defer) {
+ make_rose->state = ROSE_STATE_5;
+diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
+index 4d67f36dce1b4..7caae93937ee9 100644
+--- a/net/rose/rose_in.c
++++ b/net/rose/rose_in.c
+@@ -56,7 +56,7 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -79,12 +79,12 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ case ROSE_CLEAR_CONFIRMATION:
+ rose_disconnect(sk, 0, -1, -1);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -120,7 +120,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ case ROSE_RR:
+@@ -233,7 +233,7 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -253,7 +253,7 @@ static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int framety
+ if (frametype == ROSE_CLEAR_REQUEST) {
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose_sk(sk)->neighbour->use--;
++ rose_neigh_put(rose_sk(sk)->neighbour);
+ }
+
+ return 0;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 0c44c416f4853..8efb9033c057c 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -93,11 +93,11 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ rose_neigh->ax25 = NULL;
+ rose_neigh->dev = dev;
+ rose_neigh->count = 0;
+- rose_neigh->use = 0;
+ rose_neigh->dce_mode = 0;
+ rose_neigh->loopback = 0;
+ rose_neigh->number = rose_neigh_no++;
+ rose_neigh->restarted = 0;
++ refcount_set(&rose_neigh->use, 1);
+
+ skb_queue_head_init(&rose_neigh->queue);
+
+@@ -255,10 +255,10 @@ static void rose_remove_route(struct rose_route *rose_route)
+ struct rose_route *s;
+
+ if (rose_route->neigh1 != NULL)
+- rose_route->neigh1->use--;
++ rose_neigh_put(rose_route->neigh1);
+
+ if (rose_route->neigh2 != NULL)
+- rose_route->neigh2->use--;
++ rose_neigh_put(rose_route->neigh2);
+
+ if ((s = rose_route_list) == rose_route) {
+ rose_route_list = rose_route->next;
+@@ -323,7 +323,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
+
+- if (rose_neigh->count == 0 && rose_neigh->use == 0) {
++ if (rose_neigh->count == 0) {
+ rose_remove_neigh(rose_neigh);
+ rose_neigh_put(rose_neigh);
+ }
+@@ -375,11 +375,11 @@ void rose_add_loopback_neigh(void)
+ sn->ax25 = NULL;
+ sn->dev = NULL;
+ sn->count = 0;
+- sn->use = 0;
+ sn->dce_mode = 1;
+ sn->loopback = 1;
+ sn->number = rose_neigh_no++;
+ sn->restarted = 1;
++ refcount_set(&sn->use, 1);
+
+ skb_queue_head_init(&sn->queue);
+
+@@ -561,8 +561,7 @@ static int rose_clear_routes(void)
+ s = rose_neigh;
+ rose_neigh = rose_neigh->next;
+
+- if (s->use == 0 && !s->loopback) {
+- s->count = 0;
++ if (!s->loopback) {
+ rose_remove_neigh(s);
+ rose_neigh_put(s);
+ }
+@@ -680,6 +679,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+ for (i = 0; i < node->count; i++) {
+ if (node->neighbour[i]->restarted) {
+ res = node->neighbour[i];
++ rose_neigh_hold(node->neighbour[i]);
+ goto out;
+ }
+ }
+@@ -691,6 +691,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+ for (i = 0; i < node->count; i++) {
+ if (!rose_ftimer_running(node->neighbour[i])) {
+ res = node->neighbour[i];
++ rose_neigh_hold(node->neighbour[i]);
+ goto out;
+ }
+ failed = 1;
+@@ -780,13 +781,13 @@ static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
+ }
+
+ if (rose_route->neigh1 == rose_neigh) {
+- rose_route->neigh1->use--;
++ rose_neigh_put(rose_route->neigh1);
+ rose_route->neigh1 = NULL;
+ rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
+ }
+
+ if (rose_route->neigh2 == rose_neigh) {
+- rose_route->neigh2->use--;
++ rose_neigh_put(rose_route->neigh2);
+ rose_route->neigh2 = NULL;
+ rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
+ }
+@@ -915,7 +916,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_clear_queues(sk);
+ rose->cause = ROSE_NETWORK_CONGESTION;
+ rose->diagnostic = 0;
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose->neighbour = NULL;
+ rose->lci = 0;
+ rose->state = ROSE_STATE_0;
+@@ -1040,12 +1041,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+
+ if ((new_lci = rose_new_lci(new_neigh)) == 0) {
+ rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
+- goto out;
++ goto put_neigh;
+ }
+
+ if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
+ rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
+- goto out;
++ goto put_neigh;
+ }
+
+ rose_route->lci1 = lci;
+@@ -1058,8 +1059,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_route->lci2 = new_lci;
+ rose_route->neigh2 = new_neigh;
+
+- rose_route->neigh1->use++;
+- rose_route->neigh2->use++;
++ rose_neigh_hold(rose_route->neigh1);
++ rose_neigh_hold(rose_route->neigh2);
+
+ rose_route->next = rose_route_list;
+ rose_route_list = rose_route;
+@@ -1071,6 +1072,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_transmit_link(skb, rose_route->neigh2);
+ res = 1;
+
++put_neigh:
++ rose_neigh_put(new_neigh);
+ out:
+ spin_unlock_bh(&rose_route_list_lock);
+ spin_unlock_bh(&rose_neigh_list_lock);
+@@ -1186,7 +1189,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+ (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+ rose_neigh->dev ? rose_neigh->dev->name : "???",
+ rose_neigh->count,
+- rose_neigh->use,
++ refcount_read(&rose_neigh->use) - 1,
+ (rose_neigh->dce_mode) ? "DCE" : "DTE",
+ (rose_neigh->restarted) ? "yes" : "no",
+ ax25_display_timer(&rose_neigh->t0timer) / HZ,
+diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
+index 020369c49587f..bb60a1654d612 100644
+--- a/net/rose/rose_timer.c
++++ b/net/rose/rose_timer.c
+@@ -180,7 +180,7 @@ static void rose_timer_expiry(struct timer_list *t)
+ break;
+
+ case ROSE_STATE_2: /* T3 */
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose_disconnect(sk, ETIMEDOUT, -1, -1);
+ break;
+
+--
+2.50.1
+
--- /dev/null
+From ca4b6653dbe36488e0e6e4174ff6c19817d58eb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:57 +0900
+Subject: net: rose: include node references in rose_neigh refcount
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit da9c9c877597170b929a6121a68dcd3dd9a80f45 ]
+
+Current implementation maintains two separate reference counting
+mechanisms: the 'count' field in struct rose_neigh tracks references from
+rose_node structures, while the 'use' field (now refcount_t) tracks
+references from rose_sock.
+
+This patch merges these two reference counting systems using 'use' field
+for proper reference management. Specifically, this patch adds incrementing
+and decrementing of rose_neigh->use when rose_neigh->count is incremented
+or decremented.
+
+This patch also modifies rose_rt_free(), rose_rt_device_down() and
+rose_clear_route() to properly release references to rose_neigh objects
+before freeing a rose_node through rose_remove_node().
+
+These changes ensure rose_neigh structures are properly freed only when
+all references, including those from rose_node structures, are released.
+As a result, this resolves a slab-use-after-free issue reported by Syzbot.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+942297eecf7d2d61d1f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=942297eecf7d2d61d1f1
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-4-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rose/rose_route.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 8efb9033c057c..1adee1fbc2ed1 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -178,6 +178,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ }
+ }
+ rose_neigh->count++;
++ rose_neigh_hold(rose_neigh);
+
+ goto out;
+ }
+@@ -187,6 +188,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ rose_node->neighbour[rose_node->count] = rose_neigh;
+ rose_node->count++;
+ rose_neigh->count++;
++ rose_neigh_hold(rose_neigh);
+ }
+
+ out:
+@@ -322,6 +324,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ for (i = 0; i < rose_node->count; i++) {
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
++ rose_neigh_put(rose_neigh);
+
+ if (rose_neigh->count == 0) {
+ rose_remove_neigh(rose_neigh);
+@@ -430,6 +433,7 @@ int rose_add_loopback_node(const rose_address *address)
+ rose_node_list = rose_node;
+
+ rose_loopback_neigh->count++;
++ rose_neigh_hold(rose_loopback_neigh);
+
+ out:
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -461,6 +465,7 @@ void rose_del_loopback_node(const rose_address *address)
+ rose_remove_node(rose_node);
+
+ rose_loopback_neigh->count--;
++ rose_neigh_put(rose_loopback_neigh);
+
+ out:
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -500,6 +505,7 @@ void rose_rt_device_down(struct net_device *dev)
+ memmove(&t->neighbour[i], &t->neighbour[i + 1],
+ sizeof(t->neighbour[0]) *
+ (t->count - i));
++ rose_neigh_put(s);
+ }
+
+ if (t->count <= 0)
+@@ -543,6 +549,7 @@ static int rose_clear_routes(void)
+ {
+ struct rose_neigh *s, *rose_neigh;
+ struct rose_node *t, *rose_node;
++ int i;
+
+ spin_lock_bh(&rose_node_list_lock);
+ spin_lock_bh(&rose_neigh_list_lock);
+@@ -553,8 +560,12 @@ static int rose_clear_routes(void)
+ while (rose_node != NULL) {
+ t = rose_node;
+ rose_node = rose_node->next;
+- if (!t->loopback)
++
++ if (!t->loopback) {
++ for (i = 0; i < rose_node->count; i++)
++ rose_neigh_put(t->neighbour[i]);
+ rose_remove_node(t);
++ }
+ }
+
+ while (rose_neigh != NULL) {
+@@ -1189,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+ (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+ rose_neigh->dev ? rose_neigh->dev->name : "???",
+ rose_neigh->count,
+- refcount_read(&rose_neigh->use) - 1,
++ refcount_read(&rose_neigh->use) - rose_neigh->count - 1,
+ (rose_neigh->dce_mode) ? "DCE" : "DTE",
+ (rose_neigh->restarted) ? "yes" : "no",
+ ax25_display_timer(&rose_neigh->t0timer) / HZ,
+@@ -1294,6 +1305,7 @@ void __exit rose_rt_free(void)
+ struct rose_neigh *s, *rose_neigh = rose_neigh_list;
+ struct rose_node *t, *rose_node = rose_node_list;
+ struct rose_route *u, *rose_route = rose_route_list;
++ int i;
+
+ while (rose_neigh != NULL) {
+ s = rose_neigh;
+@@ -1307,6 +1319,8 @@ void __exit rose_rt_free(void)
+ t = rose_node;
+ rose_node = rose_node->next;
+
++ for (i = 0; i < t->count; i++)
++ rose_neigh_put(t->neighbour[i]);
+ rose_remove_node(t);
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 4487615c0f452d270b59460ed8ef914d2d8e035b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:55 +0900
+Subject: net: rose: split remove and free operations in rose_remove_neigh()
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit dcb34659028f856c423a29ef9b4e2571d203444d ]
+
+The current rose_remove_neigh() performs two distinct operations:
+1. Removes rose_neigh from rose_neigh_list
+2. Frees the rose_neigh structure
+
+Split these operations into separate functions to improve maintainability
+and prepare for upcoming refcount_t conversion. The timer cleanup remains
+in rose_remove_neigh() because free operations can be called from timer
+itself.
+
+This patch introduce rose_neigh_put() to handle the freeing of rose_neigh
+structures and modify rose_remove_neigh() to handle removal only.
+
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-2-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h | 8 ++++++++
+ net/rose/rose_route.c | 15 ++++++---------
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 23267b4efcfa3..174b4f605d849 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -151,6 +151,14 @@ struct rose_sock {
+
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
+
++static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
++{
++ if (rose_neigh->ax25)
++ ax25_cb_put(rose_neigh->ax25);
++ kfree(rose_neigh->digipeat);
++ kfree(rose_neigh);
++}
++
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int sysctl_rose_restart_request_timeout;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index b72bf8a08d489..0c44c416f4853 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -234,20 +234,12 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+
+ if ((s = rose_neigh_list) == rose_neigh) {
+ rose_neigh_list = rose_neigh->next;
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
+ return;
+ }
+
+ while (s != NULL && s->next != NULL) {
+ if (s->next == rose_neigh) {
+ s->next = rose_neigh->next;
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
+ return;
+ }
+
+@@ -331,8 +323,10 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
+
+- if (rose_neigh->count == 0 && rose_neigh->use == 0)
++ if (rose_neigh->count == 0 && rose_neigh->use == 0) {
+ rose_remove_neigh(rose_neigh);
++ rose_neigh_put(rose_neigh);
++ }
+
+ rose_node->count--;
+
+@@ -513,6 +507,7 @@ void rose_rt_device_down(struct net_device *dev)
+ }
+
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+ spin_unlock_bh(&rose_neigh_list_lock);
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -569,6 +564,7 @@ static int rose_clear_routes(void)
+ if (s->use == 0 && !s->loopback) {
+ s->count = 0;
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+ }
+
+@@ -1301,6 +1297,7 @@ void __exit rose_rt_free(void)
+ rose_neigh = rose_neigh->next;
+
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+
+ while (rose_node != NULL) {
+--
+2.50.1
+
--- /dev/null
+From 8aaa1bd4504f820f97e1827466d72d86c2058d4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:54 +0800
+Subject: net: stmmac: Set CIC bit only for TX queues with COE
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit b1eded580ab28119de0b0f21efe37ee2b4419144 ]
+
+Currently, in the AF_XDP transmit paths, the CIC bit of
+TX Desc3 is set for all packets. Setting this bit for
+packets transmitting through queues that don't support
+checksum offloading causes the TX DMA to get stuck after
+transmitting some packets. This patch ensures the CIC bit
+of TX Desc3 is set only if the TX queue supports checksum
+offloading.
+
+Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-3-c225fe4444c0@altera.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 | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index e0fb06af1f940..36082d4917bcc 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2584,6 +2584,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+ struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
+ struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
++ bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+ struct xsk_buff_pool *pool = tx_q->xsk_pool;
+ unsigned int entry = tx_q->cur_tx;
+ struct dma_desc *tx_desc = NULL;
+@@ -2671,7 +2672,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+ }
+
+ stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len,
+- true, priv->mode, true, true,
++ csum, priv->mode, true, true,
+ xdp_desc.len);
+
+ stmmac_enable_dma_transmission(priv, priv->ioaddr, queue);
+@@ -4983,6 +4984,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+ {
+ struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
++ bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+ unsigned int entry = tx_q->cur_tx;
+ struct dma_desc *tx_desc;
+ dma_addr_t dma_addr;
+@@ -5034,7 +5036,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+ stmmac_set_desc_addr(priv, tx_desc, dma_addr);
+
+ stmmac_prepare_tx_desc(priv, tx_desc, 1, xdpf->len,
+- true, priv->mode, true, true,
++ csum, priv->mode, true, true,
+ xdpf->len);
+
+ tx_q->tx_count_frames++;
+--
+2.50.1
+
--- /dev/null
+From 1c085336f1ad4c97ae5197d3a69c46fd521df342 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:53 +0800
+Subject: net: stmmac: xgmac: Correct supported speed modes
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 42ef11b2bff5b6a2910c28d2ea47cc00e0fbcaec ]
+
+Correct supported speed modes as per the XGMAC databook.
+Commit 9cb54af214a7 ("net: stmmac: Fix IP-cores specific
+MAC capabilities") removes support for 10M, 100M and
+1000HD. 1000HD is not supported by XGMAC IP, but it does
+support 10M and 100M FD mode for XGMAC version >= 2_20,
+and it also supports 10M and 100M HD mode if the HDSEL bit
+is set in the MAC_HW_FEATURE0 reg. This commit enables support
+for 10M and 100M speed modes for XGMAC IP based on XGMAC
+version and MAC capabilities.
+
+Fixes: 9cb54af214a7 ("net: stmmac: Fix IP-cores specific MAC capabilities")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-2-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 13 +++++++++++--
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 5 +++++
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+index 6cadf8de4fdfd..00e929bf280ba 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+@@ -49,6 +49,14 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,
+ writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
+ }
+
++static void dwxgmac2_update_caps(struct stmmac_priv *priv)
++{
++ if (!priv->dma_cap.mbps_10_100)
++ priv->hw->link.caps &= ~(MAC_10 | MAC_100);
++ else if (!priv->dma_cap.half_duplex)
++ priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD);
++}
++
+ static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
+ {
+ u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
+@@ -1424,6 +1432,7 @@ static void dwxgmac2_set_arp_offload(struct mac_device_info *hw, bool en,
+
+ const struct stmmac_ops dwxgmac210_ops = {
+ .core_init = dwxgmac2_core_init,
++ .update_caps = dwxgmac2_update_caps,
+ .set_mac = dwxgmac2_set_mac,
+ .rx_ipc = dwxgmac2_rx_ipc,
+ .rx_queue_enable = dwxgmac2_rx_queue_enable,
+@@ -1532,8 +1541,8 @@ int dwxgmac2_setup(struct stmmac_priv *priv)
+ mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+
+ mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+- MAC_1000FD | MAC_2500FD | MAC_5000FD |
+- MAC_10000FD;
++ MAC_10 | MAC_100 | MAC_1000FD |
++ MAC_2500FD | MAC_5000FD | MAC_10000FD;
+ mac->link.duplex = 0;
+ mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
+ mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 7201a38842651..4d6bb995d8d84 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -382,8 +382,11 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
+ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+ struct dma_features *dma_cap)
+ {
++ struct stmmac_priv *priv;
+ u32 hw_cap;
+
++ priv = container_of(dma_cap, struct stmmac_priv, dma_cap);
++
+ /* MAC HW feature 0 */
+ hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
+ dma_cap->edma = (hw_cap & XGMAC_HWFEAT_EDMA) >> 31;
+@@ -406,6 +409,8 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+ dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4;
+ dma_cap->half_duplex = (hw_cap & XGMAC_HWFEAT_HDSEL) >> 3;
+ dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;
++ if (dma_cap->mbps_1000 && priv->synopsys_id >= DWXGMAC_CORE_2_20)
++ dma_cap->mbps_10_100 = 1;
+
+ /* MAC HW feature 1 */
+ hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
+--
+2.50.1
+
--- /dev/null
+From 0c55c97c9343a3b833ffa81a41a8b8d39183281e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 5dcc95bc0ad28..7201a38842651 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -203,10 +203,6 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+ }
+
+ writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+- /* Enable MTL RX overflow */
+- value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+- writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+
+ static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+--
+2.50.1
+
--- /dev/null
+From ed23e35ef99918fd70b98941eaf46976dd02648e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 16:28:05 +0530
+Subject: Octeontx2-af: Fix NIX X2P calibration failures
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit d280233fc86692f495d5e08092e5422bc2f583a8 ]
+
+Before configuring the NIX block, the AF driver initiates the
+"NIX block X2P bus calibration" and verifies that NIX interfaces
+such as CGX and LBK are active and functioning correctly.
+
+On few silicon variants(CNF10KA and CNF10KB), X2P calibration failures
+have been observed on some CGX blocks that are not mapped to the NIX block.
+
+Since both NIX-mapped and non-NIX-mapped CGX blocks share the same
+VENDOR,DEVICE,SUBSYS_DEVID, it's not possible to skip probe based on
+these parameters.
+
+This patch introuduces "is_cgx_mapped_to_nix" API to detect and skip
+probe of non NIX mapped CGX blocks.
+
+Fixes: aba53d5dbcea ("octeontx2-af: NIX block admin queue init")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Link: https://patch.msgid.link/20250822105805.2236528-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 7 +++++++
+ drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 14 ++++++++++++++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+index 971993586fb49..442305463cc0a 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+@@ -1940,6 +1940,13 @@ static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ goto err_release_regions;
+ }
+
++ if (!is_cn20k(pdev) &&
++ !is_cgx_mapped_to_nix(pdev->subsystem_device, cgx->cgx_id)) {
++ dev_notice(dev, "CGX %d not mapped to NIX, skipping probe\n",
++ cgx->cgx_id);
++ goto err_release_regions;
++ }
++
+ cgx->lmac_count = cgx->mac_ops->get_nr_lmacs(cgx);
+ if (!cgx->lmac_count) {
+ dev_notice(dev, "CGX %d LMAC count is zero, skipping probe\n", cgx->cgx_id);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+index 5c179df1f1673..9cdb7431f558c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+@@ -761,6 +761,20 @@ static inline bool is_cn10kb(struct rvu *rvu)
+ return false;
+ }
+
++static inline bool is_cgx_mapped_to_nix(unsigned short id, u8 cgx_id)
++{
++ /* On CNF10KA and CNF10KB silicons only two CGX blocks are connected
++ * to NIX.
++ */
++ if (id == PCI_SUBSYS_DEVID_CNF10K_A || id == PCI_SUBSYS_DEVID_CNF10K_B)
++ return cgx_id <= 1;
++
++ return !(cgx_id && !(id == PCI_SUBSYS_DEVID_96XX ||
++ id == PCI_SUBSYS_DEVID_98XX ||
++ id == PCI_SUBSYS_DEVID_CN10K_A ||
++ id == PCI_SUBSYS_DEVID_CN10K_B));
++}
++
+ static inline bool is_rvu_npc_hash_extract_en(struct rvu *rvu)
+ {
+ u64 npc_const3;
+--
+2.50.1
+
--- /dev/null
+From 57543e65e58d97f5b4ab29823a0643b02c1f3ac4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 16:31:51 +0530
+Subject: octeontx2: Set appropriate PF, VF masks and shifts based on silicon
+
+From: Subbaraya Sundeep <sbhatta@marvell.com>
+
+[ Upstream commit 25d51ebf0f54f9c2424f28bb29125cf24f120df0 ]
+
+Number of RVU PFs on CN20K silicon have increased to 96 from maximum
+of 32 that were supported on earlier silicons. Every RVU PF and VF is
+identified by HW using a 16bit PF_FUNC value. Due to the change in
+Max number of PFs in CN20K, the bit encoding of this PF_FUNC has changed.
+
+This patch handles the change by using helper functions(using silicon
+check) to use PF,VF masks and shifts to support both new silicon CN20K,
+OcteonTx series. These helper functions are used in different modules.
+
+Also moved the NIX AF register offset macros to other files which
+will be posted in coming patches.
+
+Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
+Signed-off-by: Sai Krishna <saikrishnag@marvell.com>
+Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com>
+Link: https://patch.msgid.link/1749639716-13868-2-git-send-email-sbhatta@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d280233fc866 ("Octeontx2-af: Fix NIX X2P calibration failures")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../marvell/octeontx2/otx2_cpt_common.h | 5 +-
+ .../marvell/octeontx2/otx2_cptpf_mbox.c | 13 ++--
+ .../marvell/octeontx2/otx2_cptpf_ucode.c | 4 +-
+ .../marvell/octeontx2/otx2_cptvf_mbox.c | 6 +-
+ .../marvell/octeontx2/af/mcs_rvu_if.c | 6 +-
+ .../net/ethernet/marvell/octeontx2/af/rvu.c | 30 ++++----
+ .../net/ethernet/marvell/octeontx2/af/rvu.h | 52 +++++++++++---
+ .../ethernet/marvell/octeontx2/af/rvu_cgx.c | 68 +++++++++----------
+ .../ethernet/marvell/octeontx2/af/rvu_cn10k.c | 4 +-
+ .../ethernet/marvell/octeontx2/af/rvu_cpt.c | 4 +-
+ .../marvell/octeontx2/af/rvu_debugfs.c | 22 +++---
+ .../ethernet/marvell/octeontx2/af/rvu_nix.c | 54 ++++++++-------
+ .../ethernet/marvell/octeontx2/af/rvu_npc.c | 8 ++-
+ .../marvell/octeontx2/af/rvu_npc_hash.c | 16 ++---
+ .../marvell/octeontx2/af/rvu_npc_hash.h | 4 +-
+ .../ethernet/marvell/octeontx2/af/rvu_rep.c | 13 ++--
+ .../ethernet/marvell/octeontx2/af/rvu_sdp.c | 10 +--
+ .../marvell/octeontx2/af/rvu_switch.c | 8 +--
+ .../marvell/octeontx2/nic/cn10k_ipsec.c | 2 +-
+ .../marvell/octeontx2/nic/cn10k_ipsec.h | 2 +-
+ .../marvell/octeontx2/nic/otx2_common.h | 11 +--
+ .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 21 +++---
+ .../ethernet/marvell/octeontx2/nic/otx2_reg.h | 30 --------
+ .../ethernet/marvell/octeontx2/nic/otx2_tc.c | 3 +-
+ .../net/ethernet/marvell/octeontx2/nic/rep.c | 7 +-
+ include/linux/soc/marvell/silicons.h | 25 +++++++
+ 26 files changed, 225 insertions(+), 203 deletions(-)
+ create mode 100644 include/linux/soc/marvell/silicons.h
+
+diff --git a/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h b/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h
+index d529bcb03775f..062def303dcea 100644
+--- a/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h
++++ b/drivers/crypto/marvell/octeontx2/otx2_cpt_common.h
+@@ -18,9 +18,8 @@
+ #define OTX2_CPT_MAX_VFS_NUM 128
+ #define OTX2_CPT_RVU_FUNC_ADDR_S(blk, slot, offs) \
+ (((blk) << 20) | ((slot) << 12) | (offs))
+-#define OTX2_CPT_RVU_PFFUNC(pf, func) \
+- ((((pf) & RVU_PFVF_PF_MASK) << RVU_PFVF_PF_SHIFT) | \
+- (((func) & RVU_PFVF_FUNC_MASK) << RVU_PFVF_FUNC_SHIFT))
++
++#define OTX2_CPT_RVU_PFFUNC(pdev, pf, func) rvu_make_pcifunc(pdev, pf, func)
+
+ #define OTX2_CPT_INVALID_CRYPTO_ENG_GRP 0xFF
+ #define OTX2_CPT_NAME_LENGTH 64
+diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
+index 12c0e966fa65f..b4b2d3d1cbc2a 100644
+--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
++++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_mbox.c
+@@ -142,7 +142,7 @@ static int send_inline_ipsec_inbound_msg(struct otx2_cptpf_dev *cptpf,
+ memset(req, 0, sizeof(*req));
+ req->hdr.id = MBOX_MSG_CPT_INLINE_IPSEC_CFG;
+ req->hdr.sig = OTX2_MBOX_REQ_SIG;
+- req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptpf->pf_id, 0);
++ req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptpf->pdev, cptpf->pf_id, 0);
+ req->dir = CPT_INLINE_INBOUND;
+ req->slot = slot;
+ req->sso_pf_func_ovrd = cptpf->sso_pf_func_ovrd;
+@@ -184,7 +184,8 @@ static int rx_inline_ipsec_lf_cfg(struct otx2_cptpf_dev *cptpf, u8 egrp,
+ nix_req->gen_cfg.opcode = cpt_inline_rx_opcode(pdev);
+ nix_req->gen_cfg.param1 = req->param1;
+ nix_req->gen_cfg.param2 = req->param2;
+- nix_req->inst_qsel.cpt_pf_func = OTX2_CPT_RVU_PFFUNC(cptpf->pf_id, 0);
++ nix_req->inst_qsel.cpt_pf_func =
++ OTX2_CPT_RVU_PFFUNC(cptpf->pdev, cptpf->pf_id, 0);
+ nix_req->inst_qsel.cpt_slot = 0;
+ ret = otx2_cpt_send_mbox_msg(&cptpf->afpf_mbox, pdev);
+ if (ret)
+@@ -392,9 +393,8 @@ void otx2_cptpf_vfpf_mbox_handler(struct work_struct *work)
+ msg = (struct mbox_msghdr *)(mdev->mbase + offset);
+
+ /* Set which VF sent this message based on mbox IRQ */
+- msg->pcifunc = ((u16)cptpf->pf_id << RVU_PFVF_PF_SHIFT) |
+- ((vf->vf_id + 1) & RVU_PFVF_FUNC_MASK);
+-
++ msg->pcifunc = rvu_make_pcifunc(cptpf->pdev, cptpf->pf_id,
++ (vf->vf_id + 1));
+ err = cptpf_handle_vf_req(cptpf, vf, msg,
+ msg->next_msgoff - offset);
+ /*
+@@ -469,8 +469,7 @@ static void process_afpf_mbox_msg(struct otx2_cptpf_dev *cptpf,
+
+ switch (msg->id) {
+ case MBOX_MSG_READY:
+- cptpf->pf_id = (msg->pcifunc >> RVU_PFVF_PF_SHIFT) &
+- RVU_PFVF_PF_MASK;
++ cptpf->pf_id = rvu_get_pf(cptpf->pdev, msg->pcifunc);
+ break;
+ case MBOX_MSG_MSIX_OFFSET:
+ rsp_msix = (struct msix_offset_rsp *) msg;
+diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
+index 56645b3eb7175..cc47e361089a0 100644
+--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
++++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c
+@@ -176,7 +176,9 @@ static int cptx_set_ucode_base(struct otx2_cpt_eng_grp_info *eng_grp,
+ /* Set PF number for microcode fetches */
+ ret = otx2_cpt_write_af_reg(&cptpf->afpf_mbox, cptpf->pdev,
+ CPT_AF_PF_FUNC,
+- cptpf->pf_id << RVU_PFVF_PF_SHIFT, blkaddr);
++ rvu_make_pcifunc(cptpf->pdev,
++ cptpf->pf_id, 0),
++ blkaddr);
+ if (ret)
+ return ret;
+
+diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_mbox.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_mbox.c
+index 931b72580fd9f..92e49babd79af 100644
+--- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_mbox.c
++++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_mbox.c
+@@ -189,7 +189,7 @@ int otx2_cptvf_send_eng_grp_num_msg(struct otx2_cptvf_dev *cptvf, int eng_type)
+ }
+ req->hdr.id = MBOX_MSG_GET_ENG_GRP_NUM;
+ req->hdr.sig = OTX2_MBOX_REQ_SIG;
+- req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0);
++ req->hdr.pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);
+ req->eng_type = eng_type;
+
+ return otx2_cpt_send_mbox_msg(mbox, pdev);
+@@ -210,7 +210,7 @@ int otx2_cptvf_send_kvf_limits_msg(struct otx2_cptvf_dev *cptvf)
+ }
+ req->id = MBOX_MSG_GET_KVF_LIMITS;
+ req->sig = OTX2_MBOX_REQ_SIG;
+- req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0);
++ req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);
+
+ return otx2_cpt_send_mbox_msg(mbox, pdev);
+ }
+@@ -230,7 +230,7 @@ int otx2_cptvf_send_caps_msg(struct otx2_cptvf_dev *cptvf)
+ }
+ req->id = MBOX_MSG_GET_CAPS;
+ req->sig = OTX2_MBOX_REQ_SIG;
+- req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->vf_id, 0);
++ req->pcifunc = OTX2_CPT_RVU_PFFUNC(cptvf->pdev, cptvf->vf_id, 0);
+
+ return otx2_cpt_send_mbox_msg(mbox, pdev);
+ }
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c b/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
+index 0277d226293e9..d7030dfa5dad2 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
+@@ -97,7 +97,7 @@ int mcs_add_intr_wq_entry(struct mcs *mcs, struct mcs_intr_event *event)
+ if (pcifunc & RVU_PFVF_FUNC_MASK)
+ pfvf = &mcs->vf[rvu_get_hwvf(rvu, pcifunc)];
+ else
+- pfvf = &mcs->pf[rvu_get_pf(pcifunc)];
++ pfvf = &mcs->pf[rvu_get_pf(rvu->pdev, pcifunc)];
+
+ event->intr_mask &= pfvf->intr_mask;
+
+@@ -123,7 +123,7 @@ static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu)
+ struct mcs_intr_info *req;
+ int pf;
+
+- pf = rvu_get_pf(event->pcifunc);
++ pf = rvu_get_pf(rvu->pdev, event->pcifunc);
+
+ mutex_lock(&rvu->mbox_lock);
+
+@@ -193,7 +193,7 @@ int rvu_mbox_handler_mcs_intr_cfg(struct rvu *rvu,
+ if (pcifunc & RVU_PFVF_FUNC_MASK)
+ pfvf = &mcs->vf[rvu_get_hwvf(rvu, pcifunc)];
+ else
+- pfvf = &mcs->pf[rvu_get_pf(pcifunc)];
++ pfvf = &mcs->pf[rvu_get_pf(rvu->pdev, pcifunc)];
+
+ mcs->pf_map[0] = pcifunc;
+ pfvf->intr_mask = req->intr_mask;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+index a8025f0486c9f..39f664d60ecff 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+@@ -294,7 +294,7 @@ int rvu_get_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc)
+ devnum = rvu_get_hwvf(rvu, pcifunc);
+ } else {
+ is_pf = true;
+- devnum = rvu_get_pf(pcifunc);
++ devnum = rvu_get_pf(rvu->pdev, pcifunc);
+ }
+
+ /* Check if the 'pcifunc' has a NIX LF from 'BLKADDR_NIX0' or
+@@ -359,7 +359,7 @@ static void rvu_update_rsrc_map(struct rvu *rvu, struct rvu_pfvf *pfvf,
+ devnum = rvu_get_hwvf(rvu, pcifunc);
+ } else {
+ is_pf = true;
+- devnum = rvu_get_pf(pcifunc);
++ devnum = rvu_get_pf(rvu->pdev, pcifunc);
+ }
+
+ block->fn_map[lf] = attach ? pcifunc : 0;
+@@ -400,11 +400,6 @@ static void rvu_update_rsrc_map(struct rvu *rvu, struct rvu_pfvf *pfvf,
+ rvu_write64(rvu, BLKADDR_RVUM, reg | (devnum << 16), num_lfs);
+ }
+
+-inline int rvu_get_pf(u16 pcifunc)
+-{
+- return (pcifunc >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;
+-}
+-
+ void rvu_get_pf_numvfs(struct rvu *rvu, int pf, int *numvfs, int *hwvf)
+ {
+ u64 cfg;
+@@ -422,7 +417,7 @@ int rvu_get_hwvf(struct rvu *rvu, int pcifunc)
+ int pf, func;
+ u64 cfg;
+
+- pf = rvu_get_pf(pcifunc);
++ pf = rvu_get_pf(rvu->pdev, pcifunc);
+ func = pcifunc & RVU_PFVF_FUNC_MASK;
+
+ /* Get first HWVF attached to this PF */
+@@ -437,7 +432,7 @@ struct rvu_pfvf *rvu_get_pfvf(struct rvu *rvu, int pcifunc)
+ if (pcifunc & RVU_PFVF_FUNC_MASK)
+ return &rvu->hwvf[rvu_get_hwvf(rvu, pcifunc)];
+ else
+- return &rvu->pf[rvu_get_pf(pcifunc)];
++ return &rvu->pf[rvu_get_pf(rvu->pdev, pcifunc)];
+ }
+
+ static bool is_pf_func_valid(struct rvu *rvu, u16 pcifunc)
+@@ -445,7 +440,7 @@ static bool is_pf_func_valid(struct rvu *rvu, u16 pcifunc)
+ int pf, vf, nvfs;
+ u64 cfg;
+
+- pf = rvu_get_pf(pcifunc);
++ pf = rvu_get_pf(rvu->pdev, pcifunc);
+ if (pf >= rvu->hw->total_pfs)
+ return false;
+
+@@ -1487,7 +1482,7 @@ int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
+ pf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
+
+ /* All CGX mapped PFs are set with assigned NIX block during init */
+- if (is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc))) {
++ if (is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc))) {
+ blkaddr = pf->nix_blkaddr;
+ } else if (is_lbk_vf(rvu, pcifunc)) {
+ vf = pcifunc - 1;
+@@ -1501,7 +1496,7 @@ int rvu_get_nix_blkaddr(struct rvu *rvu, u16 pcifunc)
+ }
+
+ /* if SDP1 then the blkaddr is NIX1 */
+- if (is_sdp_pfvf(pcifunc) && pf->sdp_info->node_id == 1)
++ if (is_sdp_pfvf(rvu, pcifunc) && pf->sdp_info->node_id == 1)
+ blkaddr = BLKADDR_NIX1;
+
+ switch (blkaddr) {
+@@ -2006,7 +2001,7 @@ int rvu_mbox_handler_vf_flr(struct rvu *rvu, struct msg_req *req,
+
+ vf = pcifunc & RVU_PFVF_FUNC_MASK;
+ cfg = rvu_read64(rvu, BLKADDR_RVUM,
+- RVU_PRIV_PFX_CFG(rvu_get_pf(pcifunc)));
++ RVU_PRIV_PFX_CFG(rvu_get_pf(rvu->pdev, pcifunc)));
+ numvfs = (cfg >> 12) & 0xFF;
+
+ if (vf && vf <= numvfs)
+@@ -2229,9 +2224,8 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type, bool poll)
+ /* Set which PF/VF sent this message based on mbox IRQ */
+ switch (type) {
+ case TYPE_AFPF:
+- msg->pcifunc &=
+- ~(RVU_PFVF_PF_MASK << RVU_PFVF_PF_SHIFT);
+- msg->pcifunc |= (devid << RVU_PFVF_PF_SHIFT);
++ msg->pcifunc &= rvu_pcifunc_pf_mask(rvu->pdev);
++ msg->pcifunc |= rvu_make_pcifunc(rvu->pdev, devid, 0);
+ break;
+ case TYPE_AFVF:
+ msg->pcifunc &=
+@@ -2249,7 +2243,7 @@ static void __rvu_mbox_handler(struct rvu_work *mwork, int type, bool poll)
+ if (msg->pcifunc & RVU_PFVF_FUNC_MASK)
+ dev_warn(rvu->dev, "Error %d when processing message %s (0x%x) from PF%d:VF%d\n",
+ err, otx2_mbox_id2name(msg->id),
+- msg->id, rvu_get_pf(msg->pcifunc),
++ msg->id, rvu_get_pf(rvu->pdev, msg->pcifunc),
+ (msg->pcifunc & RVU_PFVF_FUNC_MASK) - 1);
+ else
+ dev_warn(rvu->dev, "Error %d when processing message %s (0x%x) from PF%d\n",
+@@ -2773,7 +2767,7 @@ static void rvu_flr_handler(struct work_struct *work)
+
+ cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf));
+ numvfs = (cfg >> 12) & 0xFF;
+- pcifunc = pf << RVU_PFVF_PF_SHIFT;
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+
+ for (vf = 0; vf < numvfs; vf++)
+ __rvu_flr_handler(rvu, (pcifunc | (vf + 1)));
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+index 48f66292ad5c5..5c179df1f1673 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+@@ -10,6 +10,7 @@
+
+ #include <linux/pci.h>
+ #include <net/devlink.h>
++#include <linux/soc/marvell/silicons.h>
+
+ #include "rvu_struct.h"
+ #include "rvu_devlink.h"
+@@ -43,10 +44,34 @@
+ #define MAX_CPT_BLKS 2
+
+ /* PF_FUNC */
+-#define RVU_PFVF_PF_SHIFT 10
+-#define RVU_PFVF_PF_MASK 0x3F
+-#define RVU_PFVF_FUNC_SHIFT 0
+-#define RVU_PFVF_FUNC_MASK 0x3FF
++#define RVU_OTX2_PFVF_PF_SHIFT 10
++#define RVU_OTX2_PFVF_PF_MASK 0x3F
++#define RVU_PFVF_FUNC_SHIFT 0
++#define RVU_PFVF_FUNC_MASK 0x3FF
++#define RVU_CN20K_PFVF_PF_SHIFT 9
++#define RVU_CN20K_PFVF_PF_MASK 0x7F
++
++static inline u16 rvu_make_pcifunc(struct pci_dev *pdev, int pf, int func)
++{
++ if (is_cn20k(pdev))
++ return ((pf & RVU_CN20K_PFVF_PF_MASK) <<
++ RVU_CN20K_PFVF_PF_SHIFT) |
++ ((func & RVU_PFVF_FUNC_MASK) <<
++ RVU_PFVF_FUNC_SHIFT);
++ else
++ return ((pf & RVU_OTX2_PFVF_PF_MASK) <<
++ RVU_OTX2_PFVF_PF_SHIFT) |
++ ((func & RVU_PFVF_FUNC_MASK) <<
++ RVU_PFVF_FUNC_SHIFT);
++}
++
++static inline int rvu_pcifunc_pf_mask(struct pci_dev *pdev)
++{
++ if (is_cn20k(pdev))
++ return ~(RVU_CN20K_PFVF_PF_MASK << RVU_CN20K_PFVF_PF_SHIFT);
++ else
++ return ~(RVU_OTX2_PFVF_PF_MASK << RVU_OTX2_PFVF_PF_SHIFT);
++}
+
+ #ifdef CONFIG_DEBUG_FS
+ struct dump_ctx {
+@@ -836,7 +861,6 @@ int rvu_alloc_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc);
+ void rvu_free_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc, int start);
+ bool rvu_rsrc_check_contig(struct rsrc_bmap *rsrc, int nrsrc);
+ u16 rvu_get_rsrc_mapcount(struct rvu_pfvf *pfvf, int blkaddr);
+-int rvu_get_pf(u16 pcifunc);
+ struct rvu_pfvf *rvu_get_pfvf(struct rvu *rvu, int pcifunc);
+ void rvu_get_pf_numvfs(struct rvu *rvu, int pf, int *numvfs, int *hwvf);
+ bool is_block_implemented(struct rvu_hwinfo *hw, int blkaddr);
+@@ -865,8 +889,8 @@ void rvu_aq_free(struct rvu *rvu, struct admin_queue *aq);
+
+ /* SDP APIs */
+ int rvu_sdp_init(struct rvu *rvu);
+-bool is_sdp_pfvf(u16 pcifunc);
+-bool is_sdp_pf(u16 pcifunc);
++bool is_sdp_pfvf(struct rvu *rvu, u16 pcifunc);
++bool is_sdp_pf(struct rvu *rvu, u16 pcifunc);
+ bool is_sdp_vf(struct rvu *rvu, u16 pcifunc);
+
+ static inline bool is_rep_dev(struct rvu *rvu, u16 pcifunc)
+@@ -877,11 +901,21 @@ static inline bool is_rep_dev(struct rvu *rvu, u16 pcifunc)
+ return false;
+ }
+
++static inline int rvu_get_pf(struct pci_dev *pdev, u16 pcifunc)
++{
++ if (is_cn20k(pdev))
++ return (pcifunc >> RVU_CN20K_PFVF_PF_SHIFT) &
++ RVU_CN20K_PFVF_PF_MASK;
++ else
++ return (pcifunc >> RVU_OTX2_PFVF_PF_SHIFT) &
++ RVU_OTX2_PFVF_PF_MASK;
++}
++
+ /* CGX APIs */
+ static inline bool is_pf_cgxmapped(struct rvu *rvu, u8 pf)
+ {
+ return (pf >= PF_CGXMAP_BASE && pf <= rvu->cgx_mapped_pfs) &&
+- !is_sdp_pf(pf << RVU_PFVF_PF_SHIFT);
++ !is_sdp_pf(rvu, rvu_make_pcifunc(rvu->pdev, pf, 0));
+ }
+
+ static inline void rvu_get_cgx_lmac_id(u8 map, u8 *cgx_id, u8 *lmac_id)
+@@ -893,7 +927,7 @@ static inline void rvu_get_cgx_lmac_id(u8 map, u8 *cgx_id, u8 *lmac_id)
+ static inline bool is_cgx_vf(struct rvu *rvu, u16 pcifunc)
+ {
+ return ((pcifunc & RVU_PFVF_FUNC_MASK) &&
+- is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)));
++ is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc)));
+ }
+
+ #define M(_name, _id, fn_name, req, rsp) \
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+index d0331b0e0bfd4..b79db887ab9b2 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+@@ -457,7 +457,7 @@ int rvu_cgx_exit(struct rvu *rvu)
+ inline bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc)
+ {
+ if ((pcifunc & RVU_PFVF_FUNC_MASK) ||
+- !is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
++ !is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc)))
+ return false;
+ return true;
+ }
+@@ -484,7 +484,7 @@ void rvu_cgx_enadis_rx_bp(struct rvu *rvu, int pf, bool enable)
+
+ int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start)
+ {
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ struct mac_ops *mac_ops;
+ u8 cgx_id, lmac_id;
+ void *cgxd;
+@@ -501,7 +501,7 @@ int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start)
+
+ int rvu_cgx_tx_enable(struct rvu *rvu, u16 pcifunc, bool enable)
+ {
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ struct mac_ops *mac_ops;
+ u8 cgx_id, lmac_id;
+ void *cgxd;
+@@ -526,7 +526,7 @@ int rvu_cgx_config_tx(void *cgxd, int lmac_id, bool enable)
+
+ void rvu_cgx_disable_dmac_entries(struct rvu *rvu, u16 pcifunc)
+ {
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ int i = 0, lmac_count = 0;
+ struct mac_ops *mac_ops;
+ u8 max_dmac_filters;
+@@ -577,7 +577,7 @@ int rvu_mbox_handler_cgx_stop_rxtx(struct rvu *rvu, struct msg_req *req,
+ static int rvu_lmac_get_stats(struct rvu *rvu, struct msg_req *req,
+ void *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ struct mac_ops *mac_ops;
+ int stat = 0, err = 0;
+ u64 tx_stat, rx_stat;
+@@ -633,7 +633,7 @@ int rvu_mbox_handler_rpm_stats(struct rvu *rvu, struct msg_req *req,
+ int rvu_mbox_handler_cgx_stats_rst(struct rvu *rvu, struct msg_req *req,
+ struct msg_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ struct rvu_pfvf *parent_pf;
+ struct mac_ops *mac_ops;
+ u8 cgx_idx, lmac;
+@@ -663,7 +663,7 @@ int rvu_mbox_handler_cgx_fec_stats(struct rvu *rvu,
+ struct msg_req *req,
+ struct cgx_fec_stats_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ struct mac_ops *mac_ops;
+ u8 cgx_idx, lmac;
+ void *cgxd;
+@@ -681,7 +681,7 @@ int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu,
+ struct cgx_mac_addr_set_or_get *req,
+ struct cgx_mac_addr_set_or_get *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -701,7 +701,7 @@ int rvu_mbox_handler_cgx_mac_addr_add(struct rvu *rvu,
+ struct cgx_mac_addr_add_req *req,
+ struct cgx_mac_addr_add_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+ int rc = 0;
+
+@@ -725,7 +725,7 @@ int rvu_mbox_handler_cgx_mac_addr_del(struct rvu *rvu,
+ struct cgx_mac_addr_del_req *req,
+ struct msg_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -743,7 +743,7 @@ int rvu_mbox_handler_cgx_mac_max_entries_get(struct rvu *rvu,
+ struct cgx_max_dmac_entries_get_rsp
+ *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ /* If msg is received from PFs(which are not mapped to CGX LMACs)
+@@ -769,7 +769,7 @@ int rvu_mbox_handler_cgx_mac_addr_get(struct rvu *rvu,
+ struct cgx_mac_addr_set_or_get *req,
+ struct cgx_mac_addr_set_or_get *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+ int rc = 0;
+ u64 cfg;
+@@ -790,7 +790,7 @@ int rvu_mbox_handler_cgx_promisc_enable(struct rvu *rvu, struct msg_req *req,
+ struct msg_rsp *rsp)
+ {
+ u16 pcifunc = req->hdr.pcifunc;
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -809,7 +809,7 @@ int rvu_mbox_handler_cgx_promisc_enable(struct rvu *rvu, struct msg_req *req,
+ int rvu_mbox_handler_cgx_promisc_disable(struct rvu *rvu, struct msg_req *req,
+ struct msg_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -828,7 +828,7 @@ int rvu_mbox_handler_cgx_promisc_disable(struct rvu *rvu, struct msg_req *req,
+ static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
+ {
+ struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ struct mac_ops *mac_ops;
+ u8 cgx_id, lmac_id;
+ void *cgxd;
+@@ -864,7 +864,7 @@ static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
+ int rvu_mbox_handler_cgx_ptp_rx_enable(struct rvu *rvu, struct msg_req *req,
+ struct msg_rsp *rsp)
+ {
+- if (!is_pf_cgxmapped(rvu, rvu_get_pf(req->hdr.pcifunc)))
++ if (!is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, req->hdr.pcifunc)))
+ return -EPERM;
+
+ return rvu_cgx_ptp_rx_cfg(rvu, req->hdr.pcifunc, true);
+@@ -878,7 +878,7 @@ int rvu_mbox_handler_cgx_ptp_rx_disable(struct rvu *rvu, struct msg_req *req,
+
+ static int rvu_cgx_config_linkevents(struct rvu *rvu, u16 pcifunc, bool en)
+ {
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_cgx_config_permitted(rvu, pcifunc))
+@@ -917,7 +917,7 @@ int rvu_mbox_handler_cgx_get_linkinfo(struct rvu *rvu, struct msg_req *req,
+ u8 cgx_id, lmac_id;
+ int pf, err;
+
+- pf = rvu_get_pf(req->hdr.pcifunc);
++ pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+
+ if (!is_pf_cgxmapped(rvu, pf))
+ return -ENODEV;
+@@ -933,7 +933,7 @@ int rvu_mbox_handler_cgx_features_get(struct rvu *rvu,
+ struct msg_req *req,
+ struct cgx_features_info_msg *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_idx, lmac;
+ void *cgxd;
+
+@@ -975,7 +975,7 @@ u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac)
+
+ static int rvu_cgx_config_intlbk(struct rvu *rvu, u16 pcifunc, bool en)
+ {
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ struct mac_ops *mac_ops;
+ u8 cgx_id, lmac_id;
+
+@@ -1005,7 +1005,7 @@ int rvu_mbox_handler_cgx_intlbk_disable(struct rvu *rvu, struct msg_req *req,
+
+ int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause)
+ {
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ u8 rx_pfc = 0, tx_pfc = 0;
+ struct mac_ops *mac_ops;
+ u8 cgx_id, lmac_id;
+@@ -1046,7 +1046,7 @@ int rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu *rvu,
+ struct cgx_pause_frm_cfg *req,
+ struct cgx_pause_frm_cfg *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ struct mac_ops *mac_ops;
+ u8 cgx_id, lmac_id;
+ int err = 0;
+@@ -1073,7 +1073,7 @@ int rvu_mbox_handler_cgx_cfg_pause_frm(struct rvu *rvu,
+ int rvu_mbox_handler_cgx_get_phy_fec_stats(struct rvu *rvu, struct msg_req *req,
+ struct msg_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_pf_cgxmapped(rvu, pf))
+@@ -1106,7 +1106,7 @@ int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id,
+ /* Assumes LF of a PF and all of its VF belongs to the same
+ * NIX block
+ */
+- pcifunc = pf << RVU_PFVF_PF_SHIFT;
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+ blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+ if (blkaddr < 0)
+ return 0;
+@@ -1133,10 +1133,10 @@ int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start)
+ struct rvu_pfvf *parent_pf, *pfvf;
+ int cgx_users, err = 0;
+
+- if (!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
++ if (!is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc)))
+ return 0;
+
+- parent_pf = &rvu->pf[rvu_get_pf(pcifunc)];
++ parent_pf = &rvu->pf[rvu_get_pf(rvu->pdev, pcifunc)];
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+ mutex_lock(&rvu->cgx_cfg_lock);
+@@ -1179,7 +1179,7 @@ int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu,
+ struct fec_mode *req,
+ struct fec_mode *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_pf_cgxmapped(rvu, pf))
+@@ -1195,7 +1195,7 @@ int rvu_mbox_handler_cgx_set_fec_param(struct rvu *rvu,
+ int rvu_mbox_handler_cgx_get_aux_link_info(struct rvu *rvu, struct msg_req *req,
+ struct cgx_fw_data *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!rvu->fwdata)
+@@ -1222,7 +1222,7 @@ int rvu_mbox_handler_cgx_set_link_mode(struct rvu *rvu,
+ struct cgx_set_link_mode_req *req,
+ struct cgx_set_link_mode_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_idx, lmac;
+ void *cgxd;
+
+@@ -1238,7 +1238,7 @@ int rvu_mbox_handler_cgx_set_link_mode(struct rvu *rvu,
+ int rvu_mbox_handler_cgx_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req,
+ struct msg_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -1256,7 +1256,7 @@ int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
+ struct cgx_mac_addr_update_req *req,
+ struct cgx_mac_addr_update_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+@@ -1272,7 +1272,7 @@ int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
+ int rvu_cgx_prio_flow_ctrl_cfg(struct rvu *rvu, u16 pcifunc, u8 tx_pause,
+ u8 rx_pause, u16 pfc_en)
+ {
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ u8 rx_8023 = 0, tx_8023 = 0;
+ struct mac_ops *mac_ops;
+ u8 cgx_id, lmac_id;
+@@ -1310,7 +1310,7 @@ int rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu *rvu,
+ struct cgx_pfc_cfg *req,
+ struct cgx_pfc_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ struct mac_ops *mac_ops;
+ u8 cgx_id, lmac_id;
+ void *cgxd;
+@@ -1335,7 +1335,7 @@ int rvu_mbox_handler_cgx_prio_flow_ctrl_cfg(struct rvu *rvu,
+
+ void rvu_mac_reset(struct rvu *rvu, u16 pcifunc)
+ {
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ struct mac_ops *mac_ops;
+ struct cgx *cgxd;
+ u8 cgx, lmac;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c
+index 4a3370a40dd88..05adc54535eb3 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c
+@@ -66,7 +66,7 @@ static int lmtst_map_table_ops(struct rvu *rvu, u32 index, u64 *val,
+ #define LMT_MAP_TBL_W1_OFF 8
+ static u32 rvu_get_lmtst_tbl_index(struct rvu *rvu, u16 pcifunc)
+ {
+- return ((rvu_get_pf(pcifunc) * LMT_MAX_VFS) +
++ return ((rvu_get_pf(rvu->pdev, pcifunc) * LMT_MAX_VFS) +
+ (pcifunc & RVU_PFVF_FUNC_MASK)) * LMT_MAPTBL_ENTRY_SIZE;
+ }
+
+@@ -83,7 +83,7 @@ static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
+
+ mutex_lock(&rvu->rsrc_lock);
+ rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_REQ, iova);
+- pf = rvu_get_pf(pcifunc) & RVU_PFVF_PF_MASK;
++ pf = rvu_get_pf(rvu->pdev, pcifunc) & RVU_OTX2_PFVF_PF_MASK;
+ val = BIT_ULL(63) | BIT_ULL(14) | BIT_ULL(13) | pf << 8 |
+ ((pcifunc & RVU_PFVF_FUNC_MASK) & 0xFF);
+ rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TXN_REQ, val);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c
+index 3c5bbaf12e594..f404117bf6c8c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c
+@@ -410,7 +410,7 @@ static bool is_cpt_pf(struct rvu *rvu, u16 pcifunc)
+ {
+ int cpt_pf_num = rvu->cpt_pf_num;
+
+- if (rvu_get_pf(pcifunc) != cpt_pf_num)
++ if (rvu_get_pf(rvu->pdev, pcifunc) != cpt_pf_num)
+ return false;
+ if (pcifunc & RVU_PFVF_FUNC_MASK)
+ return false;
+@@ -422,7 +422,7 @@ static bool is_cpt_vf(struct rvu *rvu, u16 pcifunc)
+ {
+ int cpt_pf_num = rvu->cpt_pf_num;
+
+- if (rvu_get_pf(pcifunc) != cpt_pf_num)
++ if (rvu_get_pf(rvu->pdev, pcifunc) != cpt_pf_num)
+ return false;
+ if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+ return false;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+index c827da6264712..0c20642f81b9b 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+@@ -688,7 +688,7 @@ static int get_max_column_width(struct rvu *rvu)
+
+ for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
+ for (vf = 0; vf <= rvu->hw->total_vfs; vf++) {
+- pcifunc = pf << 10 | vf;
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, vf);
+ if (!pcifunc)
+ continue;
+
+@@ -759,7 +759,7 @@ static ssize_t rvu_dbg_rsrc_attach_status(struct file *filp,
+ for (vf = 0; vf <= rvu->hw->total_vfs; vf++) {
+ off = 0;
+ flag = 0;
+- pcifunc = pf << 10 | vf;
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, vf);
+ if (!pcifunc)
+ continue;
+
+@@ -842,7 +842,7 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)
+
+ cgx[0] = 0;
+ lmac[0] = 0;
+- pcifunc = pf << 10;
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+ if (pfvf->nix_blkaddr == BLKADDR_NIX0)
+@@ -2623,10 +2623,10 @@ static int rvu_dbg_nix_band_prof_ctx_display(struct seq_file *m, void *unused)
+ pcifunc = ipolicer->pfvf_map[idx];
+ if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+ seq_printf(m, "Allocated to :: PF %d\n",
+- rvu_get_pf(pcifunc));
++ rvu_get_pf(rvu->pdev, pcifunc));
+ else
+ seq_printf(m, "Allocated to :: PF %d VF %d\n",
+- rvu_get_pf(pcifunc),
++ rvu_get_pf(rvu->pdev, pcifunc),
+ (pcifunc & RVU_PFVF_FUNC_MASK) - 1);
+ print_band_prof_ctx(m, &aq_rsp.prof);
+ }
+@@ -2983,10 +2983,10 @@ static void rvu_print_npc_mcam_info(struct seq_file *s,
+
+ if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+ seq_printf(s, "\n\t\t Device \t\t: PF%d\n",
+- rvu_get_pf(pcifunc));
++ rvu_get_pf(rvu->pdev, pcifunc));
+ else
+ seq_printf(s, "\n\t\t Device \t\t: PF%d VF%d\n",
+- rvu_get_pf(pcifunc),
++ rvu_get_pf(rvu->pdev, pcifunc),
+ (pcifunc & RVU_PFVF_FUNC_MASK) - 1);
+
+ if (entry_acnt) {
+@@ -3049,13 +3049,13 @@ static int rvu_dbg_npc_mcam_info_display(struct seq_file *filp, void *unsued)
+ seq_puts(filp, "\n\t\t Current allocation\n");
+ seq_puts(filp, "\t\t====================\n");
+ for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
+- pcifunc = (pf << RVU_PFVF_PF_SHIFT);
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+ rvu_print_npc_mcam_info(filp, pcifunc, blkaddr);
+
+ cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf));
+ numvfs = (cfg >> 12) & 0xFF;
+ for (vf = 0; vf < numvfs; vf++) {
+- pcifunc = (pf << RVU_PFVF_PF_SHIFT) | (vf + 1);
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, (vf + 1));
+ rvu_print_npc_mcam_info(filp, pcifunc, blkaddr);
+ }
+ }
+@@ -3326,7 +3326,7 @@ static int rvu_dbg_npc_mcam_show_rules(struct seq_file *s, void *unused)
+
+ mutex_lock(&mcam->lock);
+ list_for_each_entry(iter, &mcam->mcam_rules, list) {
+- pf = (iter->owner >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;
++ pf = rvu_get_pf(rvu->pdev, iter->owner);
+ seq_printf(s, "\n\tInstalled by: PF%d ", pf);
+
+ if (iter->owner & RVU_PFVF_FUNC_MASK) {
+@@ -3344,7 +3344,7 @@ static int rvu_dbg_npc_mcam_show_rules(struct seq_file *s, void *unused)
+ rvu_dbg_npc_mcam_show_flows(s, iter);
+ if (is_npc_intf_rx(iter->intf)) {
+ target = iter->rx_action.pf_func;
+- pf = (target >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;
++ pf = rvu_get_pf(rvu->pdev, target);
+ seq_printf(s, "\tForward to: PF%d ", pf);
+
+ if (target & RVU_PFVF_FUNC_MASK) {
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+index 613655fcd34f4..bdf4d852c15de 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+@@ -315,7 +315,8 @@ static bool is_valid_txschq(struct rvu *rvu, int blkaddr,
+ if (lvl >= hw->cap.nix_tx_aggr_lvl) {
+ if ((nix_get_tx_link(rvu, map_func) !=
+ nix_get_tx_link(rvu, pcifunc)) &&
+- (rvu_get_pf(map_func) != rvu_get_pf(pcifunc)))
++ (rvu_get_pf(rvu->pdev, map_func) !=
++ rvu_get_pf(rvu->pdev, pcifunc)))
+ return false;
+ else
+ return true;
+@@ -339,7 +340,7 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf,
+ bool from_vf;
+ int err;
+
+- pf = rvu_get_pf(pcifunc);
++ pf = rvu_get_pf(rvu->pdev, pcifunc);
+ if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK &&
+ type != NIX_INTF_TYPE_SDP)
+ return 0;
+@@ -416,7 +417,7 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf,
+ break;
+ case NIX_INTF_TYPE_SDP:
+ from_vf = !!(pcifunc & RVU_PFVF_FUNC_MASK);
+- parent_pf = &rvu->pf[rvu_get_pf(pcifunc)];
++ parent_pf = &rvu->pf[rvu_get_pf(rvu->pdev, pcifunc)];
+ sdp_info = parent_pf->sdp_info;
+ if (!sdp_info) {
+ dev_err(rvu->dev, "Invalid sdp_info pointer\n");
+@@ -590,12 +591,12 @@ static int nix_bp_disable(struct rvu *rvu,
+ u16 chan_v;
+ u64 cfg;
+
+- pf = rvu_get_pf(pcifunc);
++ pf = rvu_get_pf(rvu->pdev, pcifunc);
+ type = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX;
+ if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK)
+ return 0;
+
+- if (is_sdp_pfvf(pcifunc))
++ if (is_sdp_pfvf(rvu, pcifunc))
+ type = NIX_INTF_TYPE_SDP;
+
+ if (cpt_link && !rvu->hw->cpt_links)
+@@ -736,9 +737,9 @@ static int nix_bp_enable(struct rvu *rvu,
+ u16 chan_v;
+ u64 cfg;
+
+- pf = rvu_get_pf(pcifunc);
++ pf = rvu_get_pf(rvu->pdev, pcifunc);
+ type = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX;
+- if (is_sdp_pfvf(pcifunc))
++ if (is_sdp_pfvf(rvu, pcifunc))
+ type = NIX_INTF_TYPE_SDP;
+
+ /* Enable backpressure only for CGX mapped PFs and LBK/SDP interface */
+@@ -1674,7 +1675,7 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
+ }
+
+ intf = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX;
+- if (is_sdp_pfvf(pcifunc))
++ if (is_sdp_pfvf(rvu, pcifunc))
+ intf = NIX_INTF_TYPE_SDP;
+
+ err = nix_interface_init(rvu, pcifunc, intf, nixlf, rsp,
+@@ -1798,7 +1799,8 @@ int rvu_mbox_handler_nix_mark_format_cfg(struct rvu *rvu,
+ rc = rvu_nix_reserve_mark_format(rvu, nix_hw, blkaddr, cfg);
+ if (rc < 0) {
+ dev_err(rvu->dev, "No mark_format_ctl for (pf:%d, vf:%d)",
+- rvu_get_pf(pcifunc), pcifunc & RVU_PFVF_FUNC_MASK);
++ rvu_get_pf(rvu->pdev, pcifunc),
++ pcifunc & RVU_PFVF_FUNC_MASK);
+ return NIX_AF_ERR_MARK_CFG_FAIL;
+ }
+
+@@ -2050,7 +2052,7 @@ static void nix_clear_tx_xoff(struct rvu *rvu, int blkaddr,
+ static int nix_get_tx_link(struct rvu *rvu, u16 pcifunc)
+ {
+ struct rvu_hwinfo *hw = rvu->hw;
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ u8 cgx_id = 0, lmac_id = 0;
+
+ if (is_lbk_vf(rvu, pcifunc)) {/* LBK links */
+@@ -2068,7 +2070,7 @@ static void nix_get_txschq_range(struct rvu *rvu, u16 pcifunc,
+ int link, int *start, int *end)
+ {
+ struct rvu_hwinfo *hw = rvu->hw;
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+
+ /* LBK links */
+ if (is_lbk_vf(rvu, pcifunc) || is_rep_dev(rvu, pcifunc)) {
+@@ -2426,7 +2428,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr,
+ {
+ struct nix_smq_flush_ctx *smq_flush_ctx;
+ int err, restore_tx_en = 0, i;
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ u8 cgx_id = 0, lmac_id = 0;
+ u16 tl2_tl3_link_schq;
+ u8 link, link_level;
+@@ -2820,7 +2822,7 @@ void rvu_nix_tx_tl2_cfg(struct rvu *rvu, int blkaddr, u16 pcifunc,
+ {
+ struct rvu_hwinfo *hw = rvu->hw;
+ int lbk_link_start, lbk_links;
+- u8 pf = rvu_get_pf(pcifunc);
++ u8 pf = rvu_get_pf(rvu->pdev, pcifunc);
+ int schq;
+ u64 cfg;
+
+@@ -3190,7 +3192,8 @@ static int nix_blk_setup_mce(struct rvu *rvu, struct nix_hw *nix_hw,
+ err = rvu_nix_blk_aq_enq_inst(rvu, nix_hw, &aq_req, NULL);
+ if (err) {
+ dev_err(rvu->dev, "Failed to setup Bcast MCE for PF%d:VF%d\n",
+- rvu_get_pf(pcifunc), pcifunc & RVU_PFVF_FUNC_MASK);
++ rvu_get_pf(rvu->pdev, pcifunc),
++ pcifunc & RVU_PFVF_FUNC_MASK);
+ return err;
+ }
+ return 0;
+@@ -3458,7 +3461,7 @@ int nix_update_mce_list(struct rvu *rvu, u16 pcifunc,
+ dev_err(rvu->dev,
+ "%s: Idx %d > max MCE idx %d, for PF%d bcast list\n",
+ __func__, idx, mce_list->max,
+- pcifunc >> RVU_PFVF_PF_SHIFT);
++ rvu_get_pf(rvu->pdev, pcifunc));
+ return -EINVAL;
+ }
+
+@@ -3510,7 +3513,8 @@ void nix_get_mce_list(struct rvu *rvu, u16 pcifunc, int type,
+ struct rvu_pfvf *pfvf;
+
+ if (!hw->cap.nix_rx_multicast ||
+- !is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc & ~RVU_PFVF_FUNC_MASK))) {
++ !is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev,
++ pcifunc & ~RVU_PFVF_FUNC_MASK))) {
+ *mce_list = NULL;
+ *mce_idx = 0;
+ return;
+@@ -3544,13 +3548,13 @@ static int nix_update_mce_rule(struct rvu *rvu, u16 pcifunc,
+ int pf;
+
+ /* skip multicast pkt replication for AF's VFs & SDP links */
+- if (is_lbk_vf(rvu, pcifunc) || is_sdp_pfvf(pcifunc))
++ if (is_lbk_vf(rvu, pcifunc) || is_sdp_pfvf(rvu, pcifunc))
+ return 0;
+
+ if (!hw->cap.nix_rx_multicast)
+ return 0;
+
+- pf = rvu_get_pf(pcifunc);
++ pf = rvu_get_pf(rvu->pdev, pcifunc);
+ if (!is_pf_cgxmapped(rvu, pf))
+ return 0;
+
+@@ -3619,7 +3623,7 @@ static int nix_setup_mce_tables(struct rvu *rvu, struct nix_hw *nix_hw)
+
+ for (idx = 0; idx < (numvfs + 1); idx++) {
+ /* idx-0 is for PF, followed by VFs */
+- pcifunc = (pf << RVU_PFVF_PF_SHIFT);
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+ pcifunc |= idx;
+ /* Add dummy entries now, so that we don't have to check
+ * for whether AQ_OP should be INIT/WRITE later on.
+@@ -4554,7 +4558,7 @@ int rvu_mbox_handler_nix_set_rx_mode(struct rvu *rvu, struct nix_rx_mode *req,
+ static void nix_find_link_frs(struct rvu *rvu,
+ struct nix_frs_cfg *req, u16 pcifunc)
+ {
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ struct rvu_pfvf *pfvf;
+ int maxlen, minlen;
+ int numvfs, hwvf;
+@@ -4601,7 +4605,7 @@ int rvu_mbox_handler_nix_set_hw_frs(struct rvu *rvu, struct nix_frs_cfg *req,
+ {
+ struct rvu_hwinfo *hw = rvu->hw;
+ u16 pcifunc = req->hdr.pcifunc;
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ int blkaddr, link = -1;
+ struct nix_hw *nix_hw;
+ struct rvu_pfvf *pfvf;
+@@ -5251,7 +5255,7 @@ int rvu_mbox_handler_nix_lf_start_rx(struct rvu *rvu, struct msg_req *req,
+
+ rvu_switch_update_rules(rvu, pcifunc, true);
+
+- pf = rvu_get_pf(pcifunc);
++ pf = rvu_get_pf(rvu->pdev, pcifunc);
+ if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode)
+ rvu_rep_notify_pfvf_state(rvu, pcifunc, true);
+
+@@ -5284,7 +5288,7 @@ int rvu_mbox_handler_nix_lf_stop_rx(struct rvu *rvu, struct msg_req *req,
+ rvu_switch_update_rules(rvu, pcifunc, false);
+ rvu_cgx_tx_enable(rvu, pcifunc, true);
+
+- pf = rvu_get_pf(pcifunc);
++ pf = rvu_get_pf(rvu->pdev, pcifunc);
+ if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode)
+ rvu_rep_notify_pfvf_state(rvu, pcifunc, false);
+ return 0;
+@@ -5296,7 +5300,7 @@ void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int nixlf)
+ {
+ struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+ struct hwctx_disable_req ctx_req;
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ struct mac_ops *mac_ops;
+ u8 cgx_id, lmac_id;
+ u64 sa_base;
+@@ -5385,7 +5389,7 @@ static int rvu_nix_lf_ptp_tx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
+ int nixlf;
+ u64 cfg;
+
+- pf = rvu_get_pf(pcifunc);
++ pf = rvu_get_pf(rvu->pdev, pcifunc);
+ if (!is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_PTP))
+ return 0;
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+index da15bb4511788..c7c70429eb6c1 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+@@ -147,7 +147,9 @@ static int npc_get_ucast_mcam_index(struct npc_mcam *mcam, u16 pcifunc,
+ int npc_get_nixlf_mcam_index(struct npc_mcam *mcam,
+ u16 pcifunc, int nixlf, int type)
+ {
+- int pf = rvu_get_pf(pcifunc);
++ struct rvu_hwinfo *hw = container_of(mcam, struct rvu_hwinfo, mcam);
++ struct rvu *rvu = hw->rvu;
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ int index;
+
+ /* Check if this is for a PF */
+@@ -698,7 +700,7 @@ void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
+
+ /* RX_ACTION set to MCAST for CGX PF's */
+ if (hw->cap.nix_rx_multicast && pfvf->use_mce_list &&
+- is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc))) {
++ is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc))) {
+ *(u64 *)&action = 0;
+ action.op = NIX_RX_ACTIONOP_MCAST;
+ pfvf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
+@@ -3434,7 +3436,7 @@ int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
+ {
+ struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+ int blkaddr, nixlf, rc, intf_mode;
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ u64 rxpkind, txpkind;
+ u8 cgx_id, lmac_id;
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c
+index d2661e7fabdb4..999f6d93c7fe8 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c
+@@ -1465,7 +1465,7 @@ static int rvu_npc_exact_update_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_
+ int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc)
+ {
+ struct npc_exact_table *table;
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ u8 cgx_id, lmac_id;
+ u32 drop_mcam_idx;
+ bool *promisc;
+@@ -1512,7 +1512,7 @@ int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc)
+ int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc)
+ {
+ struct npc_exact_table *table;
+- int pf = rvu_get_pf(pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ u8 cgx_id, lmac_id;
+ u32 drop_mcam_idx;
+ bool *promisc;
+@@ -1560,7 +1560,7 @@ int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc)
+ int rvu_npc_exact_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req,
+ struct msg_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u32 seq_id = req->index;
+ struct rvu_pfvf *pfvf;
+ u8 cgx_id, lmac_id;
+@@ -1593,7 +1593,7 @@ int rvu_npc_exact_mac_addr_update(struct rvu *rvu,
+ struct cgx_mac_addr_update_req *req,
+ struct cgx_mac_addr_update_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ struct npc_exact_table_entry *entry;
+ struct npc_exact_table *table;
+ struct rvu_pfvf *pfvf;
+@@ -1675,7 +1675,7 @@ int rvu_npc_exact_mac_addr_add(struct rvu *rvu,
+ struct cgx_mac_addr_add_req *req,
+ struct cgx_mac_addr_add_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ struct rvu_pfvf *pfvf;
+ u8 cgx_id, lmac_id;
+ int rc = 0;
+@@ -1711,7 +1711,7 @@ int rvu_npc_exact_mac_addr_del(struct rvu *rvu,
+ struct cgx_mac_addr_del_req *req,
+ struct msg_rsp *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ int rc;
+
+ rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
+@@ -1736,7 +1736,7 @@ int rvu_npc_exact_mac_addr_del(struct rvu *rvu,
+ int rvu_npc_exact_mac_addr_set(struct rvu *rvu, struct cgx_mac_addr_set_or_get *req,
+ struct cgx_mac_addr_set_or_get *rsp)
+ {
+- int pf = rvu_get_pf(req->hdr.pcifunc);
++ int pf = rvu_get_pf(rvu->pdev, req->hdr.pcifunc);
+ u32 seq_id = req->index;
+ struct rvu_pfvf *pfvf;
+ u8 cgx_id, lmac_id;
+@@ -2001,7 +2001,7 @@ int rvu_npc_exact_init(struct rvu *rvu)
+ }
+
+ /* Filter rules are only for PF */
+- pcifunc = RVU_PFFUNC(i, 0);
++ pcifunc = RVU_PFFUNC(rvu->pdev, i, 0);
+
+ dev_dbg(rvu->dev,
+ "%s:Drop rule cgx=%d lmac=%d chan(val=0x%llx, mask=0x%llx\n",
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h
+index 57a09328d46b5..cb25cf478f1fd 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h
+@@ -139,9 +139,7 @@ static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = {
+ #define NPC_MCAM_DROP_RULE_MAX 30
+ #define NPC_MCAM_SDP_DROP_RULE_IDX 0
+
+-#define RVU_PFFUNC(pf, func) \
+- ((((pf) & RVU_PFVF_PF_MASK) << RVU_PFVF_PF_SHIFT) | \
+- (((func) & RVU_PFVF_FUNC_MASK) << RVU_PFVF_FUNC_SHIFT))
++#define RVU_PFFUNC(pdev, pf, func) rvu_make_pcifunc(pdev, pf, func)
+
+ enum npc_exact_opc_type {
+ NPC_EXACT_OPC_MEM,
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
+index 32953cca108c8..03099bc570bd5 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
+@@ -39,7 +39,7 @@ static int rvu_rep_up_notify(struct rvu *rvu, struct rep_event *event)
+ struct rep_event *msg;
+ int pf;
+
+- pf = rvu_get_pf(event->pcifunc);
++ pf = rvu_get_pf(rvu->pdev, event->pcifunc);
+
+ if (event->event & RVU_EVENT_MAC_ADDR_CHANGE)
+ ether_addr_copy(pfvf->mac_addr, event->evt_data.mac);
+@@ -114,10 +114,10 @@ int rvu_rep_notify_pfvf_state(struct rvu *rvu, u16 pcifunc, bool enable)
+ struct rep_event *req;
+ int pf;
+
+- if (!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
++ if (!is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc)))
+ return 0;
+
+- pf = rvu_get_pf(rvu->rep_pcifunc);
++ pf = rvu_get_pf(rvu->pdev, rvu->rep_pcifunc);
+
+ mutex_lock(&rvu->mbox_lock);
+ req = otx2_mbox_alloc_msg_rep_event_up_notify(rvu, pf);
+@@ -325,7 +325,7 @@ int rvu_rep_install_mcam_rules(struct rvu *rvu)
+ if (!is_pf_cgxmapped(rvu, pf))
+ continue;
+
+- pcifunc = pf << RVU_PFVF_PF_SHIFT;
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+ rvu_get_nix_blkaddr(rvu, pcifunc);
+ rep = true;
+ for (i = 0; i < 2; i++) {
+@@ -345,8 +345,7 @@ int rvu_rep_install_mcam_rules(struct rvu *rvu)
+
+ rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
+ for (vf = 0; vf < numvfs; vf++) {
+- pcifunc = pf << RVU_PFVF_PF_SHIFT |
+- ((vf + 1) & RVU_PFVF_FUNC_MASK);
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, vf + 1);
+ rvu_get_nix_blkaddr(rvu, pcifunc);
+
+ /* Skip installimg rules if nixlf is not attached */
+@@ -454,7 +453,7 @@ int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
+ for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
+ if (!is_pf_cgxmapped(rvu, pf))
+ continue;
+- pcifunc = pf << RVU_PFVF_PF_SHIFT;
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+ rvu->rep2pfvf_map[rep] = pcifunc;
+ rsp->rep_pf_map[rep] = pcifunc;
+ rep++;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+index 38cfe148f4b74..e4a5f9fa6fd46 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+@@ -17,9 +17,9 @@
+ /* SDP PF number */
+ static int sdp_pf_num[MAX_SDP] = {-1, -1};
+
+-bool is_sdp_pfvf(u16 pcifunc)
++bool is_sdp_pfvf(struct rvu *rvu, u16 pcifunc)
+ {
+- u16 pf = rvu_get_pf(pcifunc);
++ u16 pf = rvu_get_pf(rvu->pdev, pcifunc);
+ u32 found = 0, i = 0;
+
+ while (i < MAX_SDP) {
+@@ -34,9 +34,9 @@ bool is_sdp_pfvf(u16 pcifunc)
+ return true;
+ }
+
+-bool is_sdp_pf(u16 pcifunc)
++bool is_sdp_pf(struct rvu *rvu, u16 pcifunc)
+ {
+- return (is_sdp_pfvf(pcifunc) &&
++ return (is_sdp_pfvf(rvu, pcifunc) &&
+ !(pcifunc & RVU_PFVF_FUNC_MASK));
+ }
+
+@@ -46,7 +46,7 @@ bool is_sdp_vf(struct rvu *rvu, u16 pcifunc)
+ if (!(pcifunc & ~RVU_PFVF_FUNC_MASK))
+ return (rvu->vf_devid == RVU_SDP_VF_DEVID);
+
+- return (is_sdp_pfvf(pcifunc) &&
++ return (is_sdp_pfvf(rvu, pcifunc) &&
+ !!(pcifunc & RVU_PFVF_FUNC_MASK));
+ }
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
+index 268efb7c1c15d..49ce38685a7e6 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
+@@ -93,7 +93,7 @@ static int rvu_switch_install_rules(struct rvu *rvu)
+ if (!is_pf_cgxmapped(rvu, pf))
+ continue;
+
+- pcifunc = pf << 10;
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+ /* rvu_get_nix_blkaddr sets up the corresponding NIX block
+ * address and NIX RX and TX interfaces for a pcifunc.
+ * Generally it is called during attach call of a pcifunc but it
+@@ -126,7 +126,7 @@ static int rvu_switch_install_rules(struct rvu *rvu)
+
+ rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
+ for (vf = 0; vf < numvfs; vf++) {
+- pcifunc = pf << 10 | ((vf + 1) & 0x3FF);
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, (vf + 1));
+ rvu_get_nix_blkaddr(rvu, pcifunc);
+
+ err = rvu_switch_install_rx_rule(rvu, pcifunc, 0x0);
+@@ -236,7 +236,7 @@ void rvu_switch_disable(struct rvu *rvu)
+ if (!is_pf_cgxmapped(rvu, pf))
+ continue;
+
+- pcifunc = pf << 10;
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+ err = rvu_switch_install_rx_rule(rvu, pcifunc, 0xFFF);
+ if (err)
+ dev_err(rvu->dev,
+@@ -248,7 +248,7 @@ void rvu_switch_disable(struct rvu *rvu)
+
+ rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
+ for (vf = 0; vf < numvfs; vf++) {
+- pcifunc = pf << 10 | ((vf + 1) & 0x3FF);
++ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, (vf + 1));
+ err = rvu_switch_install_rx_rule(rvu, pcifunc, 0xFFF);
+ if (err)
+ dev_err(rvu->dev,
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
+index a6500e3673f24..c691f07221540 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.c
+@@ -481,7 +481,7 @@ static int cn10k_outb_write_sa(struct otx2_nic *pf, struct qmem *sa_info)
+ goto set_available;
+
+ /* Trigger CTX flush to write dirty data back to DRAM */
+- reg_val = FIELD_PREP(CPT_LF_CTX_FLUSH, sa_iova >> 7);
++ reg_val = FIELD_PREP(CPT_LF_CTX_FLUSH_CPTR, sa_iova >> 7);
+ otx2_write64(pf, CN10K_CPT_LF_CTX_FLUSH, reg_val);
+
+ set_available:
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h
+index 9965df0faa3e7..43fbce0d60390 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h
+@@ -220,7 +220,7 @@ struct cpt_sg_s {
+ #define CPT_LF_Q_SIZE_DIV40 GENMASK_ULL(14, 0)
+
+ /* CPT LF CTX Flush Register */
+-#define CPT_LF_CTX_FLUSH GENMASK_ULL(45, 0)
++#define CPT_LF_CTX_FLUSH_CPTR GENMASK_ULL(45, 0)
+
+ #ifdef CONFIG_XFRM_OFFLOAD
+ int cn10k_ipsec_init(struct net_device *netdev);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+index 5a6739d3a0688..f4fc915a0b5f1 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+@@ -28,6 +28,7 @@
+ #include "otx2_reg.h"
+ #include "otx2_txrx.h"
+ #include "otx2_devlink.h"
++#include <rvu.h>
+ #include <rvu_trace.h>
+ #include "qos.h"
+ #include "rep.h"
+@@ -900,21 +901,11 @@ MBOX_UP_MCS_MESSAGES
+ /* Time to wait before watchdog kicks off */
+ #define OTX2_TX_TIMEOUT (100 * HZ)
+
+-#define RVU_PFVF_PF_SHIFT 10
+-#define RVU_PFVF_PF_MASK 0x3F
+-#define RVU_PFVF_FUNC_SHIFT 0
+-#define RVU_PFVF_FUNC_MASK 0x3FF
+-
+ static inline bool is_otx2_vf(u16 pcifunc)
+ {
+ return !!(pcifunc & RVU_PFVF_FUNC_MASK);
+ }
+
+-static inline int rvu_get_pf(u16 pcifunc)
+-{
+- return (pcifunc >> RVU_PFVF_PF_SHIFT) & RVU_PFVF_PF_MASK;
+-}
+-
+ static inline dma_addr_t otx2_dma_map_page(struct otx2_nic *pfvf,
+ struct page *page,
+ size_t offset, size_t size,
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index 74d0b6bac600a..c6d2f2249cc35 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -206,7 +206,8 @@ static int otx2_register_flr_me_intr(struct otx2_nic *pf, int numvfs)
+
+ /* Register ME interrupt handler*/
+ irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFME0 * NAME_SIZE];
+- snprintf(irq_name, NAME_SIZE, "RVUPF%d_ME0", rvu_get_pf(pf->pcifunc));
++ snprintf(irq_name, NAME_SIZE, "RVUPF%d_ME0",
++ rvu_get_pf(pf->pdev, pf->pcifunc));
+ ret = request_irq(pci_irq_vector(pf->pdev, RVU_PF_INT_VEC_VFME0),
+ otx2_pf_me_intr_handler, 0, irq_name, pf);
+ if (ret) {
+@@ -216,7 +217,8 @@ static int otx2_register_flr_me_intr(struct otx2_nic *pf, int numvfs)
+
+ /* Register FLR interrupt handler */
+ irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFFLR0 * NAME_SIZE];
+- snprintf(irq_name, NAME_SIZE, "RVUPF%d_FLR0", rvu_get_pf(pf->pcifunc));
++ snprintf(irq_name, NAME_SIZE, "RVUPF%d_FLR0",
++ rvu_get_pf(pf->pdev, pf->pcifunc));
+ ret = request_irq(pci_irq_vector(pf->pdev, RVU_PF_INT_VEC_VFFLR0),
+ otx2_pf_flr_intr_handler, 0, irq_name, pf);
+ if (ret) {
+@@ -228,7 +230,7 @@ static int otx2_register_flr_me_intr(struct otx2_nic *pf, int numvfs)
+ if (numvfs > 64) {
+ irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFME1 * NAME_SIZE];
+ snprintf(irq_name, NAME_SIZE, "RVUPF%d_ME1",
+- rvu_get_pf(pf->pcifunc));
++ rvu_get_pf(pf->pdev, pf->pcifunc));
+ ret = request_irq(pci_irq_vector
+ (pf->pdev, RVU_PF_INT_VEC_VFME1),
+ otx2_pf_me_intr_handler, 0, irq_name, pf);
+@@ -238,7 +240,7 @@ static int otx2_register_flr_me_intr(struct otx2_nic *pf, int numvfs)
+ }
+ irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFFLR1 * NAME_SIZE];
+ snprintf(irq_name, NAME_SIZE, "RVUPF%d_FLR1",
+- rvu_get_pf(pf->pcifunc));
++ rvu_get_pf(pf->pdev, pf->pcifunc));
+ ret = request_irq(pci_irq_vector
+ (pf->pdev, RVU_PF_INT_VEC_VFFLR1),
+ otx2_pf_flr_intr_handler, 0, irq_name, pf);
+@@ -701,7 +703,7 @@ static int otx2_register_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
+ irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFPF_MBOX0 * NAME_SIZE];
+ if (pf->pcifunc)
+ snprintf(irq_name, NAME_SIZE,
+- "RVUPF%d_VF Mbox0", rvu_get_pf(pf->pcifunc));
++ "RVUPF%d_VF Mbox0", rvu_get_pf(pf->pdev, pf->pcifunc));
+ else
+ snprintf(irq_name, NAME_SIZE, "RVUPF_VF Mbox0");
+ err = request_irq(pci_irq_vector(pf->pdev, RVU_PF_INT_VEC_VFPF_MBOX0),
+@@ -717,7 +719,8 @@ static int otx2_register_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
+ irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFPF_MBOX1 * NAME_SIZE];
+ if (pf->pcifunc)
+ snprintf(irq_name, NAME_SIZE,
+- "RVUPF%d_VF Mbox1", rvu_get_pf(pf->pcifunc));
++ "RVUPF%d_VF Mbox1",
++ rvu_get_pf(pf->pdev, pf->pcifunc));
+ else
+ snprintf(irq_name, NAME_SIZE, "RVUPF_VF Mbox1");
+ err = request_irq(pci_irq_vector(pf->pdev,
+@@ -1972,7 +1975,7 @@ int otx2_open(struct net_device *netdev)
+ if (err) {
+ dev_err(pf->dev,
+ "RVUPF%d: IRQ registration failed for QERR\n",
+- rvu_get_pf(pf->pcifunc));
++ rvu_get_pf(pf->pdev, pf->pcifunc));
+ goto err_disable_napi;
+ }
+
+@@ -1990,7 +1993,7 @@ int otx2_open(struct net_device *netdev)
+ if (name_len >= NAME_SIZE) {
+ dev_err(pf->dev,
+ "RVUPF%d: IRQ registration failed for CQ%d, irq name is too long\n",
+- rvu_get_pf(pf->pcifunc), qidx);
++ rvu_get_pf(pf->pdev, pf->pcifunc), qidx);
+ err = -EINVAL;
+ goto err_free_cints;
+ }
+@@ -2001,7 +2004,7 @@ int otx2_open(struct net_device *netdev)
+ if (err) {
+ dev_err(pf->dev,
+ "RVUPF%d: IRQ registration failed for CQ%d\n",
+- rvu_get_pf(pf->pcifunc), qidx);
++ rvu_get_pf(pf->pdev, pf->pcifunc), qidx);
+ goto err_free_cints;
+ }
+ vec++;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h
+index e3aee6e362151..858f084b9d474 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h
+@@ -138,36 +138,6 @@
+ #define NIX_LF_CINTX_ENA_W1S(a) (NIX_LFBASE | 0xD40 | (a) << 12)
+ #define NIX_LF_CINTX_ENA_W1C(a) (NIX_LFBASE | 0xD50 | (a) << 12)
+
+-/* NIX AF transmit scheduler registers */
+-#define NIX_AF_SMQX_CFG(a) (0x700 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_SDP_LINK_CFG(a) (0xB10 | (u64)(a) << 16)
+-#define NIX_AF_TL1X_SCHEDULE(a) (0xC00 | (u64)(a) << 16)
+-#define NIX_AF_TL1X_CIR(a) (0xC20 | (u64)(a) << 16)
+-#define NIX_AF_TL1X_TOPOLOGY(a) (0xC80 | (u64)(a) << 16)
+-#define NIX_AF_TL2X_PARENT(a) (0xE88 | (u64)(a) << 16)
+-#define NIX_AF_TL2X_SCHEDULE(a) (0xE00 | (u64)(a) << 16)
+-#define NIX_AF_TL2X_TOPOLOGY(a) (0xE80 | (u64)(a) << 16)
+-#define NIX_AF_TL2X_CIR(a) (0xE20 | (u64)(a) << 16)
+-#define NIX_AF_TL2X_PIR(a) (0xE30 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_PARENT(a) (0x1088 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_SCHEDULE(a) (0x1000 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_SHAPE(a) (0x1010 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_CIR(a) (0x1020 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_PIR(a) (0x1030 | (u64)(a) << 16)
+-#define NIX_AF_TL3X_TOPOLOGY(a) (0x1080 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_PARENT(a) (0x1288 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_SCHEDULE(a) (0x1200 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_SHAPE(a) (0x1210 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_CIR(a) (0x1220 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_PIR(a) (0x1230 | (u64)(a) << 16)
+-#define NIX_AF_TL4X_TOPOLOGY(a) (0x1280 | (u64)(a) << 16)
+-#define NIX_AF_MDQX_SCHEDULE(a) (0x1400 | (u64)(a) << 16)
+-#define NIX_AF_MDQX_SHAPE(a) (0x1410 | (u64)(a) << 16)
+-#define NIX_AF_MDQX_CIR(a) (0x1420 | (u64)(a) << 16)
+-#define NIX_AF_MDQX_PIR(a) (0x1430 | (u64)(a) << 16)
+-#define NIX_AF_MDQX_PARENT(a) (0x1480 | (u64)(a) << 16)
+-#define NIX_AF_TL3_TL2X_LINKX_CFG(a, b) (0x1700 | (u64)(a) << 16 | (b) << 3)
+-
+ /* LMT LF registers */
+ #define LMT_LFBASE BIT_ULL(RVU_FUNC_BLKADDR_SHIFT)
+ #define LMT_LF_LMTLINEX(a) (LMT_LFBASE | 0x000 | (a) << 12)
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
+index 9a226ca744254..5f80b23c5335c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
+@@ -467,7 +467,8 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic,
+ target = act->dev;
+ if (target->dev.parent) {
+ priv = netdev_priv(target);
+- if (rvu_get_pf(nic->pcifunc) != rvu_get_pf(priv->pcifunc)) {
++ if (rvu_get_pf(nic->pdev, nic->pcifunc) !=
++ rvu_get_pf(nic->pdev, priv->pcifunc)) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "can't redirect to other pf/vf");
+ return -EOPNOTSUPP;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+index d97be15d80561..b476733a02345 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+@@ -244,10 +244,10 @@ static int rvu_rep_devlink_port_register(struct rep_dev *rep)
+
+ if (!(rep->pcifunc & RVU_PFVF_FUNC_MASK)) {
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+- attrs.phys.port_number = rvu_get_pf(rep->pcifunc);
++ attrs.phys.port_number = rvu_get_pf(priv->pdev, rep->pcifunc);
+ } else {
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF;
+- attrs.pci_vf.pf = rvu_get_pf(rep->pcifunc);
++ attrs.pci_vf.pf = rvu_get_pf(priv->pdev, rep->pcifunc);
+ attrs.pci_vf.vf = rep->pcifunc & RVU_PFVF_FUNC_MASK;
+ }
+
+@@ -683,7 +683,8 @@ int rvu_rep_create(struct otx2_nic *priv, struct netlink_ext_ack *extack)
+ rep->pcifunc = pcifunc;
+
+ snprintf(ndev->name, sizeof(ndev->name), "Rpf%dvf%d",
+- rvu_get_pf(pcifunc), (pcifunc & RVU_PFVF_FUNC_MASK));
++ rvu_get_pf(priv->pdev, pcifunc),
++ (pcifunc & RVU_PFVF_FUNC_MASK));
+
+ ndev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM | NETIF_F_RXHASH |
+diff --git a/include/linux/soc/marvell/silicons.h b/include/linux/soc/marvell/silicons.h
+new file mode 100644
+index 0000000000000..66bb9bfaf17d5
+--- /dev/null
++++ b/include/linux/soc/marvell/silicons.h
+@@ -0,0 +1,25 @@
++/* SPDX-License-Identifier: GPL-2.0-only
++ * Copyright (C) 2024 Marvell.
++ */
++
++#ifndef __SOC_SILICON_H
++#define __SOC_SILICON_H
++
++#include <linux/types.h>
++#include <linux/pci.h>
++
++#if defined(CONFIG_ARM64)
++
++#define CN20K_CHIPID 0x20
++/*
++ * Silicon check for CN20K family
++ */
++static inline bool is_cn20k(struct pci_dev *pdev)
++{
++ return (pdev->subsystem_device & 0xFF) == CN20K_CHIPID;
++}
++#else
++#define is_cn20k(pdev) ((void)(pdev), 0)
++#endif
++
++#endif /* __SOC_SILICON_H */
+--
+2.50.1
+
--- /dev/null
+From 650741f3c3c07fe4b4ca8278ea3f501591d98e1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 11:55:28 +0530
+Subject: Octeontx2-vf: Fix max packet length errors
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit a64494aafc56939564e3e9e57f99df5c27204e04 ]
+
+Once driver submits the packets to the hardware, each packet
+traverse through multiple transmit levels in the following
+order:
+ SMQ -> TL4 -> TL3 -> TL2 -> TL1
+
+The SMQ supports configurable minimum and maximum packet sizes.
+It enters to a hang state, if driver submits packets with
+out of bound lengths.
+
+To avoid the same, implement packet length validation before
+submitting packets to the hardware. Increment tx_dropped counter
+on failure.
+
+Fixes: 3184fb5ba96e ("octeontx2-vf: Virtual function driver support")
+Fixes: 22f858796758 ("octeontx2-pf: Add basic net_device_ops")
+Fixes: 3ca6c4c882a7 ("octeontx2-pf: Add packet transmission support")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Link: https://patch.msgid.link/20250821062528.1697992-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/nic/otx2_common.c | 4 +++-
+ .../ethernet/marvell/octeontx2/nic/otx2_common.h | 1 +
+ .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 3 +++
+ .../net/ethernet/marvell/octeontx2/nic/otx2_vf.c | 10 ++++++++++
+ drivers/net/ethernet/marvell/octeontx2/nic/rep.c | 13 ++++++++++++-
+ drivers/net/ethernet/marvell/octeontx2/nic/rep.h | 1 +
+ 6 files changed, 30 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index 6b5c9536d26d3..6f7b608261d9c 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -124,7 +124,9 @@ void otx2_get_dev_stats(struct otx2_nic *pfvf)
+ dev_stats->rx_ucast_frames;
+
+ dev_stats->tx_bytes = OTX2_GET_TX_STATS(TX_OCTS);
+- dev_stats->tx_drops = OTX2_GET_TX_STATS(TX_DROP);
++ dev_stats->tx_drops = OTX2_GET_TX_STATS(TX_DROP) +
++ (unsigned long)atomic_long_read(&dev_stats->tx_discards);
++
+ dev_stats->tx_bcast_frames = OTX2_GET_TX_STATS(TX_BCAST);
+ dev_stats->tx_mcast_frames = OTX2_GET_TX_STATS(TX_MCAST);
+ dev_stats->tx_ucast_frames = OTX2_GET_TX_STATS(TX_UCAST);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+index ca0e6ab12cebe..5a6739d3a0688 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+@@ -149,6 +149,7 @@ struct otx2_dev_stats {
+ u64 tx_bcast_frames;
+ u64 tx_mcast_frames;
+ u64 tx_drops;
++ atomic_long_t tx_discards;
+ };
+
+ /* Driver counted stats */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index db7c466fdc39e..74d0b6bac600a 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -2153,6 +2153,7 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
+ {
+ struct otx2_nic *pf = netdev_priv(netdev);
+ int qidx = skb_get_queue_mapping(skb);
++ struct otx2_dev_stats *dev_stats;
+ struct otx2_snd_queue *sq;
+ struct netdev_queue *txq;
+ int sq_idx;
+@@ -2165,6 +2166,8 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
+ /* Check for minimum and maximum packet length */
+ if (skb->len <= ETH_HLEN ||
+ (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) {
++ dev_stats = &pf->hw.dev_stats;
++ atomic_long_inc(&dev_stats->tx_discards);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+index 8a8b598bd389b..76dd2e965cf03 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+@@ -391,9 +391,19 @@ static netdev_tx_t otx2vf_xmit(struct sk_buff *skb, struct net_device *netdev)
+ {
+ struct otx2_nic *vf = netdev_priv(netdev);
+ int qidx = skb_get_queue_mapping(skb);
++ struct otx2_dev_stats *dev_stats;
+ struct otx2_snd_queue *sq;
+ struct netdev_queue *txq;
+
++ /* Check for minimum and maximum packet length */
++ if (skb->len <= ETH_HLEN ||
++ (!skb_shinfo(skb)->gso_size && skb->len > vf->tx_max_pktlen)) {
++ dev_stats = &vf->hw.dev_stats;
++ atomic_long_inc(&dev_stats->tx_discards);
++ dev_kfree_skb(skb);
++ return NETDEV_TX_OK;
++ }
++
+ sq = &vf->qset.sq[qidx];
+ txq = netdev_get_tx_queue(netdev, qidx);
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+index 2cd3da3b68432..d97be15d80561 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+@@ -371,7 +371,8 @@ static void rvu_rep_get_stats(struct work_struct *work)
+ stats->rx_mcast_frames = rsp->rx.mcast;
+ stats->tx_bytes = rsp->tx.octs;
+ stats->tx_frames = rsp->tx.ucast + rsp->tx.bcast + rsp->tx.mcast;
+- stats->tx_drops = rsp->tx.drop;
++ stats->tx_drops = rsp->tx.drop +
++ (unsigned long)atomic_long_read(&stats->tx_discards);
+ exit:
+ mutex_unlock(&priv->mbox.lock);
+ }
+@@ -418,6 +419,16 @@ static netdev_tx_t rvu_rep_xmit(struct sk_buff *skb, struct net_device *dev)
+ struct otx2_nic *pf = rep->mdev;
+ struct otx2_snd_queue *sq;
+ struct netdev_queue *txq;
++ struct rep_stats *stats;
++
++ /* Check for minimum and maximum packet length */
++ if (skb->len <= ETH_HLEN ||
++ (!skb_shinfo(skb)->gso_size && skb->len > pf->tx_max_pktlen)) {
++ stats = &rep->stats;
++ atomic_long_inc(&stats->tx_discards);
++ dev_kfree_skb(skb);
++ return NETDEV_TX_OK;
++ }
+
+ sq = &pf->qset.sq[rep->rep_id];
+ txq = netdev_get_tx_queue(dev, 0);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.h b/drivers/net/ethernet/marvell/octeontx2/nic/rep.h
+index 38446b3e4f13c..5bc9e2c7d800b 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.h
+@@ -27,6 +27,7 @@ struct rep_stats {
+ u64 tx_bytes;
+ u64 tx_frames;
+ u64 tx_drops;
++ atomic_long_t tx_discards;
+ };
+
+ struct rep_dev {
+--
+2.50.1
+
--- /dev/null
+From 011cc4693733b49f9ce512a632963bc49f95b7ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Aug 2025 10:24:21 -0700
+Subject: of: reserved_mem: Restructure call site for
+ dma_contiguous_early_fixup()
+
+From: Oreoluwa Babatunde <oreoluwa.babatunde@oss.qualcomm.com>
+
+[ Upstream commit 2c223f7239f376a90d71903ec474ba887cf21d94 ]
+
+Restructure the call site for dma_contiguous_early_fixup() to
+where the reserved_mem nodes are being parsed from the DT so that
+dma_mmu_remap[] is populated before dma_contiguous_remap() is called.
+
+Fixes: 8a6e02d0c00e ("of: reserved_mem: Restructure how the reserved memory regions are processed")
+Signed-off-by: Oreoluwa Babatunde <oreoluwa.babatunde@oss.qualcomm.com>
+Tested-by: William Zhang <william.zhang@broadcom.com>
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20250806172421.2748302-1-oreoluwa.babatunde@oss.qualcomm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/of/of_reserved_mem.c | 16 ++++++++++++----
+ include/linux/dma-map-ops.h | 3 +++
+ kernel/dma/contiguous.c | 2 --
+ 3 files changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
+index d3b7c4ae429c7..2e9ea751ed2df 100644
+--- a/drivers/of/of_reserved_mem.c
++++ b/drivers/of/of_reserved_mem.c
+@@ -25,6 +25,7 @@
+ #include <linux/memblock.h>
+ #include <linux/kmemleak.h>
+ #include <linux/cma.h>
++#include <linux/dma-map-ops.h>
+
+ #include "of_private.h"
+
+@@ -175,13 +176,17 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
+ base = dt_mem_next_cell(dt_root_addr_cells, &prop);
+ size = dt_mem_next_cell(dt_root_size_cells, &prop);
+
+- if (size &&
+- early_init_dt_reserve_memory(base, size, nomap) == 0)
++ if (size && early_init_dt_reserve_memory(base, size, nomap) == 0) {
++ /* Architecture specific contiguous memory fixup. */
++ if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
++ of_get_flat_dt_prop(node, "reusable", NULL))
++ dma_contiguous_early_fixup(base, size);
+ pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
+ uname, &base, (unsigned long)(size / SZ_1M));
+- else
++ } else {
+ pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
+ uname, &base, (unsigned long)(size / SZ_1M));
++ }
+
+ len -= t_len;
+ }
+@@ -472,7 +477,10 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
+ uname, (unsigned long)(size / SZ_1M));
+ return -ENOMEM;
+ }
+-
++ /* Architecture specific contiguous memory fixup. */
++ if (of_flat_dt_is_compatible(node, "shared-dma-pool") &&
++ of_get_flat_dt_prop(node, "reusable", NULL))
++ dma_contiguous_early_fixup(base, size);
+ /* Save region in the reserved_mem array */
+ fdt_reserved_mem_save_node(node, uname, base, size);
+ return 0;
+diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
+index f48e5fb88bd5d..332b80c42b6f3 100644
+--- a/include/linux/dma-map-ops.h
++++ b/include/linux/dma-map-ops.h
+@@ -153,6 +153,9 @@ static inline void dma_free_contiguous(struct device *dev, struct page *page,
+ {
+ __free_pages(page, get_order(size));
+ }
++static inline void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
++{
++}
+ #endif /* CONFIG_DMA_CMA*/
+
+ #ifdef CONFIG_DMA_DECLARE_COHERENT
+diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
+index 67af8a55185d9..d9b9dcba6ff7c 100644
+--- a/kernel/dma/contiguous.c
++++ b/kernel/dma/contiguous.c
+@@ -483,8 +483,6 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
+ pr_err("Reserved memory: unable to setup CMA region\n");
+ return err;
+ }
+- /* Architecture specific contiguous memory fixup. */
+- dma_contiguous_early_fixup(rmem->base, rmem->size);
+
+ if (default_cma)
+ dma_contiguous_default_area = cma;
+--
+2.50.1
+
--- /dev/null
+From c53ae8ac389477d45e1cc59d48be124c3c8e7ff8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 03:03:46 +0000
+Subject: page_pool: fix incorrect mp_ops error handling
+
+From: Mina Almasry <almasrymina@google.com>
+
+[ Upstream commit abadf0ff63be488dc502ecfc9f622929a21b7117 ]
+
+Minor fix to the memory provider error handling, we should be jumping to
+free_ptr_ring in this error case rather than returning directly.
+
+Found by code-inspection.
+
+Cc: skhawaja@google.com
+
+Fixes: b400f4b87430 ("page_pool: Set `dma_sync` to false for devmem memory provider")
+Signed-off-by: Mina Almasry <almasrymina@google.com>
+Reviewed-by: Samiullah Khawaja <skhawaja@google.com>
+Link: https://patch.msgid.link/20250821030349.705244-1-almasrymina@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/page_pool.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/page_pool.c b/net/core/page_pool.c
+index 368412baad264..e14d743554ec1 100644
+--- a/net/core/page_pool.c
++++ b/net/core/page_pool.c
+@@ -287,8 +287,10 @@ static int page_pool_init(struct page_pool *pool,
+ }
+
+ if (pool->mp_ops) {
+- if (!pool->dma_map || !pool->dma_sync)
+- return -EOPNOTSUPP;
++ if (!pool->dma_map || !pool->dma_sync) {
++ err = -EOPNOTSUPP;
++ goto free_ptr_ring;
++ }
+
+ if (WARN_ON(!is_kernel_rodata((unsigned long)pool->mp_ops))) {
+ err = -EFAULT;
+--
+2.50.1
+
--- /dev/null
+From 203965066ac6acb399e44104df66d14c343cebad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:55:43 +0200
+Subject: phy: mscc: Fix when PTP clock is register and unregister
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]
+
+It looks like that every time when the interface was set down and up the
+driver was creating a new ptp clock. On top of this the function
+ptp_clock_unregister was never called.
+Therefore fix this by calling ptp_clock_register and initialize the
+mii_ts struct inside the probe function and call ptp_clock_unregister when
+driver is removed.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h | 4 ++++
+ drivers/net/phy/mscc/mscc_main.c | 4 +---
+ drivers/net/phy/mscc/mscc_ptp.c | 34 ++++++++++++++++++++------------
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index 58c6d47fbe046..2bfe314ef881c 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -481,6 +481,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -495,6 +496,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
+ {
+ return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+ return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index c3209cf00e960..ac9b6130ef502 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2338,9 +2338,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+- struct vsc8531_private *priv = phydev->priv;
+-
+- skb_queue_purge(&priv->rx_skbs_list);
++ vsc8584_ptp_deinit(phydev);
+ }
+
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index de6c7312e8f29..72847320cb652 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1298,7 +1298,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+- struct vsc8531_private *vsc8531 = phydev->priv;
+ static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+ static const u8 ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+ u32 val;
+@@ -1515,17 +1514,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+
+ vsc85xx_ts_eth_cmp1_sig(phydev);
+
+- vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+- vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+- vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+- vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
+- phydev->mii_ts = &vsc8531->mii_ts;
+-
+- memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+-
+- vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+- &phydev->mdio.dev);
+- return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++ return 0;
+ }
+
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1552,6 +1541,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+ return 0;
+ }
+
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++ struct vsc8531_private *vsc8531 = phydev->priv;
++
++ if (vsc8531->ptp->ptp_clock) {
++ ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++ skb_queue_purge(&vsc8531->rx_skbs_list);
++ }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+ struct vsc8531_private *priv = phydev->priv;
+@@ -1612,7 +1611,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+
+ vsc8531->ptp->phydev = phydev;
+
+- return 0;
++ vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++ vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++ vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++ vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
++ phydev->mii_ts = &vsc8531->mii_ts;
++
++ memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
++ vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++ &phydev->mdio.dev);
++ return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+--
+2.50.1
+
--- /dev/null
+From c95e064ba88c7e1c685a340d958000e362bea7a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 5b3c093611baf..7209d00a9c257 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+ }
+
+- switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++ switch (inst_no_rt & ~KVM_MASK_RB) {
+ case KVM_INST_MTSRIN:
+ if (features & KVM_MAGIC_FEAT_SR) {
+ u32 inst_rb = _inst & KVM_MASK_RB;
+ kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+ }
+ break;
+-#endif
+ }
++#endif
+
+- switch (_inst) {
+ #ifdef CONFIG_BOOKE
++ switch (_inst) {
+ case KVM_INST_WRTEEI_0:
+ kvm_patch_ins_wrteei_0(inst);
+ break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ case KVM_INST_WRTEEI_1:
+ kvm_patch_ins_wrtee(inst, 0, 1);
+ break;
+-#endif
+ }
++#endif
+ }
+
+ extern u32 kvm_template_start[];
+--
+2.50.1
+
--- /dev/null
+From fa513dc18c41cbc491a7e1c04372864eab73042d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+ sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+ sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+ sctp_get_port net/sctp/socket.c:8523 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+ x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+ sctp_get_port net/sctp/socket.c:8515 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index a9ed2ccab1bdb..2bb5e19e10caa 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -546,7 +546,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+ addr->v6.sin6_family = AF_INET6;
+ addr->v6.sin6_port = 0;
++ addr->v6.sin6_flowinfo = 0;
+ addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++ addr->v6.sin6_scope_id = 0;
+ }
+
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+--
+2.50.1
+
io_uring-io-wq-add-check-free-worker-before-create-n.patch
platform-x86-int3472-add-hpd-pin-support.patch
vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+drm-msm-defer-fd_install-in-submit-ioctl.patch
+of-reserved_mem-restructure-call-site-for-dma_contig.patch
+hid-intel-thc-hid-intel-quicki2c-fix-acpi-dsd-icrs-i.patch
+hid-intel-thc-hid-intel-thc-fix-incorrect-pointer-ar.patch
+hid-intel-thc-hid-intel-quicki2c-enhance-driver-re-i.patch
+drm-msm-kms-move-snapshot-init-earlier-in-kms-init.patch
+drm-msm-dpu-correct-dpu_plane_virtual_atomic_check.patch
+drm-msm-update-the-high-bitfield-of-certain-dsi-regi.patch
+drm-mediatek-add-error-handling-for-old-state-crtc-i.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+hid-input-rename-hidinput_set_battery_charge_status.patch
+hid-input-report-battery-status-changes-immediately.patch
+idpf-add-support-for-tx-refillqs-in-flow-scheduling-.patch
+idpf-simplify-and-fix-splitq-tx-packet-rollback-erro.patch
+idpf-replace-flow-scheduling-buffer-ring-with-buffer.patch
+idpf-stop-tx-if-there-are-insufficient-buffer-resour.patch
+net-macb-fix-unregister_netdev-call-order-in-macb_re.patch
+bluetooth-hci_conn-make-unacked-packet-handling-more.patch
+bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
+bluetooth-hci_event-mark-connection-as-closed-during.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+bluetooth-hci_event-disconnect-device-when-big-sync-.patch
+bluetooth-hci_sync-fix-set_local_name-race-condition.patch
+page_pool-fix-incorrect-mp_ops-error-handling.patch
+octeontx2-vf-fix-max-packet-length-errors.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch
+drm-nouveau-remove-unused-memory-target-test.patch
+ice-fix-null-pointer-dereference-in-ice_unplug_aux_d.patch
+ice-don-t-leave-device-non-functional-if-tx-schedule.patch
+ice-use-fixed-adapter-index-for-e825c-embedded-devic.patch
+ice-fix-incorrect-counter-for-buffer-allocation-fail.patch
+ixgbe-fix-ixgbe_orom_civd_info-struct-layout.patch
+dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch
+drm-msm-dpu-add-a-null-ptr-check-for-dpu_encoder_nee.patch
+octeontx2-set-appropriate-pf-vf-masks-and-shifts-bas.patch
+octeontx2-af-fix-nix-x2p-calibration-failures.patch
+misdn-hfcpci-fix-warning-when-deleting-uninitialized.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+efi-stmm-fix-incorrect-buffer-allocation-method.patch
+drm-xe-xe_sync-avoid-race-during-ufence-signaling.patch
+drm-xe-vm-don-t-pin-the-vm_resv-during-validation.patch
+drm-xe-don-t-trigger-rebind-on-initial-dma-buf-valid.patch
+block-validate-qos-before-calling-__rq_qos_done_bio.patch
+phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
+net-macb-fix-offset-error-in-gem_update_stats.patch
+bnxt_en-fix-memory-corruption-when-fw-resources-chan.patch
+bnxt_en-adjust-tx-rings-if-reservation-is-less-than-.patch
+bnxt_en-fix-stats-context-reservation-logic.patch
+net-mlx5-hws-fix-memory-leak-in-hws_pool_buddy_init-.patch
+net-mlx5-hws-fix-memory-leak-in-hws_action_get_share.patch
+net-mlx5-hws-fix-uninitialized-variables-in-mlx5hws_.patch
+net-mlx5-hws-fix-pattern-destruction-in-mlx5hws_pat_.patch
+net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
+net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch
+net-mlx5-nack-sync-reset-when-sfs-are-present.patch
+net-mlx5-prevent-flow-steering-mode-changes-in-switc.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+net-stmmac-xgmac-correct-supported-speed-modes.patch
+net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch
+net-hv_netvsc-fix-loss-of-early-receive-events-from-.patch
+io_uring-kbuf-fix-signedness-in-this_len-calculation.patch
+net-rose-split-remove-and-free-operations-in-rose_re.patch
+net-rose-convert-use-field-to-refcount_t.patch
+net-rose-include-node-references-in-rose_neigh-refco.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+l2tp-do-not-use-sock_hold-in-pppol2tp_session_get_so.patch
+fbnic-move-phylink-resume-out-of-service_task-and-in.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch
+net-macb-disable-clocks-once.patch
+io_uring-kbuf-always-use-read_once-to-read-ring-prov.patch
+drm-mediatek-mtk_hdmi-fix-inverted-parameters-in-som.patch
--- /dev/null
+From b5f82bcf10808933c86a10e78ef2e0f3efb0e4ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Aug 2025 02:18:24 +0000
+Subject: atm: atmtcp: Prevent arbitrary write in atmtcp_recv_control().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit ec79003c5f9d2c7f9576fc69b8dbda80305cbe3a ]
+
+syzbot reported the splat below. [0]
+
+When atmtcp_v_open() or atmtcp_v_close() is called via connect()
+or close(), atmtcp_send_control() is called to send an in-kernel
+special message.
+
+The message has ATMTCP_HDR_MAGIC in atmtcp_control.hdr.length.
+Also, a pointer of struct atm_vcc is set to atmtcp_control.vcc.
+
+The notable thing is struct atmtcp_control is uAPI but has a
+space for an in-kernel pointer.
+
+ struct atmtcp_control {
+ struct atmtcp_hdr hdr; /* must be first */
+ ...
+ atm_kptr_t vcc; /* both directions */
+ ...
+ } __ATM_API_ALIGN;
+
+ typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+The special message is processed in atmtcp_recv_control() called
+from atmtcp_c_send().
+
+atmtcp_c_send() is vcc->dev->ops->send() and called from 2 paths:
+
+ 1. .ndo_start_xmit() (vcc->send() == atm_send_aal0())
+ 2. vcc_sendmsg()
+
+The problem is sendmsg() does not validate the message length and
+userspace can abuse atmtcp_recv_control() to overwrite any kptr
+by atmtcp_control.
+
+Let's add a new ->pre_send() hook to validate messages from sendmsg().
+
+[0]:
+Oops: general protection fault, probably for non-canonical address 0xdffffc00200000ab: 0000 [#1] SMP KASAN PTI
+KASAN: probably user-memory-access in range [0x0000000100000558-0x000000010000055f]
+CPU: 0 UID: 0 PID: 5865 Comm: syz-executor331 Not tainted 6.17.0-rc1-syzkaller-00215-gbab3ce404553 #0 PREEMPT(full)
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/12/2025
+RIP: 0010:atmtcp_recv_control drivers/atm/atmtcp.c:93 [inline]
+RIP: 0010:atmtcp_c_send+0x1da/0x950 drivers/atm/atmtcp.c:297
+Code: 4d 8d 75 1a 4c 89 f0 48 c1 e8 03 42 0f b6 04 20 84 c0 0f 85 15 06 00 00 41 0f b7 1e 4d 8d b7 60 05 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 13 06 00 00 66 41 89 1e 4d 8d 75 1c 4c
+RSP: 0018:ffffc90003f5f810 EFLAGS: 00010203
+RAX: 00000000200000ab RBX: 0000000000000000 RCX: 0000000000000000
+RDX: ffff88802a510000 RSI: 00000000ffffffff RDI: ffff888030a6068c
+RBP: ffff88802699fb40 R08: ffff888030a606eb R09: 1ffff1100614c0dd
+R10: dffffc0000000000 R11: ffffffff8718fc40 R12: dffffc0000000000
+R13: ffff888030a60680 R14: 000000010000055f R15: 00000000ffffffff
+FS: 00007f8d7e9236c0(0000) GS:ffff888125c1c000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000000000045ad50 CR3: 0000000075bde000 CR4: 00000000003526f0
+Call Trace:
+ <TASK>
+ vcc_sendmsg+0xa10/0xc60 net/atm/common.c:645
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ __sock_sendmsg+0x219/0x270 net/socket.c:729
+ ____sys_sendmsg+0x505/0x830 net/socket.c:2614
+ ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2668
+ __sys_sendmsg net/socket.c:2700 [inline]
+ __do_sys_sendmsg net/socket.c:2705 [inline]
+ __se_sys_sendmsg net/socket.c:2703 [inline]
+ __x64_sys_sendmsg+0x19b/0x260 net/socket.c:2703
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f8d7e96a4a9
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007f8d7e923198 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f8d7e9f4308 RCX: 00007f8d7e96a4a9
+RDX: 0000000000000000 RSI: 0000200000000240 RDI: 0000000000000005
+RBP: 00007f8d7e9f4300 R08: 65732f636f72702f R09: 65732f636f72702f
+R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f8d7e9c10ac
+R13: 00007f8d7e9231a0 R14: 0000200000000200 R15: 0000200000000250
+ </TASK>
+Modules linked in:
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68a6767c.050a0220.3d78fd.0011.GAE@google.com/
+Tested-by: syzbot+1741b56d54536f4ec349@syzkaller.appspotmail.com
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250821021901.2814721-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/atm/atmtcp.c | 17 ++++++++++++++---
+ include/linux/atmdev.h | 1 +
+ net/atm/common.c | 15 ++++++++++++---
+ 3 files changed, 27 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
+index ff558908897f3..9c83fb29b2f1b 100644
+--- a/drivers/atm/atmtcp.c
++++ b/drivers/atm/atmtcp.c
+@@ -279,6 +279,19 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
+ return NULL;
+ }
+
++static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
++{
++ struct atmtcp_hdr *hdr;
++
++ if (skb->len < sizeof(struct atmtcp_hdr))
++ return -EINVAL;
++
++ hdr = (struct atmtcp_hdr *)skb->data;
++ if (hdr->length == ATMTCP_HDR_MAGIC)
++ return -EINVAL;
++
++ return 0;
++}
+
+ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ {
+@@ -288,9 +301,6 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
+ struct sk_buff *new_skb;
+ int result = 0;
+
+- if (skb->len < sizeof(struct atmtcp_hdr))
+- goto done;
+-
+ dev = vcc->dev_data;
+ hdr = (struct atmtcp_hdr *) skb->data;
+ if (hdr->length == ATMTCP_HDR_MAGIC) {
+@@ -347,6 +357,7 @@ static const struct atmdev_ops atmtcp_v_dev_ops = {
+
+ static const struct atmdev_ops atmtcp_c_dev_ops = {
+ .close = atmtcp_c_close,
++ .pre_send = atmtcp_c_pre_send,
+ .send = atmtcp_c_send
+ };
+
+diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
+index 45f2f278b50a8..70807c679f1ab 100644
+--- a/include/linux/atmdev.h
++++ b/include/linux/atmdev.h
+@@ -185,6 +185,7 @@ struct atmdev_ops { /* only send is required */
+ int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
+ void __user *arg);
+ #endif
++ int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+ int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
+ int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
+diff --git a/net/atm/common.c b/net/atm/common.c
+index 9cc82acbc7358..48bb3f66a3f2a 100644
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -635,18 +635,27 @@ int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size)
+
+ skb->dev = NULL; /* for paths shared with net_device interfaces */
+ if (!copy_from_iter_full(skb_put(skb, size), size, &m->msg_iter)) {
+- atm_return_tx(vcc, skb);
+- kfree_skb(skb);
+ error = -EFAULT;
+- goto out;
++ goto free_skb;
+ }
+ if (eff != size)
+ memset(skb->data + size, 0, eff-size);
++
++ if (vcc->dev->ops->pre_send) {
++ error = vcc->dev->ops->pre_send(vcc, skb);
++ if (error)
++ goto free_skb;
++ }
++
+ error = vcc->dev->ops->send(vcc, skb);
+ error = error ? error : size;
+ out:
+ release_sock(sk);
+ return error;
++free_skb:
++ atm_return_tx(vcc, skb);
++ kfree_skb(skb);
++ goto out;
+ }
+
+ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
+--
+2.50.1
+
--- /dev/null
+From 4fc487d1c4efa2becb85150b0763d1918b00dcee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Aug 2025 17:04:00 -0400
+Subject: Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 15bf2c6391bafb14a3020d06ec0761bce0803463 ]
+
+This attempts to detect if HCI_EV_NUM_COMP_PKTS contain an unbalanced
+(more than currently considered outstanding) number of packets otherwise
+it could cause the hcon->sent to underflow and loop around breaking the
+tracking of the outstanding packets pending acknowledgment.
+
+Fixes: f42809185896 ("Bluetooth: Simplify num_comp_pkts_evt function")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index a07ad1c99a4b0..5eed23b8d6c33 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -4392,7 +4392,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+ if (!conn)
+ continue;
+
+- conn->sent -= count;
++ /* Check if there is really enough packets outstanding before
++ * attempting to decrease the sent counter otherwise it could
++ * underflow..
++ */
++ if (conn->sent >= count) {
++ conn->sent -= count;
++ } else {
++ bt_dev_warn(hdev, "hcon %p sent %u < count %u",
++ conn, conn->sent, count);
++ conn->sent = 0;
++ }
+
+ switch (conn->type) {
+ case ACL_LINK:
+--
+2.50.1
+
--- /dev/null
+From e96a8d41136d799832dc0a75f3ef866fed855b78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:27 +0200
+Subject: Bluetooth: hci_event: Mark connection as closed during suspend
+ disconnect
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit b7fafbc499b5ee164018eb0eefe9027f5a6aaad2 ]
+
+When suspending, the disconnect command for an active Bluetooth
+connection could be issued, but the corresponding
+`HCI_EV_DISCONN_COMPLETE` event might not be received before the system
+completes the suspend process. This can lead to an inconsistent state.
+
+On resume, the controller may auto-accept reconnections from the same
+device (due to suspend event filters), but these new connections are
+rejected by the kernel which still has connection objects from before
+suspend. Resulting in errors like:
+```
+kernel: Bluetooth: hci0: ACL packet for unknown connection handle 1
+kernel: Bluetooth: hci0: Ignoring HCI_Connection_Complete for existing
+connection
+```
+
+This is a btmon snippet that shows the issue:
+```
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+ Handle: 1 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+ Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+ Disconnect (0x01|0x0006) ncmd 2
+ Status: Success (0x00)
+[...]
+// Host suspends with the event filter set for the device
+// On resume, the device tries to reconnect with a new handle
+
+> HCI Event: Connect Complete (0x03) plen 11
+ Status: Success (0x00)
+ Handle: 2
+ Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+
+// Kernel ignores this event because there is an existing connection
+with
+// handle 1
+```
+
+By explicitly setting the connection state to BT_CLOSED we can ensure a
+consistent state, even if we don't receive the disconnect complete event
+in time.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index fb5e4e4858f77..a07ad1c99a4b0 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2707,6 +2707,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+ goto done;
+ }
+
++ /* During suspend, mark connection as closed immediately
++ * since we might not receive HCI_EV_DISCONN_COMPLETE
++ */
++ if (hdev->suspended)
++ conn->state = BT_CLOSED;
++
+ mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
+
+ if (conn->type == ACL_LINK) {
+--
+2.50.1
+
--- /dev/null
+From 20ddcc5dba9be8ec57cb33fae759b1ba02e0815e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 17:55:26 +0200
+Subject: Bluetooth: hci_event: Treat UNKNOWN_CONN_ID on disconnect as success
+
+From: Ludovico de Nittis <ludovico.denittis@collabora.com>
+
+[ Upstream commit 2f050a5392b7a0928bf836d9891df4851463512c ]
+
+When the host sends an HCI_OP_DISCONNECT command, the controller may
+respond with the status HCI_ERROR_UNKNOWN_CONN_ID (0x02). E.g. this can
+happen on resume from suspend, if the link was terminated by the remote
+device before the event mask was correctly set.
+
+This is a btmon snippet that shows the issue:
+```
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+ L2CAP: Disconnection Request (0x06) ident 5 len 4
+ Destination CID: 65
+ Source CID: 72
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+ L2CAP: Disconnection Response (0x07) ident 5 len 4
+ Destination CID: 65
+ Source CID: 72
+> ACL Data RX: Handle 3 flags 0x02 dlen 12
+ L2CAP: Disconnection Request (0x06) ident 6 len 4
+ Destination CID: 64
+ Source CID: 71
+< ACL Data TX: Handle 3 flags 0x00 dlen 12
+ L2CAP: Disconnection Response (0x07) ident 6 len 4
+ Destination CID: 64
+ Source CID: 71
+< HCI Command: Set Event Mask (0x03|0x0001) plen 8
+ Mask: 0x3dbff807fffbffff
+ Inquiry Complete
+ Inquiry Result
+ Connection Complete
+ Connection Request
+ Disconnection Complete
+ Authentication Complete
+[...]
+< HCI Command: Disconnect (0x01|0x0006) plen 3
+ Handle: 3 Address: 78:20:A5:4A:DF:28 (Nintendo Co.,Ltd)
+ Reason: Remote User Terminated Connection (0x13)
+> HCI Event: Command Status (0x0f) plen 4
+ Disconnect (0x01|0x0006) ncmd 1
+ Status: Unknown Connection Identifier (0x02)
+```
+
+Currently, the hci_cs_disconnect function treats any non-zero status
+as a command failure. This can be misleading because the connection is
+indeed being terminated and the controller is confirming that is has no
+knowledge of that connection handle. Meaning that the initial request of
+disconnecting a device should be treated as done.
+
+With this change we allow the function to proceed, following the success
+path, which correctly calls `mgmt_device_disconnected` and ensures a
+consistent state.
+
+Link: https://github.com/bluez/bluez/issues/1226
+Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier")
+Signed-off-by: Ludovico de Nittis <ludovico.denittis@collabora.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bluetooth/hci_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index c06010c0d8829..fb5e4e4858f77 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -2692,7 +2692,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
+ if (!conn)
+ goto unlock;
+
+- if (status) {
++ if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
+ mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+ conn->dst_type, status);
+
+--
+2.50.1
+
--- /dev/null
+From f89392b975eceaa442c3fc8ea797d98242860861 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Aug 2025 12:20:55 +0300
+Subject: Bluetooth: hci_sync: fix set_local_name race condition
+
+From: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+
+[ Upstream commit 6bbd0d3f0c23fc53c17409dd7476f38ae0ff0cd9 ]
+
+Function set_name_sync() uses hdev->dev_name field to send
+HCI_OP_WRITE_LOCAL_NAME command, but copying from data to hdev->dev_name
+is called after mgmt cmd was queued, so it is possible that function
+set_name_sync() will read old name value.
+
+This change adds name as a parameter for function hci_update_name_sync()
+to avoid race condition.
+
+Fixes: 6f6ff38a1e14 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LOCAL_NAME")
+Signed-off-by: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/hci_sync.h | 2 +-
+ net/bluetooth/hci_sync.c | 6 +++---
+ net/bluetooth/mgmt.c | 5 ++++-
+ 3 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
+index 3cb2d10cac930..e2e588b08fe90 100644
+--- a/include/net/bluetooth/hci_sync.h
++++ b/include/net/bluetooth/hci_sync.h
+@@ -72,7 +72,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
+
+ int hci_update_eir_sync(struct hci_dev *hdev);
+ int hci_update_class_sync(struct hci_dev *hdev);
+-int hci_update_name_sync(struct hci_dev *hdev);
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
+ int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
+
+ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index 01aca07707117..020f1809fc994 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3491,13 +3491,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
+ return hci_write_scan_enable_sync(hdev, scan);
+ }
+
+-int hci_update_name_sync(struct hci_dev *hdev)
++int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
+ {
+ struct hci_cp_write_local_name cp;
+
+ memset(&cp, 0, sizeof(cp));
+
+- memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
++ memcpy(cp.name, name, sizeof(cp.name));
+
+ return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
+ sizeof(cp), &cp,
+@@ -3550,7 +3550,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
+ hci_write_fast_connectable_sync(hdev, false);
+ hci_update_scan_sync(hdev);
+ hci_update_class_sync(hdev);
+- hci_update_name_sync(hdev);
++ hci_update_name_sync(hdev, hdev->dev_name);
+ hci_update_eir_sync(hdev);
+ }
+
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 82fa8c28438f2..9b01eaaa0eb2d 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -3819,8 +3819,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
+
+ static int set_name_sync(struct hci_dev *hdev, void *data)
+ {
++ struct mgmt_pending_cmd *cmd = data;
++ struct mgmt_cp_set_local_name *cp = cmd->param;
++
+ if (lmp_bredr_capable(hdev)) {
+- hci_update_name_sync(hdev);
++ hci_update_name_sync(hdev, cp->name);
+ hci_update_eir_sync(hdev);
+ }
+
+--
+2.50.1
+
--- /dev/null
+From a03fa1a6628bde0d8f40b6af39118a4b88397457 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Jul 2025 13:28:22 -0700
+Subject: drm/msm: Defer fd_install in SUBMIT ioctl
+
+From: Rob Clark <robin.clark@oss.qualcomm.com>
+
+[ Upstream commit f22853435bbd1e9836d0dce7fd99c040b94c2bf1 ]
+
+Avoid fd_install() until there are no more potential error paths, to
+avoid put_unused_fd() after the fd is made visible to userspace.
+
+Fixes: 68dc6c2d5eec ("drm/msm: Fix submit error-path leaks")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/665363/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
+index bbe4f1665b603..dc142f9e4f602 100644
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c
+@@ -981,12 +981,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+
+ if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+ sync_file = sync_file_create(submit->user_fence);
+- if (!sync_file) {
++ if (!sync_file)
+ ret = -ENOMEM;
+- } else {
+- fd_install(out_fence_fd, sync_file->file);
+- args->fence_fd = out_fence_fd;
+- }
+ }
+
+ submit_attach_object_fences(submit);
+@@ -1013,10 +1009,14 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+ out_unlock:
+ mutex_unlock(&queue->lock);
+ out_post_unlock:
+- if (ret && (out_fence_fd >= 0)) {
+- put_unused_fd(out_fence_fd);
++ if (ret) {
++ if (out_fence_fd >= 0)
++ put_unused_fd(out_fence_fd);
+ if (sync_file)
+ fput(sync_file->file);
++ } else if (sync_file) {
++ fd_install(out_fence_fd, sync_file->file);
++ args->fence_fd = out_fence_fd;
+ }
+
+ if (!IS_ERR_OR_NULL(submit)) {
+--
+2.50.1
+
--- /dev/null
+From fc83643fe0827a46683640052a4287ae9bf5109b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:03 -0500
+Subject: drm/nouveau: remove unused increment in gm200_flcn_pio_imem_wr
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit f529b8915543fb9ceb732cec5571f7fe12bc9530 ]
+
+The 'tag' parameter is passed by value and is not actually used after
+being incremented, so remove the increment. It's the function that calls
+gm200_flcn_pio_imem_wr that is supposed to (and does) increment 'tag'.
+
+Fixes: 0e44c2170876 ("drm/nouveau/flcn: new code to load+boot simple HS FWs (VPR scrubber)")
+Reviewed-by: Philipp Stanner <phasta@kernel.org>
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-2-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index b7da3ab44c277..6a004c6e67425 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -103,7 +103,7 @@ gm200_flcn_pio_imem_wr_init(struct nvkm_falcon *falcon, u8 port, bool sec, u32 i
+ static void
+ gm200_flcn_pio_imem_wr(struct nvkm_falcon *falcon, u8 port, const u8 *img, int len, u16 tag)
+ {
+- nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag++);
++ nvkm_falcon_wr32(falcon, 0x188 + (port * 0x10), tag);
+ while (len >= 4) {
+ nvkm_falcon_wr32(falcon, 0x184 + (port * 0x10), *(u32 *)img);
+ img += 4;
+--
+2.50.1
+
--- /dev/null
+From fc29d890a49f334fc8a809b2a8b2381604528a56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Aug 2025 19:10:04 -0500
+Subject: drm/nouveau: remove unused memory target test
+
+From: Timur Tabi <ttabi@nvidia.com>
+
+[ Upstream commit 64c722b5e7f6b909b0e448e580f64628a0d76208 ]
+
+The memory target check is a hold-over from a refactor. It's harmless
+but distracting, so just remove it.
+
+Fixes: 2541626cfb79 ("drm/nouveau/acr: use common falcon HS FW code for ACR FWs")
+Signed-off-by: Timur Tabi <ttabi@nvidia.com>
+Link: https://lore.kernel.org/r/20250813001004.2986092-3-ttabi@nvidia.com
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+index 6a004c6e67425..7c43397c19e61 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/falcon/gm200.c
+@@ -249,9 +249,11 @@ int
+ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+ {
+ struct nvkm_falcon *falcon = fw->falcon;
+- int target, ret;
++ int ret;
+
+ if (fw->inst) {
++ int target;
++
+ nvkm_falcon_mask(falcon, 0x048, 0x00000001, 0x00000001);
+
+ switch (nvkm_memory_target(fw->inst)) {
+@@ -285,15 +287,6 @@ gm200_flcn_fw_load(struct nvkm_falcon_fw *fw)
+ }
+
+ if (fw->boot) {
+- switch (nvkm_memory_target(&fw->fw.mem.memory)) {
+- case NVKM_MEM_TARGET_VRAM: target = 4; break;
+- case NVKM_MEM_TARGET_HOST: target = 5; break;
+- case NVKM_MEM_TARGET_NCOH: target = 6; break;
+- default:
+- WARN_ON(1);
+- return -EINVAL;
+- }
+-
+ ret = nvkm_falcon_pio_wr(falcon, fw->boot, 0, 0,
+ IMEM, falcon->code.limit - fw->boot_size, fw->boot_size,
+ fw->boot_addr >> 8, false);
+--
+2.50.1
+
--- /dev/null
+From cfa3271a53d1cc123f2329f18fe2256bc3265c45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 9 Aug 2025 11:36:54 +0300
+Subject: dt-bindings: display/msm: qcom,mdp5: drop lut clock
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit 7ab3b7579a6d2660a3425b9ea93b9a140b07f49c ]
+
+None of MDP5 platforms have a LUT clock on the display-controller, it
+was added by the mistake. Drop it, fixing DT warnings on MSM8976 /
+MSM8956 platforms. Technically it's an ABI break, but no other platforms
+are affected.
+
+Fixes: 385c8ac763b3 ("dt-bindings: display/msm: convert MDP5 schema to YAML format")
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Patchwork: https://patchwork.freedesktop.org/patch/667822/
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+index 91c774f106ceb..ab1196d1ec2dd 100644
+--- a/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
++++ b/Documentation/devicetree/bindings/display/msm/qcom,mdp5.yaml
+@@ -59,7 +59,6 @@ properties:
+ - const: bus
+ - const: core
+ - const: vsync
+- - const: lut
+ - const: tbu
+ - const: tbu_rt
+ # MSM8996 has additional iommu clock
+--
+2.50.1
+
--- /dev/null
+From 4bd779158a3bfc1c9c06f418a2df5d81a7ce02b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 15:39:54 +0800
+Subject: efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare
+
+From: Li Nan <linan122@huawei.com>
+
+[ Upstream commit a6358f8cf64850f3f27857b8ed8c1b08cfc4685c ]
+
+Observed on kernel 6.6 (present on master as well):
+
+ BUG: KASAN: slab-out-of-bounds in memcmp+0x98/0xd0
+ Call trace:
+ kasan_check_range+0xe8/0x190
+ __asan_loadN+0x1c/0x28
+ memcmp+0x98/0xd0
+ efivarfs_d_compare+0x68/0xd8
+ __d_lookup_rcu_op_compare+0x178/0x218
+ __d_lookup_rcu+0x1f8/0x228
+ d_alloc_parallel+0x150/0x648
+ lookup_open.isra.0+0x5f0/0x8d0
+ open_last_lookups+0x264/0x828
+ path_openat+0x130/0x3f8
+ do_filp_open+0x114/0x248
+ do_sys_openat2+0x340/0x3c0
+ __arm64_sys_openat+0x120/0x1a0
+
+If dentry->d_name.len < EFI_VARIABLE_GUID_LEN , 'guid' can become
+negative, leadings to oob. The issue can be triggered by parallel
+lookups using invalid filename:
+
+ T1 T2
+ lookup_open
+ ->lookup
+ simple_lookup
+ d_add
+ // invalid dentry is added to hash list
+
+ lookup_open
+ d_alloc_parallel
+ __d_lookup_rcu
+ __d_lookup_rcu_op_compare
+ hlist_bl_for_each_entry_rcu
+ // invalid dentry can be retrieved
+ ->d_compare
+ efivarfs_d_compare
+ // oob
+
+Fix it by checking 'guid' before cmp.
+
+Fixes: da27a24383b2 ("efivarfs: guid part of filenames are case-insensitive")
+Signed-off-by: Li Nan <linan122@huawei.com>
+Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/efivarfs/super.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index 586c5709dfb55..34438981ddd80 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -90,6 +90,10 @@ static int efivarfs_d_compare(const struct dentry *dentry,
+ {
+ int guid = len - EFI_VARIABLE_GUID_LEN;
+
++ /* Parallel lookups may produce a temporary invalid filename */
++ if (guid <= 0)
++ return 1;
++
+ if (name->len != len)
+ return 1;
+
+--
+2.50.1
+
--- /dev/null
+From c0e020b69ab9cc830030b0eb40c9d9a68875e070 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:39 +0200
+Subject: HID: input: rename hidinput_set_battery_charge_status()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit a82231b2a8712d0218fc286a9b0da328d419a3f4 ]
+
+In preparation for a patch fixing a bug affecting
+hidinput_set_battery_charge_status(), rename the function to
+hidinput_update_battery_charge_status() and move it up so it can be used
+by hidinput_update_battery().
+
+Refactor, no functional changes.
+
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Stable-dep-of: e94536e1d181 ("HID: input: report battery status changes immediately")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input-test.c | 10 +++++-----
+ drivers/hid/hid-input.c | 38 ++++++++++++++++++------------------
+ 2 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c
+index 77c2d45ac62a7..6f5c71660d823 100644
+--- a/drivers/hid/hid-input-test.c
++++ b/drivers/hid/hid-input-test.c
+@@ -7,7 +7,7 @@
+
+ #include <kunit/test.h>
+
+-static void hid_test_input_set_battery_charge_status(struct kunit *test)
++static void hid_test_input_update_battery_charge_status(struct kunit *test)
+ {
+ struct hid_device *dev;
+ bool handled;
+@@ -15,15 +15,15 @@ static void hid_test_input_set_battery_charge_status(struct kunit *test)
+ dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
++ handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
+ KUNIT_EXPECT_FALSE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
++ handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
+ KUNIT_EXPECT_TRUE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
+
+- handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
++ handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
+ KUNIT_EXPECT_TRUE(test, handled);
+ KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
+ }
+@@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
+ }
+
+ static struct kunit_case hid_input_tests[] = {
+- KUNIT_CASE(hid_test_input_set_battery_charge_status),
++ KUNIT_CASE(hid_test_input_update_battery_charge_status),
+ KUNIT_CASE(hid_test_input_get_battery_property),
+ { }
+ };
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 9d80635a91ebd..b372b74f3e24b 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -595,6 +595,20 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ dev->battery = NULL;
+ }
+
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++ unsigned int usage, int value)
++{
++ switch (usage) {
++ case HID_BAT_CHARGING:
++ dev->battery_charge_status = value ?
++ POWER_SUPPLY_STATUS_CHARGING :
++ POWER_SUPPLY_STATUS_DISCHARGING;
++ return true;
++ }
++
++ return false;
++}
++
+ static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+ int capacity;
+@@ -617,20 +631,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
+ power_supply_changed(dev->battery);
+ }
+ }
+-
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
+-{
+- switch (usage) {
+- case HID_BAT_CHARGING:
+- dev->battery_charge_status = value ?
+- POWER_SUPPLY_STATUS_CHARGING :
+- POWER_SUPPLY_STATUS_DISCHARGING;
+- return true;
+- }
+-
+- return false;
+-}
+ #else /* !CONFIG_HID_BATTERY_STRENGTH */
+ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+ struct hid_field *field, bool is_percentage)
+@@ -642,14 +642,14 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static bool hidinput_update_battery_charge_status(struct hid_device *dev,
++ unsigned int usage, int value)
+ {
++ return false;
+ }
+
+-static bool hidinput_set_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
++static void hidinput_update_battery(struct hid_device *dev, int value)
+ {
+- return false;
+ }
+ #endif /* CONFIG_HID_BATTERY_STRENGTH */
+
+@@ -1515,7 +1515,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+ return;
+
+ if (usage->type == EV_PWR) {
+- bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
++ bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+
+ if (!handled)
+ hidinput_update_battery(hid, value);
+--
+2.50.1
+
--- /dev/null
+From 9c99b289313b7897a310c5628ed9ba80accbe2f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Aug 2025 12:39:40 +0200
+Subject: HID: input: report battery status changes immediately
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: José Expósito <jose.exposito89@gmail.com>
+
+[ Upstream commit e94536e1d1818b0989aa19b443b7089f50133c35 ]
+
+Previously, the battery status (charging/discharging) was not reported
+immediately to user-space.
+
+For most input devices, this wasn't problematic because changing their
+battery status requires connecting them to a different bus.
+For example, a gamepad would report a discharging status while
+connected via Bluetooth and a charging status while connected via USB.
+
+However, certain devices are not connected or disconnected when their
+battery status changes. For example, a phone battery changes its status
+without connecting or disconnecting it.
+In these cases, the battery status was not reported immediately to user
+space.
+
+Report battery status changes immediately to user space to support
+these kinds of devices.
+
+Fixes: a608dc1c0639 ("HID: input: map battery system charging")
+Reported-by: 卢国宏 <luguohong@xiaomi.com>
+Closes: https://lore.kernel.org/linux-input/aI49Im0sGb6fpgc8@fedora/T/
+Tested-by: 卢国宏 <luguohong@xiaomi.com>
+Signed-off-by: José Expósito <jose.exposito89@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hid/hid-input.c | 23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index b372b74f3e24b..f5c217ac4bfaa 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -609,13 +609,19 @@ static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+ return false;
+ }
+
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++ int value)
+ {
+ int capacity;
+
+ if (!dev->battery)
+ return;
+
++ if (hidinput_update_battery_charge_status(dev, usage, value)) {
++ power_supply_changed(dev->battery);
++ return;
++ }
++
+ if (value == 0 || value < dev->battery_min || value > dev->battery_max)
+ return;
+
+@@ -642,13 +648,8 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
+ {
+ }
+
+-static bool hidinput_update_battery_charge_status(struct hid_device *dev,
+- unsigned int usage, int value)
+-{
+- return false;
+-}
+-
+-static void hidinput_update_battery(struct hid_device *dev, int value)
++static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
++ int value)
+ {
+ }
+ #endif /* CONFIG_HID_BATTERY_STRENGTH */
+@@ -1515,11 +1516,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+ return;
+
+ if (usage->type == EV_PWR) {
+- bool handled = hidinput_update_battery_charge_status(hid, usage->hid, value);
+-
+- if (!handled)
+- hidinput_update_battery(hid, value);
+-
++ hidinput_update_battery(hid, usage->hid, value);
+ return;
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 542aaf000548c5e1c84555586ca0c1086792d8c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Aug 2025 17:53:10 +0200
+Subject: ice: fix incorrect counter for buffer allocation failures
+
+From: Michal Kubiak <michal.kubiak@intel.com>
+
+[ Upstream commit b1a0c977c6f1130f7dd125ee3db8c2435d7e3d41 ]
+
+Currently, the driver increments `alloc_page_failed` when buffer allocation fails
+in `ice_clean_rx_irq()`. However, this counter is intended for page allocation
+failures, not buffer allocation issues.
+
+This patch corrects the counter by incrementing `alloc_buf_failed` instead,
+ensuring accurate statistics reporting for buffer allocation failures.
+
+Fixes: 2fba7dc5157b ("ice: Add support for XDP multi-buffer on Rx side")
+Reported-by: Jacob Keller <jacob.e.keller@intel.com>
+Suggested-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Tested-by: Priya Singh <priyax.singh@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index e7084c6aab6da..eae4376c68595 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -1297,7 +1297,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ skb = ice_construct_skb(rx_ring, xdp);
+ /* exit if we failed to retrieve a buffer */
+ if (!skb) {
+- rx_ring->ring_stats->rx_stats.alloc_page_failed++;
++ rx_ring->ring_stats->rx_stats.alloc_buf_failed++;
+ xdp_verdict = ICE_XDP_CONSUMED;
+ }
+ ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+--
+2.50.1
+
--- /dev/null
+From f1efbf972a288ff9f706dd2c69e6745f21199b32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 16:01:17 +0100
+Subject: ice: gather page_count()'s of each frag right before XDP prog call
+
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+
+[ Upstream commit 11c4aa074d547d825b19cd8d9f288254d89d805c ]
+
+If we store the pgcnt on few fragments while being in the middle of
+gathering the whole frame and we stumbled upon DD bit not being set, we
+terminate the NAPI Rx processing loop and come back later on. Then on
+next NAPI execution we work on previously stored pgcnt.
+
+Imagine that second half of page was used actively by networking stack
+and by the time we came back, stack is not busy with this page anymore
+and decremented the refcnt. The page reuse algorithm in this case should
+be good to reuse the page but given the old refcnt it will not do so and
+attempt to release the page via page_frag_cache_drain() with
+pagecnt_bias used as an arg. This in turn will result in negative refcnt
+on struct page, which was initially observed by Xu Du.
+
+Therefore, move the page count storage from ice_get_rx_buf() to a place
+where we are sure that whole frame has been collected, but before
+calling XDP program as it internally can also change the page count of
+fragments belonging to xdp_buff.
+
+Fixes: ac0753391195 ("ice: Store page count inside ice_rx_buf")
+Reported-and-tested-by: Xu Du <xudu@redhat.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Co-developed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Tested-by: Chandan Kumar Rout <chandanx.rout@intel.com> (A Contingent Worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: b1a0c977c6f1 ("ice: fix incorrect counter for buffer allocation failures")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 27 ++++++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index 46f10f32924ee..beb5c8643fe7d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -924,7 +924,6 @@ ice_get_rx_buf(struct ice_rx_ring *rx_ring, const unsigned int size,
+ struct ice_rx_buf *rx_buf;
+
+ rx_buf = &rx_ring->rx_buf[ntc];
+- rx_buf->pgcnt = page_count(rx_buf->page);
+ prefetchw(rx_buf->page);
+
+ if (!size)
+@@ -940,6 +939,31 @@ ice_get_rx_buf(struct ice_rx_ring *rx_ring, const unsigned int size,
+ return rx_buf;
+ }
+
++/**
++ * ice_get_pgcnts - grab page_count() for gathered fragments
++ * @rx_ring: Rx descriptor ring to store the page counts on
++ *
++ * This function is intended to be called right before running XDP
++ * program so that the page recycling mechanism will be able to take
++ * a correct decision regarding underlying pages; this is done in such
++ * way as XDP program can change the refcount of page
++ */
++static void ice_get_pgcnts(struct ice_rx_ring *rx_ring)
++{
++ u32 nr_frags = rx_ring->nr_frags + 1;
++ u32 idx = rx_ring->first_desc;
++ struct ice_rx_buf *rx_buf;
++ u32 cnt = rx_ring->count;
++
++ for (int i = 0; i < nr_frags; i++) {
++ rx_buf = &rx_ring->rx_buf[idx];
++ rx_buf->pgcnt = page_count(rx_buf->page);
++
++ if (++idx == cnt)
++ idx = 0;
++ }
++}
++
+ /**
+ * ice_build_skb - Build skb around an existing buffer
+ * @rx_ring: Rx descriptor ring to transact packets on
+@@ -1243,6 +1267,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ if (ice_is_non_eop(rx_ring, rx_desc))
+ continue;
+
++ ice_get_pgcnts(rx_ring);
+ ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf, rx_desc);
+ if (rx_buf->act == ICE_XDP_PASS)
+ goto construct_skb;
+--
+2.50.1
+
--- /dev/null
+From a5a6221a29b14c86f4ff94984cbe9bd80c30aea0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 22:08:33 +0100
+Subject: ice: Introduce ice_xdp_buff
+
+From: Larysa Zaremba <larysa.zaremba@intel.com>
+
+[ Upstream commit d951c14ad237b087f0d1377c44932fcc0b322c40 ]
+
+In order to use XDP hints via kfuncs we need to put
+RX descriptor and miscellaneous data next to xdp_buff.
+Same as in hints implementations in other drivers, we achieve
+this through putting xdp_buff into a child structure.
+
+Currently, xdp_buff is stored in the ring structure,
+so replace it with union that includes child structure.
+This way enough memory is available while existing XDP code
+remains isolated from hints.
+
+Minimum size of the new child structure (ice_xdp_buff) is exactly
+64 bytes (single cache line). To place it at the start of a cache line,
+move 'next' field from CL1 to CL4, as it isn't used often. This still
+leaves 192 bits available in CL3 for packet context extensions.
+
+Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
+Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Link: https://lore.kernel.org/r/20231205210847.28460-5-larysa.zaremba@intel.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Stable-dep-of: b1a0c977c6f1 ("ice: fix incorrect counter for buffer allocation failures")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 7 +++++--
+ drivers/net/ethernet/intel/ice/ice_txrx.h | 18 +++++++++++++++---
+ drivers/net/ethernet/intel/ice/ice_txrx_lib.h | 10 ++++++++++
+ 3 files changed, 30 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index f5023ac9ab832..46f10f32924ee 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -528,13 +528,14 @@ int ice_setup_rx_ring(struct ice_rx_ring *rx_ring)
+ * @xdp_prog: XDP program to run
+ * @xdp_ring: ring to be used for XDP_TX action
+ * @rx_buf: Rx buffer to store the XDP action
++ * @eop_desc: Last descriptor in packet to read metadata from
+ *
+ * Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR}
+ */
+ static void
+ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+ struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring,
+- struct ice_rx_buf *rx_buf)
++ struct ice_rx_buf *rx_buf, union ice_32b_rx_flex_desc *eop_desc)
+ {
+ unsigned int ret = ICE_XDP_PASS;
+ u32 act;
+@@ -542,6 +543,8 @@ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+ if (!xdp_prog)
+ goto exit;
+
++ ice_xdp_meta_set_desc(xdp, eop_desc);
++
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
+ switch (act) {
+ case XDP_PASS:
+@@ -1240,7 +1243,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ if (ice_is_non_eop(rx_ring, rx_desc))
+ continue;
+
+- ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf);
++ ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf, rx_desc);
+ if (rx_buf->act == ICE_XDP_PASS)
+ goto construct_skb;
+ total_rx_bytes += xdp_get_buff_len(xdp);
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
+index 407d4c320097f..ad2d286bd359d 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
+@@ -257,6 +257,14 @@ enum ice_rx_dtype {
+ ICE_RX_DTYPE_SPLIT_ALWAYS = 2,
+ };
+
++struct ice_xdp_buff {
++ struct xdp_buff xdp_buff;
++ const union ice_32b_rx_flex_desc *eop_desc;
++};
++
++/* Required for compatibility with xdp_buffs from xsk_pool */
++static_assert(offsetof(struct ice_xdp_buff, xdp_buff) == 0);
++
+ /* indices into GLINT_ITR registers */
+ #define ICE_RX_ITR ICE_IDX_ITR0
+ #define ICE_TX_ITR ICE_IDX_ITR1
+@@ -298,7 +306,6 @@ enum ice_dynamic_itr {
+ /* descriptor ring, associated with a VSI */
+ struct ice_rx_ring {
+ /* CL1 - 1st cacheline starts here */
+- struct ice_rx_ring *next; /* pointer to next ring in q_vector */
+ void *desc; /* Descriptor ring memory */
+ struct device *dev; /* Used for DMA mapping */
+ struct net_device *netdev; /* netdev ring maps to */
+@@ -310,12 +317,16 @@ struct ice_rx_ring {
+ u16 count; /* Number of descriptors */
+ u16 reg_idx; /* HW register index of the ring */
+ u16 next_to_alloc;
+- /* CL2 - 2nd cacheline starts here */
++
+ union {
+ struct ice_rx_buf *rx_buf;
+ struct xdp_buff **xdp_buf;
+ };
+- struct xdp_buff xdp;
++ /* CL2 - 2nd cacheline starts here */
++ union {
++ struct ice_xdp_buff xdp_ext;
++ struct xdp_buff xdp;
++ };
+ /* CL3 - 3rd cacheline starts here */
+ struct bpf_prog *xdp_prog;
+ u16 rx_offset;
+@@ -332,6 +343,7 @@ struct ice_rx_ring {
+ /* CL4 - 4th cacheline starts here */
+ struct ice_channel *ch;
+ struct ice_tx_ring *xdp_ring;
++ struct ice_rx_ring *next; /* pointer to next ring in q_vector */
+ struct xsk_buff_pool *xsk_pool;
+ u32 nr_frags;
+ dma_addr_t dma; /* physical address of ring */
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
+index b0e56675f98b2..00971f8491358 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
+@@ -164,4 +164,14 @@ ice_process_skb_fields(struct ice_rx_ring *rx_ring,
+ struct sk_buff *skb, u16 ptype);
+ void
+ ice_receive_skb(struct ice_rx_ring *rx_ring, struct sk_buff *skb, u16 vlan_tag);
++
++static inline void
++ice_xdp_meta_set_desc(struct xdp_buff *xdp,
++ union ice_32b_rx_flex_desc *eop_desc)
++{
++ struct ice_xdp_buff *xdp_ext = container_of(xdp, struct ice_xdp_buff,
++ xdp_buff);
++
++ xdp_ext->eop_desc = eop_desc;
++}
+ #endif /* !_ICE_TXRX_LIB_H_ */
+--
+2.50.1
+
--- /dev/null
+From 995eca567db21c04c41f7106762898c7fabae519 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jan 2025 16:01:18 +0100
+Subject: ice: stop storing XDP verdict within ice_rx_buf
+
+From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+
+[ Upstream commit 468a1952df78f65c5991b7ac885c8b5b7dd87bab ]
+
+Idea behind having ice_rx_buf::act was to simplify and speed up the Rx
+data path by walking through buffers that were representing cleaned HW
+Rx descriptors. Since it caused us a major headache recently and we
+rolled back to old approach that 'puts' Rx buffers right after running
+XDP prog/creating skb, this is useless now and should be removed.
+
+Get rid of ice_rx_buf::act and related logic. We still need to take care
+of a corner case where XDP program releases a particular fragment.
+
+Make ice_run_xdp() to return its result and use it within
+ice_put_rx_mbuf().
+
+Fixes: 2fba7dc5157b ("ice: Add support for XDP multi-buffer on Rx side")
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
+Tested-by: Chandan Kumar Rout <chandanx.rout@intel.com> (A Contingent Worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: b1a0c977c6f1 ("ice: fix incorrect counter for buffer allocation failures")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 62 +++++++++++--------
+ drivers/net/ethernet/intel/ice/ice_txrx.h | 1 -
+ drivers/net/ethernet/intel/ice/ice_txrx_lib.h | 43 -------------
+ 3 files changed, 36 insertions(+), 70 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index beb5c8643fe7d..e7084c6aab6da 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -527,15 +527,14 @@ int ice_setup_rx_ring(struct ice_rx_ring *rx_ring)
+ * @xdp: xdp_buff used as input to the XDP program
+ * @xdp_prog: XDP program to run
+ * @xdp_ring: ring to be used for XDP_TX action
+- * @rx_buf: Rx buffer to store the XDP action
+ * @eop_desc: Last descriptor in packet to read metadata from
+ *
+ * Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR}
+ */
+-static void
++static u32
+ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+ struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring,
+- struct ice_rx_buf *rx_buf, union ice_32b_rx_flex_desc *eop_desc)
++ union ice_32b_rx_flex_desc *eop_desc)
+ {
+ unsigned int ret = ICE_XDP_PASS;
+ u32 act;
+@@ -574,7 +573,7 @@ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+ ret = ICE_XDP_CONSUMED;
+ }
+ exit:
+- ice_set_rx_bufs_act(xdp, rx_ring, ret);
++ return ret;
+ }
+
+ /**
+@@ -860,10 +859,8 @@ ice_add_xdp_frag(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+ xdp_buff_set_frags_flag(xdp);
+ }
+
+- if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) {
+- ice_set_rx_bufs_act(xdp, rx_ring, ICE_XDP_CONSUMED);
++ if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS))
+ return -ENOMEM;
+- }
+
+ __skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, rx_buf->page,
+ rx_buf->page_offset, size);
+@@ -1076,12 +1073,12 @@ ice_construct_skb(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp)
+ rx_buf->page_offset + headlen, size,
+ xdp->frame_sz);
+ } else {
+- /* buffer is unused, change the act that should be taken later
+- * on; data was copied onto skb's linear part so there's no
++ /* buffer is unused, restore biased page count in Rx buffer;
++ * data was copied onto skb's linear part so there's no
+ * need for adjusting page offset and we can reuse this buffer
+ * as-is
+ */
+- rx_buf->act = ICE_SKB_CONSUMED;
++ rx_buf->pagecnt_bias++;
+ }
+
+ if (unlikely(xdp_buff_has_frags(xdp))) {
+@@ -1134,29 +1131,34 @@ ice_put_rx_buf(struct ice_rx_ring *rx_ring, struct ice_rx_buf *rx_buf)
+ * @xdp: XDP buffer carrying linear + frags part
+ * @xdp_xmit: XDP_TX/XDP_REDIRECT verdict storage
+ * @ntc: a current next_to_clean value to be stored at rx_ring
++ * @verdict: return code from XDP program execution
+ *
+ * Walk through gathered fragments and satisfy internal page
+ * recycle mechanism; we take here an action related to verdict
+ * returned by XDP program;
+ */
+ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+- u32 *xdp_xmit, u32 ntc)
++ u32 *xdp_xmit, u32 ntc, u32 verdict)
+ {
+ u32 nr_frags = rx_ring->nr_frags + 1;
+ u32 idx = rx_ring->first_desc;
+ u32 cnt = rx_ring->count;
++ u32 post_xdp_frags = 1;
+ struct ice_rx_buf *buf;
+ int i;
+
+- for (i = 0; i < nr_frags; i++) {
++ if (unlikely(xdp_buff_has_frags(xdp)))
++ post_xdp_frags += xdp_get_shared_info_from_buff(xdp)->nr_frags;
++
++ for (i = 0; i < post_xdp_frags; i++) {
+ buf = &rx_ring->rx_buf[idx];
+
+- if (buf->act & (ICE_XDP_TX | ICE_XDP_REDIR)) {
++ if (verdict & (ICE_XDP_TX | ICE_XDP_REDIR)) {
+ ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
+- *xdp_xmit |= buf->act;
+- } else if (buf->act & ICE_XDP_CONSUMED) {
++ *xdp_xmit |= verdict;
++ } else if (verdict & ICE_XDP_CONSUMED) {
+ buf->pagecnt_bias++;
+- } else if (buf->act == ICE_XDP_PASS) {
++ } else if (verdict == ICE_XDP_PASS) {
+ ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
+ }
+
+@@ -1165,6 +1167,17 @@ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+ if (++idx == cnt)
+ idx = 0;
+ }
++ /* handle buffers that represented frags released by XDP prog;
++ * for these we keep pagecnt_bias as-is; refcount from struct page
++ * has been decremented within XDP prog and we do not have to increase
++ * the biased refcnt
++ */
++ for (; i < nr_frags; i++) {
++ buf = &rx_ring->rx_buf[idx];
++ ice_put_rx_buf(rx_ring, buf);
++ if (++idx == cnt)
++ idx = 0;
++ }
+
+ xdp->data = NULL;
+ rx_ring->first_desc = ntc;
+@@ -1191,9 +1204,9 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ struct ice_tx_ring *xdp_ring = NULL;
+ struct bpf_prog *xdp_prog = NULL;
+ u32 ntc = rx_ring->next_to_clean;
++ u32 cached_ntu, xdp_verdict;
+ u32 cnt = rx_ring->count;
+ u32 xdp_xmit = 0;
+- u32 cached_ntu;
+ bool failure;
+
+ xdp_prog = READ_ONCE(rx_ring->xdp_prog);
+@@ -1257,7 +1270,7 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ xdp_prepare_buff(xdp, hard_start, offset, size, !!offset);
+ xdp_buff_clear_frags_flag(xdp);
+ } else if (ice_add_xdp_frag(rx_ring, xdp, rx_buf, size)) {
+- ice_put_rx_mbuf(rx_ring, xdp, NULL, ntc);
++ ice_put_rx_mbuf(rx_ring, xdp, NULL, ntc, ICE_XDP_CONSUMED);
+ break;
+ }
+ if (++ntc == cnt)
+@@ -1268,13 +1281,13 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ continue;
+
+ ice_get_pgcnts(rx_ring);
+- ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf, rx_desc);
+- if (rx_buf->act == ICE_XDP_PASS)
++ xdp_verdict = ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_desc);
++ if (xdp_verdict == ICE_XDP_PASS)
+ goto construct_skb;
+ total_rx_bytes += xdp_get_buff_len(xdp);
+ total_rx_pkts++;
+
+- ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc);
++ ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+
+ continue;
+ construct_skb:
+@@ -1285,12 +1298,9 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget)
+ /* exit if we failed to retrieve a buffer */
+ if (!skb) {
+ rx_ring->ring_stats->rx_stats.alloc_page_failed++;
+- rx_buf->act = ICE_XDP_CONSUMED;
+- if (unlikely(xdp_buff_has_frags(xdp)))
+- ice_set_rx_bufs_act(xdp, rx_ring,
+- ICE_XDP_CONSUMED);
++ xdp_verdict = ICE_XDP_CONSUMED;
+ }
+- ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc);
++ ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+
+ if (!skb)
+ break;
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
+index ad2d286bd359d..53a155dde3e32 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
+@@ -201,7 +201,6 @@ struct ice_rx_buf {
+ struct page *page;
+ unsigned int page_offset;
+ unsigned int pgcnt;
+- unsigned int act;
+ unsigned int pagecnt_bias;
+ };
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
+index 00971f8491358..41efafc5eb386 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
++++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
+@@ -5,49 +5,6 @@
+ #define _ICE_TXRX_LIB_H_
+ #include "ice.h"
+
+-/**
+- * ice_set_rx_bufs_act - propagate Rx buffer action to frags
+- * @xdp: XDP buffer representing frame (linear and frags part)
+- * @rx_ring: Rx ring struct
+- * act: action to store onto Rx buffers related to XDP buffer parts
+- *
+- * Set action that should be taken before putting Rx buffer from first frag
+- * to the last.
+- */
+-static inline void
+-ice_set_rx_bufs_act(struct xdp_buff *xdp, const struct ice_rx_ring *rx_ring,
+- const unsigned int act)
+-{
+- u32 sinfo_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags;
+- u32 nr_frags = rx_ring->nr_frags + 1;
+- u32 idx = rx_ring->first_desc;
+- u32 cnt = rx_ring->count;
+- struct ice_rx_buf *buf;
+-
+- for (int i = 0; i < nr_frags; i++) {
+- buf = &rx_ring->rx_buf[idx];
+- buf->act = act;
+-
+- if (++idx == cnt)
+- idx = 0;
+- }
+-
+- /* adjust pagecnt_bias on frags freed by XDP prog */
+- if (sinfo_frags < rx_ring->nr_frags && act == ICE_XDP_CONSUMED) {
+- u32 delta = rx_ring->nr_frags - sinfo_frags;
+-
+- while (delta) {
+- if (idx == 0)
+- idx = cnt - 1;
+- else
+- idx--;
+- buf = &rx_ring->rx_buf[idx];
+- buf->pagecnt_bias--;
+- delta--;
+- }
+- }
+-}
+-
+ /**
+ * ice_test_staterr - tests bits in Rx descriptor status and error fields
+ * @status_err_n: Rx descriptor status_error0 or status_error1 bits
+--
+2.50.1
+
--- /dev/null
+From 873765c16ba313611e466623793a24b8e13469af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 03:29:24 +0900
+Subject: net: dlink: fix multicast stats being counted incorrectly
+
+From: Yeounsu Moon <yyyynoom@gmail.com>
+
+[ Upstream commit 007a5ffadc4fd51739527f1503b7cf048f31c413 ]
+
+`McstFramesRcvdOk` counts the number of received multicast packets, and
+it reports the value correctly.
+
+However, reading `McstFramesRcvdOk` clears the register to zero. As a
+result, the driver was reporting only the packets since the last read,
+instead of the accumulated total.
+
+Fix this by updating the multicast statistics accumulatively instaed of
+instantaneously.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-on: D-Link DGE-550T Rev-A3
+Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250823182927.6063-3-yyyynoom@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/dlink/dl2k.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
+index fad5a72d3b167..f1208591ed67e 100644
+--- a/drivers/net/ethernet/dlink/dl2k.c
++++ b/drivers/net/ethernet/dlink/dl2k.c
+@@ -1092,7 +1092,7 @@ get_stats (struct net_device *dev)
+ dev->stats.rx_bytes += dr32(OctetRcvOk);
+ dev->stats.tx_bytes += dr32(OctetXmtOk);
+
+- dev->stats.multicast = dr32(McstFramesRcvdOk);
++ dev->stats.multicast += dr32(McstFramesRcvdOk);
+ dev->stats.collisions += dr32(SingleColFrames)
+ + dr32(MultiColFrames);
+
+--
+2.50.1
+
--- /dev/null
+From 1ed62904f05e264e2cf8232c0ee98ef03c920dee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Aug 2025 08:23:21 +0200
+Subject: net: ipv4: fix regression in local-broadcast routes
+
+From: Oscar Maes <oscmaes92@gmail.com>
+
+[ Upstream commit 5189446ba995556eaa3755a6e875bc06675b88bd ]
+
+Commit 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+introduced a regression where local-broadcast packets would have their
+gateway set in __mkroute_output, which was caused by fi = NULL being
+removed.
+
+Fix this by resetting the fib_info for local-broadcast packets. This
+preserves the intended changes for directed-broadcast packets.
+
+Cc: stable@vger.kernel.org
+Fixes: 9e30ecf23b1b ("net: ipv4: fix incorrect MTU in broadcast routes")
+Reported-by: Brett A C Sheffield <bacs@librecast.net>
+Closes: https://lore.kernel.org/regressions/20250822165231.4353-4-bacs@librecast.net
+Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250827062322.4807-1-oscmaes92@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/route.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 8672ebbace980..20f5c8307443d 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -2547,12 +2547,16 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+ !netif_is_l3_master(dev_out))
+ return ERR_PTR(-EINVAL);
+
+- if (ipv4_is_lbcast(fl4->daddr))
++ if (ipv4_is_lbcast(fl4->daddr)) {
+ type = RTN_BROADCAST;
+- else if (ipv4_is_multicast(fl4->daddr))
++
++ /* reset fi to prevent gateway resolution */
++ fi = NULL;
++ } else if (ipv4_is_multicast(fl4->daddr)) {
+ type = RTN_MULTICAST;
+- else if (ipv4_is_zeronet(fl4->daddr))
++ } else if (ipv4_is_zeronet(fl4->daddr)) {
+ return ERR_PTR(-EINVAL);
++ }
+
+ if (dev_out->flags & IFF_LOOPBACK)
+ flags |= RTCF_LOCAL;
+--
+2.50.1
+
--- /dev/null
+From 15f719a86bda9471820e5d022e59ac3d60d69ae5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 13:17:51 -0700
+Subject: net/mlx5: Add device cap for supporting hot reset in sync reset flow
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 9947204cdad97d22d171039019a4aad4d6899cdd ]
+
+New devices with new FW can support sync reset for firmware activate
+using hot reset. Add capability for supporting it and add MFRL field to
+query from FW which type of PCI reset method to use while handling sync
+reset events.
+
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20240911201757.1505453-10-saeed@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 902a8bc23a24 ("net/mlx5: Fix lockdep assertion on sync reset unload event")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mlx5/mlx5_ifc.h | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
+index 9106771bb92f0..4913d364e9774 100644
+--- a/include/linux/mlx5/mlx5_ifc.h
++++ b/include/linux/mlx5/mlx5_ifc.h
+@@ -1731,7 +1731,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
+ u8 reserved_at_328[0x2];
+ u8 relaxed_ordering_read[0x1];
+ u8 log_max_pd[0x5];
+- u8 reserved_at_330[0x6];
++ u8 reserved_at_330[0x5];
++ u8 pcie_reset_using_hotreset_method[0x1];
+ u8 pci_sync_for_fw_update_with_driver_unload[0x1];
+ u8 vnic_env_cnt_steering_fail[0x1];
+ u8 vport_counter_local_loopback[0x1];
+@@ -10824,6 +10825,11 @@ struct mlx5_ifc_mcda_reg_bits {
+ u8 data[][0x20];
+ };
+
++enum {
++ MLX5_MFRL_REG_PCI_RESET_METHOD_LINK_TOGGLE = 0,
++ MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET = 1,
++};
++
+ enum {
+ MLX5_MFRL_REG_RESET_STATE_IDLE = 0,
+ MLX5_MFRL_REG_RESET_STATE_IN_NEGOTIATION = 1,
+@@ -10851,7 +10857,8 @@ struct mlx5_ifc_mfrl_reg_bits {
+ u8 pci_sync_for_fw_update_start[0x1];
+ u8 pci_sync_for_fw_update_resp[0x2];
+ u8 rst_type_sel[0x3];
+- u8 reserved_at_28[0x4];
++ u8 pci_reset_req_method[0x3];
++ u8 reserved_at_2b[0x1];
+ u8 reset_state[0x4];
+ u8 reset_type[0x8];
+ u8 reset_level[0x8];
+--
+2.50.1
+
--- /dev/null
+From 67f945582744ec16678dfbbc9b5b2c3e6cfdf89e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Sep 2024 13:17:52 -0700
+Subject: net/mlx5: Add support for sync reset using hot reset
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 57502f62678ced0149d415324931bde37b42885a ]
+
+On device that supports sync reset for firmware activate using hot
+reset, the driver queries the required reset method while handling the
+sync reset request. If the required reset method is hot reset, the
+driver will use pci_reset_bus() to reset the PCI link instead of the
+link toggle.
+
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20240911201757.1505453-11-saeed@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 902a8bc23a24 ("net/mlx5: Fix lockdep assertion on sync reset unload event")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/fw_reset.c | 82 +++++++++++++++----
+ .../net/ethernet/mellanox/mlx5/core/main.c | 3 +
+ 2 files changed, 69 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 6b17346aa4cef..a1c2dd7f5c2c0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -26,6 +26,7 @@ struct mlx5_fw_reset {
+ struct work_struct reset_now_work;
+ struct work_struct reset_abort_work;
+ unsigned long reset_flags;
++ u8 reset_method;
+ struct timer_list timer;
+ struct completion done;
+ int ret;
+@@ -94,7 +95,7 @@ static int mlx5_reg_mfrl_set(struct mlx5_core_dev *dev, u8 reset_level,
+ }
+
+ static int mlx5_reg_mfrl_query(struct mlx5_core_dev *dev, u8 *reset_level,
+- u8 *reset_type, u8 *reset_state)
++ u8 *reset_type, u8 *reset_state, u8 *reset_method)
+ {
+ u32 out[MLX5_ST_SZ_DW(mfrl_reg)] = {};
+ u32 in[MLX5_ST_SZ_DW(mfrl_reg)] = {};
+@@ -110,13 +111,26 @@ static int mlx5_reg_mfrl_query(struct mlx5_core_dev *dev, u8 *reset_level,
+ *reset_type = MLX5_GET(mfrl_reg, out, reset_type);
+ if (reset_state)
+ *reset_state = MLX5_GET(mfrl_reg, out, reset_state);
++ if (reset_method)
++ *reset_method = MLX5_GET(mfrl_reg, out, pci_reset_req_method);
+
+ return 0;
+ }
+
+ int mlx5_fw_reset_query(struct mlx5_core_dev *dev, u8 *reset_level, u8 *reset_type)
+ {
+- return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL);
++ return mlx5_reg_mfrl_query(dev, reset_level, reset_type, NULL, NULL);
++}
++
++static int mlx5_fw_reset_get_reset_method(struct mlx5_core_dev *dev,
++ u8 *reset_method)
++{
++ if (!MLX5_CAP_GEN(dev, pcie_reset_using_hotreset_method)) {
++ *reset_method = MLX5_MFRL_REG_PCI_RESET_METHOD_LINK_TOGGLE;
++ return 0;
++ }
++
++ return mlx5_reg_mfrl_query(dev, NULL, NULL, NULL, reset_method);
+ }
+
+ static int mlx5_fw_reset_get_reset_state_err(struct mlx5_core_dev *dev,
+@@ -124,7 +138,7 @@ static int mlx5_fw_reset_get_reset_state_err(struct mlx5_core_dev *dev,
+ {
+ u8 reset_state;
+
+- if (mlx5_reg_mfrl_query(dev, NULL, NULL, &reset_state))
++ if (mlx5_reg_mfrl_query(dev, NULL, NULL, &reset_state, NULL))
+ goto out;
+
+ if (!reset_state)
+@@ -402,7 +416,11 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
+ struct mlx5_core_dev *dev = fw_reset->dev;
+ int err;
+
+- if (test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
++ err = mlx5_fw_reset_get_reset_method(dev, &fw_reset->reset_method);
++ if (err)
++ mlx5_core_warn(dev, "Failed reading MFRL, err %d\n", err);
++
++ if (err || test_bit(MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST, &fw_reset->reset_flags) ||
+ !mlx5_is_reset_now_capable(dev)) {
+ err = mlx5_fw_reset_set_reset_sync_nack(dev);
+ mlx5_core_warn(dev, "PCI Sync FW Update Reset Nack %s",
+@@ -419,21 +437,15 @@ static void mlx5_sync_reset_request_event(struct work_struct *work)
+ mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack. Device reset is expected.\n");
+ }
+
+-static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
++static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev, u16 dev_id)
+ {
+ struct pci_bus *bridge_bus = dev->pdev->bus;
+ struct pci_dev *bridge = bridge_bus->self;
+ unsigned long timeout;
+ struct pci_dev *sdev;
+- u16 reg16, dev_id;
+ int cap, err;
++ u16 reg16;
+
+- err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id);
+- if (err)
+- return pcibios_err_to_errno(err);
+- err = mlx5_check_dev_ids(dev, dev_id);
+- if (err)
+- return err;
+ cap = pci_find_capability(bridge, PCI_CAP_ID_EXP);
+ if (!cap)
+ return -EOPNOTSUPP;
+@@ -503,6 +515,44 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
+ return err;
+ }
+
++static int mlx5_pci_reset_bus(struct mlx5_core_dev *dev)
++{
++ if (!MLX5_CAP_GEN(dev, pcie_reset_using_hotreset_method))
++ return -EOPNOTSUPP;
++
++ return pci_reset_bus(dev->pdev);
++}
++
++static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method)
++{
++ u16 dev_id;
++ int err;
++
++ err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id);
++ if (err)
++ return pcibios_err_to_errno(err);
++ err = mlx5_check_dev_ids(dev, dev_id);
++ if (err)
++ return err;
++
++ switch (reset_method) {
++ case MLX5_MFRL_REG_PCI_RESET_METHOD_LINK_TOGGLE:
++ err = mlx5_pci_link_toggle(dev, dev_id);
++ if (err)
++ mlx5_core_warn(dev, "mlx5_pci_link_toggle failed\n");
++ break;
++ case MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET:
++ err = mlx5_pci_reset_bus(dev);
++ if (err)
++ mlx5_core_warn(dev, "mlx5_pci_reset_bus failed\n");
++ break;
++ default:
++ return -EOPNOTSUPP;
++ }
++
++ return err;
++}
++
+ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ {
+ struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+@@ -521,9 +571,9 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ goto done;
+ }
+
+- err = mlx5_pci_link_toggle(dev);
++ err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+ if (err) {
+- mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, no reset done, err %d\n", err);
++ mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, no reset done, err %d\n", err);
+ set_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags);
+ }
+
+@@ -585,9 +635,9 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+
+ mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state);
+ if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
+- err = mlx5_pci_link_toggle(dev);
++ err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+ if (err) {
+- mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, err %d\n", err);
++ mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", err);
+ fw_reset->ret = err;
+ }
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 62a85f09b52fd..8a11e410f7c13 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -627,6 +627,9 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
+ if (MLX5_CAP_GEN_MAX(dev, pci_sync_for_fw_update_with_driver_unload))
+ MLX5_SET(cmd_hca_cap, set_hca_cap,
+ pci_sync_for_fw_update_with_driver_unload, 1);
++ if (MLX5_CAP_GEN_MAX(dev, pcie_reset_using_hotreset_method))
++ MLX5_SET(cmd_hca_cap, set_hca_cap,
++ pcie_reset_using_hotreset_method, 1);
+
+ if (MLX5_CAP_GEN_MAX(dev, num_vhca_ports))
+ MLX5_SET(cmd_hca_cap,
+--
+2.50.1
+
--- /dev/null
+From a9d4f19c2bd7009548765f7889228d5b65f048c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Jun 2023 13:43:42 +0200
+Subject: net/mlx5: Call mlx5_sf_id_erase() once in mlx5_sf_dealloc()
+
+From: Jiri Pirko <jiri@nvidia.com>
+
+[ Upstream commit 2597ee190b4eb48d3b7d35b7bb2cc18046ae087e ]
+
+Before every call of mlx5_sf_dealloc(), there is a call to
+mlx5_sf_id_erase(). So move it to the beginning of mlx5_sf_dealloc().
+Also remove redundant mlx5_sf_id_erase() call from mlx5_sf_free()
+as it is called only from mlx5_sf_dealloc().
+
+Signed-off-by: Jiri Pirko <jiri@nvidia.com>
+Reviewed-by: Shay Drory <shayd@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 26e42ec7712d ("net/mlx5: Nack sync reset when SFs are present")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index e34a8f88c518c..1dd01701df20e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -111,7 +111,6 @@ mlx5_sf_alloc(struct mlx5_sf_table *table, struct mlx5_eswitch *esw,
+
+ static void mlx5_sf_free(struct mlx5_sf_table *table, struct mlx5_sf *sf)
+ {
+- mlx5_sf_id_erase(table, sf);
+ mlx5_sf_hw_table_sf_free(table->dev, sf->controller, sf->id);
+ trace_mlx5_sf_free(table->dev, sf->port_index, sf->controller, sf->hw_fn_id);
+ kfree(sf);
+@@ -361,6 +360,8 @@ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+
+ static void mlx5_sf_dealloc(struct mlx5_sf_table *table, struct mlx5_sf *sf)
+ {
++ mlx5_sf_id_erase(table, sf);
++
+ if (sf->hw_state == MLX5_VHCA_STATE_ALLOCATED) {
+ mlx5_sf_free(table, sf);
+ } else if (mlx5_sf_is_active(sf)) {
+@@ -401,7 +402,6 @@ int mlx5_devlink_sf_port_del(struct devlink *devlink,
+ }
+
+ mlx5_eswitch_unload_sf_vport(esw, sf->hw_fn_id);
+- mlx5_sf_id_erase(table, sf);
+
+ mutex_lock(&table->sf_state_lock);
+ mlx5_sf_dealloc(table, sf);
+@@ -473,7 +473,6 @@ static void mlx5_sf_deactivate_all(struct mlx5_sf_table *table)
+ */
+ xa_for_each(&table->port_indices, index, sf) {
+ mlx5_eswitch_unload_sf_vport(esw, sf->hw_fn_id);
+- mlx5_sf_id_erase(table, sf);
+ mlx5_sf_dealloc(table, sf);
+ }
+ }
+--
+2.50.1
+
--- /dev/null
+From e8e34b31f43733bc8af5b694cf341343cb4884bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 May 2023 11:33:16 +0200
+Subject: net/mlx5: Convert SF port_indices xarray to function_ids xarray
+
+From: Jiri Pirko <jiri@nvidia.com>
+
+[ Upstream commit 2284a4836251b3dee348172f69ac84157aa7b03e ]
+
+No need to lookup for sf by a port index. Convert the xarray to have
+function id as an index and optimize the remaining function id
+based lookup.
+
+Signed-off-by: Jiri Pirko <jiri@nvidia.com>
+Reviewed-by: Shay Drory <shayd@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 26e42ec7712d ("net/mlx5: Nack sync reset when SFs are present")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/sf/devlink.c | 29 +++++++------------
+ 1 file changed, 11 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index 4711dcfe8ba83..3f0ac2d1dde68 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -29,7 +29,7 @@ static void *mlx5_sf_by_dl_port(struct devlink_port *dl_port)
+
+ struct mlx5_sf_table {
+ struct mlx5_core_dev *dev; /* To refer from notifier context. */
+- struct xarray port_indices; /* port index based lookup. */
++ struct xarray function_ids; /* function id based lookup. */
+ refcount_t refcount;
+ struct completion disable_complete;
+ struct mutex sf_state_lock; /* Serializes sf state among user cmds & vhca event handler. */
+@@ -40,24 +40,17 @@ struct mlx5_sf_table {
+ static struct mlx5_sf *
+ mlx5_sf_lookup_by_function_id(struct mlx5_sf_table *table, unsigned int fn_id)
+ {
+- unsigned long index;
+- struct mlx5_sf *sf;
+-
+- xa_for_each(&table->port_indices, index, sf) {
+- if (sf->hw_fn_id == fn_id)
+- return sf;
+- }
+- return NULL;
++ return xa_load(&table->function_ids, fn_id);
+ }
+
+-static int mlx5_sf_id_insert(struct mlx5_sf_table *table, struct mlx5_sf *sf)
++static int mlx5_sf_function_id_insert(struct mlx5_sf_table *table, struct mlx5_sf *sf)
+ {
+- return xa_insert(&table->port_indices, sf->port_index, sf, GFP_KERNEL);
++ return xa_insert(&table->function_ids, sf->hw_fn_id, sf, GFP_KERNEL);
+ }
+
+-static void mlx5_sf_id_erase(struct mlx5_sf_table *table, struct mlx5_sf *sf)
++static void mlx5_sf_function_id_erase(struct mlx5_sf_table *table, struct mlx5_sf *sf)
+ {
+- xa_erase(&table->port_indices, sf->port_index);
++ xa_erase(&table->function_ids, sf->hw_fn_id);
+ }
+
+ static struct mlx5_sf *
+@@ -94,7 +87,7 @@ mlx5_sf_alloc(struct mlx5_sf_table *table, struct mlx5_eswitch *esw,
+ sf->hw_state = MLX5_VHCA_STATE_ALLOCATED;
+ sf->controller = controller;
+
+- err = mlx5_sf_id_insert(table, sf);
++ err = mlx5_sf_function_id_insert(table, sf);
+ if (err)
+ goto insert_err;
+
+@@ -347,7 +340,7 @@ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+
+ static void mlx5_sf_dealloc(struct mlx5_sf_table *table, struct mlx5_sf *sf)
+ {
+- mlx5_sf_id_erase(table, sf);
++ mlx5_sf_function_id_erase(table, sf);
+
+ if (sf->hw_state == MLX5_VHCA_STATE_ALLOCATED) {
+ mlx5_sf_free(table, sf);
+@@ -451,7 +444,7 @@ static void mlx5_sf_deactivate_all(struct mlx5_sf_table *table)
+ /* At this point, no new user commands can start and no vhca event can
+ * arrive. It is safe to destroy all user created SFs.
+ */
+- xa_for_each(&table->port_indices, index, sf) {
++ xa_for_each(&table->function_ids, index, sf) {
+ mlx5_eswitch_unload_sf_vport(esw, sf->hw_fn_id);
+ mlx5_sf_dealloc(table, sf);
+ }
+@@ -510,7 +503,7 @@ int mlx5_sf_table_init(struct mlx5_core_dev *dev)
+
+ mutex_init(&table->sf_state_lock);
+ table->dev = dev;
+- xa_init(&table->port_indices);
++ xa_init(&table->function_ids);
+ dev->priv.sf_table = table;
+ refcount_set(&table->refcount, 0);
+ table->esw_nb.notifier_call = mlx5_sf_esw_event;
+@@ -545,6 +538,6 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+ mlx5_esw_event_notifier_unregister(dev->priv.eswitch, &table->esw_nb);
+ WARN_ON(refcount_read(&table->refcount));
+ mutex_destroy(&table->sf_state_lock);
+- WARN_ON(!xa_empty(&table->port_indices));
++ WARN_ON(!xa_empty(&table->function_ids));
+ kfree(table);
+ }
+--
+2.50.1
+
--- /dev/null
+From 879ac7b238ecec0f9e67a75e763f9557f23314b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:29 +0300
+Subject: net/mlx5: Fix lockdep assertion on sync reset unload event
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 902a8bc23a24882200f57cadc270e15a2cfaf2bb ]
+
+Fix lockdep assertion triggered during sync reset unload event. When the
+sync reset flow is initiated using the devlink reload fw_activate
+option, the PF already holds the devlink lock while handling unload
+event. In this case, delegate sync reset unload event handling back to
+the devlink callback process to avoid double-locking and resolve the
+lockdep warning.
+
+Kernel log:
+WARNING: CPU: 9 PID: 1578 at devl_assert_locked+0x31/0x40
+[...]
+Call Trace:
+<TASK>
+ mlx5_unload_one_devl_locked+0x2c/0xc0 [mlx5_core]
+ mlx5_sync_reset_unload_event+0xaf/0x2f0 [mlx5_core]
+ process_one_work+0x222/0x640
+ worker_thread+0x199/0x350
+ kthread+0x10b/0x230
+ ? __pfx_worker_thread+0x10/0x10
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x8e/0x100
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+</TASK>
+
+Fixes: 7a9770f1bfea ("net/mlx5: Handle sync reset unload event")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-7-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ .../ethernet/mellanox/mlx5/core/fw_reset.c | 108 ++++++++++--------
+ .../ethernet/mellanox/mlx5/core/fw_reset.h | 1 +
+ 3 files changed, 63 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index f2d1f7cad7e72..8489b5087d9c6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+ if (err)
+ return err;
+
+- mlx5_unload_one_devl_locked(dev, false);
++ mlx5_sync_reset_unload_flow(dev, true);
+ err = mlx5_health_wait_pci_up(dev);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index a1c2dd7f5c2c0..b9986a2656083 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -12,7 +12,8 @@ enum {
+ MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
+ MLX5_FW_RESET_FLAGS_PENDING_COMP,
+ MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
+- MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
++ MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED,
++ MLX5_FW_RESET_FLAGS_UNLOAD_EVENT,
+ };
+
+ struct mlx5_fw_reset {
+@@ -217,7 +218,7 @@ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev)
+ return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL0, 0, 0, false);
+ }
+
+-static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unloaded)
++static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+ {
+ struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
+ struct devlink *devlink = priv_to_devlink(dev);
+@@ -226,8 +227,7 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unload
+ if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) {
+ complete(&fw_reset->done);
+ } else {
+- if (!unloaded)
+- mlx5_unload_one(dev, false);
++ mlx5_sync_reset_unload_flow(dev, false);
+ if (mlx5_health_wait_pci_up(dev))
+ mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
+ else
+@@ -270,7 +270,7 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work)
+
+ mlx5_sync_reset_clear_reset_requested(dev, false);
+ mlx5_enter_error_state(dev, true);
+- mlx5_fw_reset_complete_reload(dev, false);
++ mlx5_fw_reset_complete_reload(dev);
+ }
+
+ #define MLX5_RESET_POLL_INTERVAL (HZ / 10)
+@@ -553,6 +553,59 @@ static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method)
+ return err;
+ }
+
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked)
++{
++ struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
++ unsigned long timeout;
++ bool reset_action;
++ u8 rst_state;
++ int err;
++
++ if (locked)
++ mlx5_unload_one_devl_locked(dev, false);
++ else
++ mlx5_unload_one(dev, false);
++
++ if (!test_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags))
++ return;
++
++ mlx5_set_fw_rst_ack(dev);
++ mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
++
++ reset_action = false;
++ timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
++ do {
++ rst_state = mlx5_get_fw_rst_state(dev);
++ if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
++ rst_state == MLX5_FW_RST_STATE_IDLE) {
++ reset_action = true;
++ break;
++ }
++ msleep(20);
++ } while (!time_after(jiffies, timeout));
++
++ if (!reset_action) {
++ mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
++ rst_state);
++ fw_reset->ret = -ETIMEDOUT;
++ goto done;
++ }
++
++ mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n",
++ rst_state);
++ if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
++ err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
++ if (err) {
++ mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n",
++ err);
++ fw_reset->ret = err;
++ }
++ }
++
++done:
++ clear_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
++}
++
+ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ {
+ struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset,
+@@ -580,16 +633,13 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ mlx5_enter_error_state(dev, true);
+ done:
+ fw_reset->ret = err;
+- mlx5_fw_reset_complete_reload(dev, false);
++ mlx5_fw_reset_complete_reload(dev);
+ }
+
+ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ {
+ struct mlx5_fw_reset *fw_reset;
+ struct mlx5_core_dev *dev;
+- unsigned long timeout;
+- bool reset_action;
+- u8 rst_state;
+ int err;
+
+ fw_reset = container_of(work, struct mlx5_fw_reset, reset_unload_work);
+@@ -598,6 +648,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ if (mlx5_sync_reset_clear_reset_requested(dev, false))
+ return;
+
++ set_bit(MLX5_FW_RESET_FLAGS_UNLOAD_EVENT, &fw_reset->reset_flags);
+ mlx5_core_warn(dev, "Sync Reset Unload. Function is forced down.\n");
+
+ err = mlx5_cmd_fast_teardown_hca(dev);
+@@ -606,44 +657,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
+ else
+ mlx5_enter_error_state(dev, true);
+
+- if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags))
+- mlx5_unload_one_devl_locked(dev, false);
+- else
+- mlx5_unload_one(dev, false);
+-
+- mlx5_set_fw_rst_ack(dev);
+- mlx5_core_warn(dev, "Sync Reset Unload done, device reset expected\n");
+-
+- reset_action = false;
+- timeout = jiffies + msecs_to_jiffies(mlx5_tout_ms(dev, RESET_UNLOAD));
+- do {
+- rst_state = mlx5_get_fw_rst_state(dev);
+- if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
+- rst_state == MLX5_FW_RST_STATE_IDLE) {
+- reset_action = true;
+- break;
+- }
+- msleep(20);
+- } while (!time_after(jiffies, timeout));
+-
+- if (!reset_action) {
+- mlx5_core_err(dev, "Got timeout waiting for sync reset action, state = %u\n",
+- rst_state);
+- fw_reset->ret = -ETIMEDOUT;
+- goto done;
+- }
+-
+- mlx5_core_warn(dev, "Sync Reset, got reset action. rst_state = %u\n", rst_state);
+- if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ) {
+- err = mlx5_sync_pci_reset(dev, fw_reset->reset_method);
+- if (err) {
+- mlx5_core_warn(dev, "mlx5_sync_pci_reset failed, err %d\n", err);
+- fw_reset->ret = err;
+- }
+- }
+-
+-done:
+- mlx5_fw_reset_complete_reload(dev, true);
++ mlx5_fw_reset_complete_reload(dev);
+ }
+
+ static void mlx5_sync_reset_abort_event(struct work_struct *work)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+index ea527d06a85f0..d5b28525c960d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.h
+@@ -12,6 +12,7 @@ int mlx5_fw_reset_set_reset_sync(struct mlx5_core_dev *dev, u8 reset_type_sel,
+ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev);
+
+ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev);
++void mlx5_sync_reset_unload_flow(struct mlx5_core_dev *dev, bool locked);
+ int mlx5_fw_reset_verify_fw_complete(struct mlx5_core_dev *dev,
+ struct netlink_ext_ack *extack);
+ void mlx5_fw_reset_events_start(struct mlx5_core_dev *dev);
+--
+2.50.1
+
--- /dev/null
+From b21262d4f99e687d7fc8da8ccc2760a8444a2c3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:30 +0300
+Subject: net/mlx5: Nack sync reset when SFs are present
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 26e42ec7712d392d561964514b1f253b1a96f42d ]
+
+If PF (Physical Function) has SFs (Sub-Functions), since the SFs are not
+taking part in the synchronization flow, sync reset can lead to fatal
+error on the SFs, as the function will be closed unexpectedly from the
+SF point of view.
+
+Add a check to prevent sync reset when there are SFs on a PF device
+which is not ECPF, as ECPF is teardowned gracefully before reset.
+
+Fixes: 92501fa6e421 ("net/mlx5: Ack on sync_reset_request only if PF can do reset_now")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Parav Pandit <parav@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-8-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 6 ++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c | 10 ++++++++++
+ drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h | 6 ++++++
+ 3 files changed, 22 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index b9986a2656083..1547704c89767 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -6,6 +6,7 @@
+ #include "fw_reset.h"
+ #include "diag/fw_tracer.h"
+ #include "lib/tout.h"
++#include "sf/sf.h"
+
+ enum {
+ MLX5_FW_RESET_FLAGS_RESET_REQUESTED,
+@@ -397,6 +398,11 @@ static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev)
+ return false;
+ }
+
++ if (!mlx5_core_is_ecpf(dev) && !mlx5_sf_table_empty(dev)) {
++ mlx5_core_warn(dev, "SFs should be removed before reset\n");
++ return false;
++ }
++
+ #if IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)
+ err = mlx5_check_hotplug_interrupt(dev);
+ if (err)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index 3f0ac2d1dde68..c9089f2ec5f25 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -541,3 +541,13 @@ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+ WARN_ON(!xa_empty(&table->function_ids));
+ kfree(table);
+ }
++
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++ struct mlx5_sf_table *table = dev->priv.sf_table;
++
++ if (!table)
++ return true;
++
++ return xa_empty(&table->function_ids);
++}
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+index 860f9ddb7107b..89559a37997ad 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/sf.h
+@@ -17,6 +17,7 @@ void mlx5_sf_hw_table_destroy(struct mlx5_core_dev *dev);
+
+ int mlx5_sf_table_init(struct mlx5_core_dev *dev);
+ void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev);
++bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev);
+
+ int mlx5_devlink_sf_port_new(struct devlink *devlink,
+ const struct devlink_port_new_attrs *add_attr,
+@@ -61,6 +62,11 @@ static inline void mlx5_sf_table_cleanup(struct mlx5_core_dev *dev)
+ {
+ }
+
++static inline bool mlx5_sf_table_empty(const struct mlx5_core_dev *dev)
++{
++ return true;
++}
++
+ #endif
+
+ #endif
+--
+2.50.1
+
--- /dev/null
+From 422436abfb60fb8c885b171070635649ce062a8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:28 +0300
+Subject: net/mlx5: Reload auxiliary drivers on fw_activate
+
+From: Moshe Shemesh <moshe@nvidia.com>
+
+[ Upstream commit 34cc6a54914f478c93e176450fae6313404f9f74 ]
+
+The devlink reload fw_activate command performs firmware activation
+followed by driver reload, while devlink reload driver_reinit triggers
+only driver reload. However, the driver reload logic differs between the
+two modes, as on driver_reinit mode mlx5 also reloads auxiliary drivers,
+while in fw_activate mode the auxiliary drivers are suspended where
+applicable.
+
+Additionally, following the cited commit, if the device has multiple PFs,
+the behavior during fw_activate may vary between PFs: one PF may suspend
+auxiliary drivers, while another reloads them.
+
+Align devlink dev reload fw_activate behavior with devlink dev reload
+driver_reinit, to reload all auxiliary drivers.
+
+Fixes: 72ed5d5624af ("net/mlx5: Suspend auxiliary devices only in case of PCI device suspend")
+Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-6-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index f66788a2ed77e..f2d1f7cad7e72 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -107,7 +107,7 @@ static int mlx5_devlink_reload_fw_activate(struct devlink *devlink, struct netli
+ if (err)
+ return err;
+
+- mlx5_unload_one_devl_locked(dev, true);
++ mlx5_unload_one_devl_locked(dev, false);
+ err = mlx5_health_wait_pci_up(dev);
+ if (err)
+ NL_SET_ERR_MSG_MOD(extack, "FW activate aborted, PCI reads fail after reset");
+--
+2.50.1
+
--- /dev/null
+From 4003b3bacd9920125af73f19eb1dfd88d7f4ccc2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 May 2023 13:59:34 +0200
+Subject: net/mlx5: Use devlink port pointer to get the pointer of container SF
+ struct
+
+From: Jiri Pirko <jiri@nvidia.com>
+
+[ Upstream commit 9caeb1475c3e852bcfa6332227c6bb2feaa8eb23 ]
+
+Benefit from the fact that struct devlink_port is eventually embedded
+in struct mlx5_sf and use container_of() macro to get it instead of the
+xarray lookup in every devlink port op.
+
+Signed-off-by: Jiri Pirko <jiri@nvidia.com>
+Reviewed-by: Shay Drory <shayd@nvidia.com>
+Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
+Stable-dep-of: 26e42ec7712d ("net/mlx5: Nack sync reset when SFs are present")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlx5/core/sf/devlink.c | 44 +++++--------------
+ 1 file changed, 12 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+index 1dd01701df20e..4711dcfe8ba83 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+@@ -20,6 +20,13 @@ struct mlx5_sf {
+ u16 hw_state;
+ };
+
++static void *mlx5_sf_by_dl_port(struct devlink_port *dl_port)
++{
++ struct mlx5_devlink_port *mlx5_dl_port = mlx5_devlink_port_get(dl_port);
++
++ return container_of(mlx5_dl_port, struct mlx5_sf, dl_port);
++}
++
+ struct mlx5_sf_table {
+ struct mlx5_core_dev *dev; /* To refer from notifier context. */
+ struct xarray port_indices; /* port index based lookup. */
+@@ -30,12 +37,6 @@ struct mlx5_sf_table {
+ struct notifier_block vhca_nb;
+ };
+
+-static struct mlx5_sf *
+-mlx5_sf_lookup_by_index(struct mlx5_sf_table *table, unsigned int port_index)
+-{
+- return xa_load(&table->port_indices, port_index);
+-}
+-
+ static struct mlx5_sf *
+ mlx5_sf_lookup_by_function_id(struct mlx5_sf_table *table, unsigned int fn_id)
+ {
+@@ -171,26 +172,19 @@ int mlx5_devlink_sf_port_fn_state_get(struct devlink_port *dl_port,
+ struct netlink_ext_ack *extack)
+ {
+ struct mlx5_core_dev *dev = devlink_priv(dl_port->devlink);
++ struct mlx5_sf *sf = mlx5_sf_by_dl_port(dl_port);
+ struct mlx5_sf_table *table;
+- struct mlx5_sf *sf;
+- int err = 0;
+
+ table = mlx5_sf_table_try_get(dev);
+ if (!table)
+ return -EOPNOTSUPP;
+
+- sf = mlx5_sf_lookup_by_index(table, dl_port->index);
+- if (!sf) {
+- err = -EOPNOTSUPP;
+- goto sf_err;
+- }
+ mutex_lock(&table->sf_state_lock);
+ *state = mlx5_sf_to_devlink_state(sf->hw_state);
+ *opstate = mlx5_sf_to_devlink_opstate(sf->hw_state);
+ mutex_unlock(&table->sf_state_lock);
+-sf_err:
+ mlx5_sf_table_put(table);
+- return err;
++ return 0;
+ }
+
+ static int mlx5_sf_activate(struct mlx5_core_dev *dev, struct mlx5_sf *sf,
+@@ -256,8 +250,8 @@ int mlx5_devlink_sf_port_fn_state_set(struct devlink_port *dl_port,
+ struct netlink_ext_ack *extack)
+ {
+ struct mlx5_core_dev *dev = devlink_priv(dl_port->devlink);
++ struct mlx5_sf *sf = mlx5_sf_by_dl_port(dl_port);
+ struct mlx5_sf_table *table;
+- struct mlx5_sf *sf;
+ int err;
+
+ table = mlx5_sf_table_try_get(dev);
+@@ -266,14 +260,7 @@ int mlx5_devlink_sf_port_fn_state_set(struct devlink_port *dl_port,
+ "Port state set is only supported in eswitch switchdev mode or SF ports are disabled.");
+ return -EOPNOTSUPP;
+ }
+- sf = mlx5_sf_lookup_by_index(table, dl_port->index);
+- if (!sf) {
+- err = -ENODEV;
+- goto out;
+- }
+-
+ err = mlx5_sf_state_set(dev, table, sf, state, extack);
+-out:
+ mlx5_sf_table_put(table);
+ return err;
+ }
+@@ -384,10 +371,9 @@ int mlx5_devlink_sf_port_del(struct devlink *devlink,
+ struct netlink_ext_ack *extack)
+ {
+ struct mlx5_core_dev *dev = devlink_priv(devlink);
++ struct mlx5_sf *sf = mlx5_sf_by_dl_port(dl_port);
+ struct mlx5_eswitch *esw = dev->priv.eswitch;
+ struct mlx5_sf_table *table;
+- struct mlx5_sf *sf;
+- int err = 0;
+
+ table = mlx5_sf_table_try_get(dev);
+ if (!table) {
+@@ -395,20 +381,14 @@ int mlx5_devlink_sf_port_del(struct devlink *devlink,
+ "Port del is only supported in eswitch switchdev mode or SF ports are disabled.");
+ return -EOPNOTSUPP;
+ }
+- sf = mlx5_sf_lookup_by_index(table, dl_port->index);
+- if (!sf) {
+- err = -ENODEV;
+- goto sf_err;
+- }
+
+ mlx5_eswitch_unload_sf_vport(esw, sf->hw_fn_id);
+
+ mutex_lock(&table->sf_state_lock);
+ mlx5_sf_dealloc(table, sf);
+ mutex_unlock(&table->sf_state_lock);
+-sf_err:
+ mlx5_sf_table_put(table);
+- return err;
++ return 0;
+ }
+
+ static bool mlx5_sf_state_update_check(const struct mlx5_sf *sf, u8 new_state)
+--
+2.50.1
+
--- /dev/null
+From d8f10dce13db9cb33c70242c5defdb7a34e0ed09 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:34 +0300
+Subject: net/mlx5e: Set local Xoff after FW update
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit aca0c31af61e0d5cf1675a0cbd29460b95ae693c ]
+
+The local Xoff value is being set before the firmware (FW) update.
+In case of a failure where the FW is not updated with the new value,
+there is no fallback to the previous value.
+Update the local Xoff value after the FW has been successfully set.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-12-mbloch@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/port_buffer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+index 3efa8bf1d14ef..4720523813b97 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+@@ -575,7 +575,6 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ if (err)
+ return err;
+ }
+- priv->dcbx.xoff = xoff;
+
+ /* Apply the settings */
+ if (update_buffer) {
+@@ -584,6 +583,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ return err;
+ }
+
++ priv->dcbx.xoff = xoff;
++
+ if (update_prio2buffer)
+ err = mlx5e_port_set_priority2buffer(priv->mdev, prio2buffer);
+
+--
+2.50.1
+
--- /dev/null
+From 77fc8620dc459df9fabc242ff50f80487757a7a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:32 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon MTU set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit ceddedc969f0532b7c62ca971ee50d519d2bc0cb ]
+
+Xon/Xoff sizes are derived from calculation that include the MTU size.
+Set Xon/Xoff when MTU is set.
+If Xon/Xoff fails, set the previous MTU.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-10-mbloch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlx5/core/en/port_buffer.h | 12 ++++++++++++
+ .../net/ethernet/mellanox/mlx5/core/en_main.c | 17 ++++++++++++++++-
+ 2 files changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+index f4a19ffbb641c..66d276a1be836 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h
+@@ -66,11 +66,23 @@ struct mlx5e_port_buffer {
+ struct mlx5e_bufferx_reg buffer[MLX5E_MAX_NETWORK_BUFFER];
+ };
+
++#ifdef CONFIG_MLX5_CORE_EN_DCB
+ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
+ u32 change, unsigned int mtu,
+ struct ieee_pfc *pfc,
+ u32 *buffer_size,
+ u8 *prio2buffer);
++#else
++static inline int
++mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
++ u32 change, unsigned int mtu,
++ void *pfc,
++ u32 *buffer_size,
++ u8 *prio2buffer)
++{
++ return 0;
++}
++#endif
+
+ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
+ struct mlx5e_port_buffer *port_buffer);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 5c6f01abdcb91..09ba60b2e744b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -44,6 +44,7 @@
+ #include "eswitch.h"
+ #include "en.h"
+ #include "en/txrx.h"
++#include "en/port_buffer.h"
+ #include "en_tc.h"
+ #include "en_rep.h"
+ #include "en_accel/ipsec.h"
+@@ -2722,9 +2723,11 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ struct mlx5e_params *params = &priv->channels.params;
+ struct net_device *netdev = priv->netdev;
+ struct mlx5_core_dev *mdev = priv->mdev;
+- u16 mtu;
++ u16 mtu, prev_mtu;
+ int err;
+
++ mlx5e_query_mtu(mdev, params, &prev_mtu);
++
+ err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
+ if (err)
+ return err;
+@@ -2734,6 +2737,18 @@ int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
+ netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
+ __func__, mtu, params->sw_mtu);
+
++ if (mtu != prev_mtu && MLX5_BUFFER_SUPPORTED(mdev)) {
++ err = mlx5e_port_manual_buffer_config(priv, 0, mtu,
++ NULL, NULL, NULL);
++ if (err) {
++ netdev_warn(netdev, "%s: Failed to set Xon/Xoff values with MTU %d (err %d), setting back to previous MTU %d\n",
++ __func__, mtu, err, prev_mtu);
++
++ mlx5e_set_mtu(mdev, params, prev_mtu);
++ return err;
++ }
++ }
++
+ params->sw_mtu = mtu;
+ return 0;
+ }
+--
+2.50.1
+
--- /dev/null
+From 9cf9b2f104bdf25466fc38648440c45456850785 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 17:34:33 +0300
+Subject: net/mlx5e: Update and set Xon/Xoff upon port speed set
+
+From: Alexei Lazar <alazar@nvidia.com>
+
+[ Upstream commit d24341740fe48add8a227a753e68b6eedf4b385a ]
+
+Xon/Xoff sizes are derived from calculations that include
+the port speed.
+These settings need to be updated and applied whenever the
+port speed is changed.
+The port speed is typically set after the physical link goes down
+and is negotiated as part of the link-up process between the two
+connected interfaces.
+Xon/Xoff parameters being updated at the point where the new
+negotiated speed is established.
+
+Fixes: 0696d60853d5 ("net/mlx5e: Receive buffer configuration")
+Signed-off-by: Alexei Lazar <alazar@nvidia.com>
+Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
+Signed-off-by: Mark Bloch <mbloch@nvidia.com>
+Link: https://patch.msgid.link/20250825143435.598584-11-mbloch@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_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 09ba60b2e744b..d378aa55f22f9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -109,6 +109,8 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
+ if (up) {
+ netdev_info(priv->netdev, "Link up\n");
+ netif_carrier_on(priv->netdev);
++ mlx5e_port_manual_buffer_config(priv, 0, priv->netdev->mtu,
++ NULL, NULL, NULL);
+ } else {
+ netdev_info(priv->netdev, "Link down\n");
+ netif_carrier_off(priv->netdev);
+--
+2.50.1
+
--- /dev/null
+From ea4d53c4008cae4f229baffd5cb00438bce6437d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:56 +0900
+Subject: net: rose: convert 'use' field to refcount_t
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit d860d1faa6b2ce3becfdb8b0c2b048ad31800061 ]
+
+The 'use' field in struct rose_neigh is used as a reference counter but
+lacks atomicity. This can lead to race conditions where a rose_neigh
+structure is freed while still being referenced by other code paths.
+
+For example, when rose_neigh->use becomes zero during an ioctl operation
+via rose_rt_ioctl(), the structure may be removed while its timer is
+still active, potentially causing use-after-free issues.
+
+This patch changes the type of 'use' from unsigned short to refcount_t and
+updates all code paths to use rose_neigh_hold() and rose_neigh_put() which
+operate reference counts atomically.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-3-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h | 18 +++++++++++++-----
+ net/rose/af_rose.c | 13 +++++++------
+ net/rose/rose_in.c | 12 ++++++------
+ net/rose/rose_route.c | 33 ++++++++++++++++++---------------
+ net/rose/rose_timer.c | 2 +-
+ 5 files changed, 45 insertions(+), 33 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 174b4f605d849..2b5491bbf39ab 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -8,6 +8,7 @@
+ #ifndef _ROSE_H
+ #define _ROSE_H
+
++#include <linux/refcount.h>
+ #include <linux/rose.h>
+ #include <net/ax25.h>
+ #include <net/sock.h>
+@@ -96,7 +97,7 @@ struct rose_neigh {
+ ax25_cb *ax25;
+ struct net_device *dev;
+ unsigned short count;
+- unsigned short use;
++ refcount_t use;
+ unsigned int number;
+ char restarted;
+ char dce_mode;
+@@ -151,12 +152,19 @@ struct rose_sock {
+
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
+
++static inline void rose_neigh_hold(struct rose_neigh *rose_neigh)
++{
++ refcount_inc(&rose_neigh->use);
++}
++
+ static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
+ {
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
++ if (refcount_dec_and_test(&rose_neigh->use)) {
++ if (rose_neigh->ax25)
++ ax25_cb_put(rose_neigh->ax25);
++ kfree(rose_neigh->digipeat);
++ kfree(rose_neigh);
++ }
+ }
+
+ /* af_rose.c */
+diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
+index 66e9ceaaa43a1..614695444b6ac 100644
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -170,7 +170,7 @@ void rose_kill_by_neigh(struct rose_neigh *neigh)
+
+ if (rose->neighbour == neigh) {
+ rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose->neighbour = NULL;
+ }
+ }
+@@ -212,7 +212,7 @@ static void rose_kill_by_device(struct net_device *dev)
+ if (rose->device == dev) {
+ rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+ if (rose->neighbour)
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ netdev_put(rose->device, &rose->dev_tracker);
+ rose->device = NULL;
+ }
+@@ -655,7 +655,7 @@ static int rose_release(struct socket *sock)
+ break;
+
+ case ROSE_STATE_2:
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ release_sock(sk);
+ rose_disconnect(sk, 0, -1, -1);
+ lock_sock(sk);
+@@ -823,6 +823,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ rose->lci = rose_new_lci(rose->neighbour);
+ if (!rose->lci) {
+ err = -ENETUNREACH;
++ rose_neigh_put(rose->neighbour);
+ goto out_release;
+ }
+
+@@ -834,12 +835,14 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+ dev = rose_dev_first();
+ if (!dev) {
+ err = -ENETUNREACH;
++ rose_neigh_put(rose->neighbour);
+ goto out_release;
+ }
+
+ user = ax25_findbyuid(current_euid());
+ if (!user) {
+ err = -EINVAL;
++ rose_neigh_put(rose->neighbour);
+ dev_put(dev);
+ goto out_release;
+ }
+@@ -874,8 +877,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
+
+ rose->state = ROSE_STATE_1;
+
+- rose->neighbour->use++;
+-
+ rose_write_internal(sk, ROSE_CALL_REQUEST);
+ rose_start_heartbeat(sk);
+ rose_start_t1timer(sk);
+@@ -1077,7 +1078,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
+ GFP_ATOMIC);
+ make_rose->facilities = facilities;
+
+- make_rose->neighbour->use++;
++ rose_neigh_hold(make_rose->neighbour);
+
+ if (rose_sk(sk)->defer) {
+ make_rose->state = ROSE_STATE_5;
+diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
+index 4d67f36dce1b4..7caae93937ee9 100644
+--- a/net/rose/rose_in.c
++++ b/net/rose/rose_in.c
+@@ -56,7 +56,7 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -79,12 +79,12 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ case ROSE_CLEAR_CONFIRMATION:
+ rose_disconnect(sk, 0, -1, -1);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -120,7 +120,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ case ROSE_RR:
+@@ -233,7 +233,7 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety
+ case ROSE_CLEAR_REQUEST:
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ break;
+
+ default:
+@@ -253,7 +253,7 @@ static int rose_state5_machine(struct sock *sk, struct sk_buff *skb, int framety
+ if (frametype == ROSE_CLEAR_REQUEST) {
+ rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
+ rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+- rose_sk(sk)->neighbour->use--;
++ rose_neigh_put(rose_sk(sk)->neighbour);
+ }
+
+ return 0;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index b406b1e0fb1e7..42460da0854d5 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -93,11 +93,11 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ rose_neigh->ax25 = NULL;
+ rose_neigh->dev = dev;
+ rose_neigh->count = 0;
+- rose_neigh->use = 0;
+ rose_neigh->dce_mode = 0;
+ rose_neigh->loopback = 0;
+ rose_neigh->number = rose_neigh_no++;
+ rose_neigh->restarted = 0;
++ refcount_set(&rose_neigh->use, 1);
+
+ skb_queue_head_init(&rose_neigh->queue);
+
+@@ -255,10 +255,10 @@ static void rose_remove_route(struct rose_route *rose_route)
+ struct rose_route *s;
+
+ if (rose_route->neigh1 != NULL)
+- rose_route->neigh1->use--;
++ rose_neigh_put(rose_route->neigh1);
+
+ if (rose_route->neigh2 != NULL)
+- rose_route->neigh2->use--;
++ rose_neigh_put(rose_route->neigh2);
+
+ if ((s = rose_route_list) == rose_route) {
+ rose_route_list = rose_route->next;
+@@ -323,7 +323,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
+
+- if (rose_neigh->count == 0 && rose_neigh->use == 0) {
++ if (rose_neigh->count == 0) {
+ rose_remove_neigh(rose_neigh);
+ rose_neigh_put(rose_neigh);
+ }
+@@ -375,11 +375,11 @@ void rose_add_loopback_neigh(void)
+ sn->ax25 = NULL;
+ sn->dev = NULL;
+ sn->count = 0;
+- sn->use = 0;
+ sn->dce_mode = 1;
+ sn->loopback = 1;
+ sn->number = rose_neigh_no++;
+ sn->restarted = 1;
++ refcount_set(&sn->use, 1);
+
+ skb_queue_head_init(&sn->queue);
+
+@@ -561,8 +561,7 @@ static int rose_clear_routes(void)
+ s = rose_neigh;
+ rose_neigh = rose_neigh->next;
+
+- if (s->use == 0 && !s->loopback) {
+- s->count = 0;
++ if (!s->loopback) {
+ rose_remove_neigh(s);
+ rose_neigh_put(s);
+ }
+@@ -680,6 +679,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+ for (i = 0; i < node->count; i++) {
+ if (node->neighbour[i]->restarted) {
+ res = node->neighbour[i];
++ rose_neigh_hold(node->neighbour[i]);
+ goto out;
+ }
+ }
+@@ -691,6 +691,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause,
+ for (i = 0; i < node->count; i++) {
+ if (!rose_ftimer_running(node->neighbour[i])) {
+ res = node->neighbour[i];
++ rose_neigh_hold(node->neighbour[i]);
+ goto out;
+ }
+ failed = 1;
+@@ -780,13 +781,13 @@ static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
+ }
+
+ if (rose_route->neigh1 == rose_neigh) {
+- rose_route->neigh1->use--;
++ rose_neigh_put(rose_route->neigh1);
+ rose_route->neigh1 = NULL;
+ rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
+ }
+
+ if (rose_route->neigh2 == rose_neigh) {
+- rose_route->neigh2->use--;
++ rose_neigh_put(rose_route->neigh2);
+ rose_route->neigh2 = NULL;
+ rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
+ }
+@@ -915,7 +916,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_clear_queues(sk);
+ rose->cause = ROSE_NETWORK_CONGESTION;
+ rose->diagnostic = 0;
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose->neighbour = NULL;
+ rose->lci = 0;
+ rose->state = ROSE_STATE_0;
+@@ -1040,12 +1041,12 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+
+ if ((new_lci = rose_new_lci(new_neigh)) == 0) {
+ rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 71);
+- goto out;
++ goto put_neigh;
+ }
+
+ if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) {
+ rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120);
+- goto out;
++ goto put_neigh;
+ }
+
+ rose_route->lci1 = lci;
+@@ -1058,8 +1059,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_route->lci2 = new_lci;
+ rose_route->neigh2 = new_neigh;
+
+- rose_route->neigh1->use++;
+- rose_route->neigh2->use++;
++ rose_neigh_hold(rose_route->neigh1);
++ rose_neigh_hold(rose_route->neigh2);
+
+ rose_route->next = rose_route_list;
+ rose_route_list = rose_route;
+@@ -1071,6 +1072,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+ rose_transmit_link(skb, rose_route->neigh2);
+ res = 1;
+
++put_neigh:
++ rose_neigh_put(new_neigh);
+ out:
+ spin_unlock_bh(&rose_route_list_lock);
+ spin_unlock_bh(&rose_neigh_list_lock);
+@@ -1186,7 +1189,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+ (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+ rose_neigh->dev ? rose_neigh->dev->name : "???",
+ rose_neigh->count,
+- rose_neigh->use,
++ refcount_read(&rose_neigh->use) - 1,
+ (rose_neigh->dce_mode) ? "DCE" : "DTE",
+ (rose_neigh->restarted) ? "yes" : "no",
+ ax25_display_timer(&rose_neigh->t0timer) / HZ,
+diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
+index 1525773e94aa1..c52d7d20c5199 100644
+--- a/net/rose/rose_timer.c
++++ b/net/rose/rose_timer.c
+@@ -180,7 +180,7 @@ static void rose_timer_expiry(struct timer_list *t)
+ break;
+
+ case ROSE_STATE_2: /* T3 */
+- rose->neighbour->use--;
++ rose_neigh_put(rose->neighbour);
+ rose_disconnect(sk, ETIMEDOUT, -1, -1);
+ break;
+
+--
+2.50.1
+
--- /dev/null
+From ef0b2fc4f9ca9e4f777ccb13eaae3ba3ce851928 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:57 +0900
+Subject: net: rose: include node references in rose_neigh refcount
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit da9c9c877597170b929a6121a68dcd3dd9a80f45 ]
+
+Current implementation maintains two separate reference counting
+mechanisms: the 'count' field in struct rose_neigh tracks references from
+rose_node structures, while the 'use' field (now refcount_t) tracks
+references from rose_sock.
+
+This patch merges these two reference counting systems using 'use' field
+for proper reference management. Specifically, this patch adds incrementing
+and decrementing of rose_neigh->use when rose_neigh->count is incremented
+or decremented.
+
+This patch also modifies rose_rt_free(), rose_rt_device_down() and
+rose_clear_route() to properly release references to rose_neigh objects
+before freeing a rose_node through rose_remove_node().
+
+These changes ensure rose_neigh structures are properly freed only when
+all references, including those from rose_node structures, are released.
+As a result, this resolves a slab-use-after-free issue reported by Syzbot.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+942297eecf7d2d61d1f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=942297eecf7d2d61d1f1
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-4-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rose/rose_route.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index 42460da0854d5..6acbb795c506d 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -178,6 +178,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ }
+ }
+ rose_neigh->count++;
++ rose_neigh_hold(rose_neigh);
+
+ goto out;
+ }
+@@ -187,6 +188,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
+ rose_node->neighbour[rose_node->count] = rose_neigh;
+ rose_node->count++;
+ rose_neigh->count++;
++ rose_neigh_hold(rose_neigh);
+ }
+
+ out:
+@@ -322,6 +324,7 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ for (i = 0; i < rose_node->count; i++) {
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
++ rose_neigh_put(rose_neigh);
+
+ if (rose_neigh->count == 0) {
+ rose_remove_neigh(rose_neigh);
+@@ -430,6 +433,7 @@ int rose_add_loopback_node(const rose_address *address)
+ rose_node_list = rose_node;
+
+ rose_loopback_neigh->count++;
++ rose_neigh_hold(rose_loopback_neigh);
+
+ out:
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -461,6 +465,7 @@ void rose_del_loopback_node(const rose_address *address)
+ rose_remove_node(rose_node);
+
+ rose_loopback_neigh->count--;
++ rose_neigh_put(rose_loopback_neigh);
+
+ out:
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -500,6 +505,7 @@ void rose_rt_device_down(struct net_device *dev)
+ memmove(&t->neighbour[i], &t->neighbour[i + 1],
+ sizeof(t->neighbour[0]) *
+ (t->count - i));
++ rose_neigh_put(s);
+ }
+
+ if (t->count <= 0)
+@@ -543,6 +549,7 @@ static int rose_clear_routes(void)
+ {
+ struct rose_neigh *s, *rose_neigh;
+ struct rose_node *t, *rose_node;
++ int i;
+
+ spin_lock_bh(&rose_node_list_lock);
+ spin_lock_bh(&rose_neigh_list_lock);
+@@ -553,8 +560,12 @@ static int rose_clear_routes(void)
+ while (rose_node != NULL) {
+ t = rose_node;
+ rose_node = rose_node->next;
+- if (!t->loopback)
++
++ if (!t->loopback) {
++ for (i = 0; i < rose_node->count; i++)
++ rose_neigh_put(t->neighbour[i]);
+ rose_remove_node(t);
++ }
+ }
+
+ while (rose_neigh != NULL) {
+@@ -1189,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
+ (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
+ rose_neigh->dev ? rose_neigh->dev->name : "???",
+ rose_neigh->count,
+- refcount_read(&rose_neigh->use) - 1,
++ refcount_read(&rose_neigh->use) - rose_neigh->count - 1,
+ (rose_neigh->dce_mode) ? "DCE" : "DTE",
+ (rose_neigh->restarted) ? "yes" : "no",
+ ax25_display_timer(&rose_neigh->t0timer) / HZ,
+@@ -1294,6 +1305,7 @@ void __exit rose_rt_free(void)
+ struct rose_neigh *s, *rose_neigh = rose_neigh_list;
+ struct rose_node *t, *rose_node = rose_node_list;
+ struct rose_route *u, *rose_route = rose_route_list;
++ int i;
+
+ while (rose_neigh != NULL) {
+ s = rose_neigh;
+@@ -1307,6 +1319,8 @@ void __exit rose_rt_free(void)
+ t = rose_node;
+ rose_node = rose_node->next;
+
++ for (i = 0; i < t->count; i++)
++ rose_neigh_put(t->neighbour[i]);
+ rose_remove_node(t);
+ }
+
+--
+2.50.1
+
--- /dev/null
+From 7dcf66da101ce72d7691bf6ecc16b81acb41eca5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 23 Aug 2025 17:58:55 +0900
+Subject: net: rose: split remove and free operations in rose_remove_neigh()
+
+From: Takamitsu Iwai <takamitz@amazon.co.jp>
+
+[ Upstream commit dcb34659028f856c423a29ef9b4e2571d203444d ]
+
+The current rose_remove_neigh() performs two distinct operations:
+1. Removes rose_neigh from rose_neigh_list
+2. Frees the rose_neigh structure
+
+Split these operations into separate functions to improve maintainability
+and prepare for upcoming refcount_t conversion. The timer cleanup remains
+in rose_remove_neigh() because free operations can be called from timer
+itself.
+
+This patch introduce rose_neigh_put() to handle the freeing of rose_neigh
+structures and modify rose_remove_neigh() to handle removal only.
+
+Signed-off-by: Takamitsu Iwai <takamitz@amazon.co.jp>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20250823085857.47674-2-takamitz@amazon.co.jp
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/rose.h | 8 ++++++++
+ net/rose/rose_route.c | 15 ++++++---------
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/include/net/rose.h b/include/net/rose.h
+index 23267b4efcfa3..174b4f605d849 100644
+--- a/include/net/rose.h
++++ b/include/net/rose.h
+@@ -151,6 +151,14 @@ struct rose_sock {
+
+ #define rose_sk(sk) ((struct rose_sock *)(sk))
+
++static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
++{
++ if (rose_neigh->ax25)
++ ax25_cb_put(rose_neigh->ax25);
++ kfree(rose_neigh->digipeat);
++ kfree(rose_neigh);
++}
++
+ /* af_rose.c */
+ extern ax25_address rose_callsign;
+ extern int sysctl_rose_restart_request_timeout;
+diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
+index a7054546f52df..b406b1e0fb1e7 100644
+--- a/net/rose/rose_route.c
++++ b/net/rose/rose_route.c
+@@ -234,20 +234,12 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh)
+
+ if ((s = rose_neigh_list) == rose_neigh) {
+ rose_neigh_list = rose_neigh->next;
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
+ return;
+ }
+
+ while (s != NULL && s->next != NULL) {
+ if (s->next == rose_neigh) {
+ s->next = rose_neigh->next;
+- if (rose_neigh->ax25)
+- ax25_cb_put(rose_neigh->ax25);
+- kfree(rose_neigh->digipeat);
+- kfree(rose_neigh);
+ return;
+ }
+
+@@ -331,8 +323,10 @@ static int rose_del_node(struct rose_route_struct *rose_route,
+ if (rose_node->neighbour[i] == rose_neigh) {
+ rose_neigh->count--;
+
+- if (rose_neigh->count == 0 && rose_neigh->use == 0)
++ if (rose_neigh->count == 0 && rose_neigh->use == 0) {
+ rose_remove_neigh(rose_neigh);
++ rose_neigh_put(rose_neigh);
++ }
+
+ rose_node->count--;
+
+@@ -513,6 +507,7 @@ void rose_rt_device_down(struct net_device *dev)
+ }
+
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+ spin_unlock_bh(&rose_neigh_list_lock);
+ spin_unlock_bh(&rose_node_list_lock);
+@@ -569,6 +564,7 @@ static int rose_clear_routes(void)
+ if (s->use == 0 && !s->loopback) {
+ s->count = 0;
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+ }
+
+@@ -1301,6 +1297,7 @@ void __exit rose_rt_free(void)
+ rose_neigh = rose_neigh->next;
+
+ rose_remove_neigh(s);
++ rose_neigh_put(s);
+ }
+
+ while (rose_node != NULL) {
+--
+2.50.1
+
--- /dev/null
+From c13941d8583162065671e8da74728f84e5e132a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Apr 2024 12:03:05 +0300
+Subject: net: stmmac: Rename phylink_get_caps() callback to update_caps()
+
+From: Serge Semin <fancer.lancer@gmail.com>
+
+[ Upstream commit dc144baeb4fbfa0d91ce9c3875307566f58704ec ]
+
+Since recent commits the stmmac_ops::phylink_get_caps() callback has no
+longer been responsible for the phylink MAC capabilities getting, but
+merely updates the MAC capabilities in the mac_device_info::link::caps
+field. Rename the callback to comply with the what the method does now.
+
+Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
+Reviewed-by: Romain Gantois <romain.gantois@bootlin.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 42ef11b2bff5 ("net: stmmac: xgmac: Correct supported speed modes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 8 ++++----
+ drivers/net/ethernet/stmicro/stmmac/hwif.h | 8 ++++----
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++---
+ 3 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+index a9837985a483d..bdb4f527289d2 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+@@ -69,7 +69,7 @@ static void dwmac4_core_init(struct mac_device_info *hw,
+ init_waitqueue_head(&priv->tstamp_busy_wait);
+ }
+
+-static void dwmac4_phylink_get_caps(struct stmmac_priv *priv)
++static void dwmac4_update_caps(struct stmmac_priv *priv)
+ {
+ if (priv->plat->tx_queues_to_use > 1)
+ priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD | MAC_1000HD);
+@@ -1161,7 +1161,7 @@ static int dwmac4_config_l4_filter(struct mac_device_info *hw, u32 filter_no,
+
+ const struct stmmac_ops dwmac4_ops = {
+ .core_init = dwmac4_core_init,
+- .phylink_get_caps = dwmac4_phylink_get_caps,
++ .update_caps = dwmac4_update_caps,
+ .set_mac = stmmac_set_mac,
+ .rx_ipc = dwmac4_rx_ipc_enable,
+ .rx_queue_enable = dwmac4_rx_queue_enable,
+@@ -1204,7 +1204,7 @@ const struct stmmac_ops dwmac4_ops = {
+
+ const struct stmmac_ops dwmac410_ops = {
+ .core_init = dwmac4_core_init,
+- .phylink_get_caps = dwmac4_phylink_get_caps,
++ .update_caps = dwmac4_update_caps,
+ .set_mac = stmmac_dwmac4_set_mac,
+ .rx_ipc = dwmac4_rx_ipc_enable,
+ .rx_queue_enable = dwmac4_rx_queue_enable,
+@@ -1253,7 +1253,7 @@ const struct stmmac_ops dwmac410_ops = {
+
+ const struct stmmac_ops dwmac510_ops = {
+ .core_init = dwmac4_core_init,
+- .phylink_get_caps = dwmac4_phylink_get_caps,
++ .update_caps = dwmac4_update_caps,
+ .set_mac = stmmac_dwmac4_set_mac,
+ .rx_ipc = dwmac4_rx_ipc_enable,
+ .rx_queue_enable = dwmac4_rx_queue_enable,
+diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
+index 47fb8e1646c2e..ee9a7d98648b0 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
++++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
+@@ -300,8 +300,8 @@ struct stmmac_est;
+ struct stmmac_ops {
+ /* MAC core initialization */
+ void (*core_init)(struct mac_device_info *hw, struct net_device *dev);
+- /* Get phylink capabilities */
+- void (*phylink_get_caps)(struct stmmac_priv *priv);
++ /* Update MAC capabilities */
++ void (*update_caps)(struct stmmac_priv *priv);
+ /* Enable the MAC RX/TX */
+ void (*set_mac)(void __iomem *ioaddr, bool enable);
+ /* Enable and verify that the IPC module is supported */
+@@ -423,8 +423,8 @@ struct stmmac_ops {
+
+ #define stmmac_core_init(__priv, __args...) \
+ stmmac_do_void_callback(__priv, mac, core_init, __args)
+-#define stmmac_mac_phylink_get_caps(__priv) \
+- stmmac_do_void_callback(__priv, mac, phylink_get_caps, __priv)
++#define stmmac_mac_update_caps(__priv) \
++ stmmac_do_void_callback(__priv, mac, update_caps, __priv)
+ #define stmmac_mac_set(__priv, __args...) \
+ stmmac_do_void_callback(__priv, mac, set_mac, __args)
+ #define stmmac_rx_ipc(__priv, __args...) \
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 615d25a0e46be..fa8ee0624f2f2 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1230,8 +1230,8 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
+ xpcs_get_interfaces(priv->hw->xpcs,
+ priv->phylink_config.supported_interfaces);
+
+- /* Get the MAC specific capabilities */
+- stmmac_mac_phylink_get_caps(priv);
++ /* Refresh the MAC-specific capabilities */
++ stmmac_mac_update_caps(priv);
+
+ priv->phylink_config.mac_capabilities = priv->hw->link.caps;
+
+@@ -7232,7 +7232,7 @@ int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt)
+ priv->rss.table[i] = ethtool_rxfh_indir_default(i,
+ rx_cnt);
+
+- stmmac_mac_phylink_get_caps(priv);
++ stmmac_mac_update_caps(priv);
+
+ priv->phylink_config.mac_capabilities = priv->hw->link.caps;
+
+--
+2.50.1
+
--- /dev/null
+From 70d5703b835a692e70b28d80b73eb51b16e492fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:54 +0800
+Subject: net: stmmac: Set CIC bit only for TX queues with COE
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit b1eded580ab28119de0b0f21efe37ee2b4419144 ]
+
+Currently, in the AF_XDP transmit paths, the CIC bit of
+TX Desc3 is set for all packets. Setting this bit for
+packets transmitting through queues that don't support
+checksum offloading causes the TX DMA to get stuck after
+transmitting some packets. This patch ensures the CIC bit
+of TX Desc3 is set only if the TX queue supports checksum
+offloading.
+
+Fixes: 132c32ee5bc0 ("net: stmmac: Add TX via XDP zero-copy socket")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-3-c225fe4444c0@altera.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 | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index fa8ee0624f2f2..ff5389a8efc33 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2426,6 +2426,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+ struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue);
+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
+ struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
++ bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+ struct xsk_buff_pool *pool = tx_q->xsk_pool;
+ unsigned int entry = tx_q->cur_tx;
+ struct dma_desc *tx_desc = NULL;
+@@ -2496,7 +2497,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
+ }
+
+ stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len,
+- true, priv->mode, true, true,
++ csum, priv->mode, true, true,
+ xdp_desc.len);
+
+ stmmac_enable_dma_transmission(priv, priv->ioaddr);
+@@ -4789,6 +4790,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+ {
+ struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[queue];
+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
++ bool csum = !priv->plat->tx_queues_cfg[queue].coe_unsupported;
+ unsigned int entry = tx_q->cur_tx;
+ struct dma_desc *tx_desc;
+ dma_addr_t dma_addr;
+@@ -4833,7 +4835,7 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
+ stmmac_set_desc_addr(priv, tx_desc, dma_addr);
+
+ stmmac_prepare_tx_desc(priv, tx_desc, 1, xdpf->len,
+- true, priv->mode, true, true,
++ csum, priv->mode, true, true,
+ xdpf->len);
+
+ tx_q->tx_count_frames++;
+--
+2.50.1
+
--- /dev/null
+From c3be2a69b1d2e2d1b8e80a1b63e29db53152f337 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:53 +0800
+Subject: net: stmmac: xgmac: Correct supported speed modes
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 42ef11b2bff5b6a2910c28d2ea47cc00e0fbcaec ]
+
+Correct supported speed modes as per the XGMAC databook.
+Commit 9cb54af214a7 ("net: stmmac: Fix IP-cores specific
+MAC capabilities") removes support for 10M, 100M and
+1000HD. 1000HD is not supported by XGMAC IP, but it does
+support 10M and 100M FD mode for XGMAC version >= 2_20,
+and it also supports 10M and 100M HD mode if the HDSEL bit
+is set in the MAC_HW_FEATURE0 reg. This commit enables support
+for 10M and 100M speed modes for XGMAC IP based on XGMAC
+version and MAC capabilities.
+
+Fixes: 9cb54af214a7 ("net: stmmac: Fix IP-cores specific MAC capabilities")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-2-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 13 +++++++++++--
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 5 +++++
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+index 052566f5b7f36..0bcb378fa0bc9 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+@@ -47,6 +47,14 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,
+ writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
+ }
+
++static void dwxgmac2_update_caps(struct stmmac_priv *priv)
++{
++ if (!priv->dma_cap.mbps_10_100)
++ priv->hw->link.caps &= ~(MAC_10 | MAC_100);
++ else if (!priv->dma_cap.half_duplex)
++ priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD);
++}
++
+ static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
+ {
+ u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
+@@ -1583,6 +1591,7 @@ static void dwxgmac3_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *
+
+ const struct stmmac_ops dwxgmac210_ops = {
+ .core_init = dwxgmac2_core_init,
++ .update_caps = dwxgmac2_update_caps,
+ .set_mac = dwxgmac2_set_mac,
+ .rx_ipc = dwxgmac2_rx_ipc,
+ .rx_queue_enable = dwxgmac2_rx_queue_enable,
+@@ -1705,8 +1714,8 @@ int dwxgmac2_setup(struct stmmac_priv *priv)
+ mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+
+ mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+- MAC_1000FD | MAC_2500FD | MAC_5000FD |
+- MAC_10000FD;
++ MAC_10 | MAC_100 | MAC_1000FD |
++ MAC_2500FD | MAC_5000FD | MAC_10000FD;
+ mac->link.duplex = 0;
+ mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
+ mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 37c4258fef794..b2c03cb65c7cc 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -382,8 +382,11 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
+ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+ struct dma_features *dma_cap)
+ {
++ struct stmmac_priv *priv;
+ u32 hw_cap;
+
++ priv = container_of(dma_cap, struct stmmac_priv, dma_cap);
++
+ /* MAC HW feature 0 */
+ hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
+ dma_cap->edma = (hw_cap & XGMAC_HWFEAT_EDMA) >> 31;
+@@ -406,6 +409,8 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+ dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4;
+ dma_cap->half_duplex = (hw_cap & XGMAC_HWFEAT_HDSEL) >> 3;
+ dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;
++ if (dma_cap->mbps_1000 && priv->synopsys_id >= DWXGMAC_CORE_2_20)
++ dma_cap->mbps_10_100 = 1;
+
+ /* MAC HW feature 1 */
+ hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
+--
+2.50.1
+
--- /dev/null
+From 5fbfd8e6fa5005293c49fc6d46ea7b9a12ac785d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 12:36:52 +0800
+Subject: net: stmmac: xgmac: Do not enable RX FIFO Overflow interrupts
+
+From: Rohan G Thomas <rohan.g.thomas@altera.com>
+
+[ Upstream commit 4f23382841e67174211271a454811dd17c0ef3c5 ]
+
+Enabling RX FIFO Overflow interrupts is counterproductive
+and causes an interrupt storm when RX FIFO overflows.
+Disabling this interrupt has no side effect and eliminates
+interrupt storms when the RX FIFO overflows.
+
+Commit 8a7cb245cf28 ("net: stmmac: Do not enable RX FIFO
+overflow interrupts") disables RX FIFO overflow interrupts
+for DWMAC4 IP and removes the corresponding handling of
+this interrupt. This patch is doing the same thing for
+XGMAC IP.
+
+Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
+Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
+Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250825-xgmac-minor-fixes-v3-1-c225fe4444c0@altera.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+index 05ea74e937939..37c4258fef794 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+@@ -203,10 +203,6 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+ }
+
+ writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+-
+- /* Enable MTL RX overflow */
+- value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+- writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+ }
+
+ static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
+--
+2.50.1
+
--- /dev/null
+From ab8b27d03d86e08bfd0667fd0965c5dbeab92974 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Aug 2025 08:55:43 +0200
+Subject: phy: mscc: Fix when PTP clock is register and unregister
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit 882e57cbc7204662f6c5672d5b04336c1d790b03 ]
+
+It looks like that every time when the interface was set down and up the
+driver was creating a new ptp clock. On top of this the function
+ptp_clock_unregister was never called.
+Therefore fix this by calling ptp_clock_register and initialize the
+mii_ts struct inside the probe function and call ptp_clock_unregister when
+driver is removed.
+
+Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250825065543.2916334-1-horatiu.vultur@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/mscc/mscc.h | 4 ++++
+ drivers/net/phy/mscc/mscc_main.c | 4 +---
+ drivers/net/phy/mscc/mscc_ptp.c | 34 ++++++++++++++++++++------------
+ 3 files changed, 26 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
+index cdb343779a8fb..4ba6e32cf6d8d 100644
+--- a/drivers/net/phy/mscc/mscc.h
++++ b/drivers/net/phy/mscc/mscc.h
+@@ -476,6 +476,7 @@ static inline void vsc8584_config_macsec_intr(struct phy_device *phydev)
+ void vsc85xx_link_change_notify(struct phy_device *phydev);
+ void vsc8584_config_ts_intr(struct phy_device *phydev);
+ int vsc8584_ptp_init(struct phy_device *phydev);
++void vsc8584_ptp_deinit(struct phy_device *phydev);
+ int vsc8584_ptp_probe_once(struct phy_device *phydev);
+ int vsc8584_ptp_probe(struct phy_device *phydev);
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev);
+@@ -490,6 +491,9 @@ static inline int vsc8584_ptp_init(struct phy_device *phydev)
+ {
+ return 0;
+ }
++static inline void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++}
+ static inline int vsc8584_ptp_probe_once(struct phy_device *phydev)
+ {
+ return 0;
+diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
+index 3de72d9cc22bd..3a932b30f4358 100644
+--- a/drivers/net/phy/mscc/mscc_main.c
++++ b/drivers/net/phy/mscc/mscc_main.c
+@@ -2337,9 +2337,7 @@ static int vsc85xx_probe(struct phy_device *phydev)
+
+ static void vsc85xx_remove(struct phy_device *phydev)
+ {
+- struct vsc8531_private *priv = phydev->priv;
+-
+- skb_queue_purge(&priv->rx_skbs_list);
++ vsc8584_ptp_deinit(phydev);
+ }
+
+ /* Microsemi VSC85xx PHYs */
+diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
+index add1a9ee721af..1f6237705b44b 100644
+--- a/drivers/net/phy/mscc/mscc_ptp.c
++++ b/drivers/net/phy/mscc/mscc_ptp.c
+@@ -1297,7 +1297,6 @@ static void vsc8584_set_input_clk_configured(struct phy_device *phydev)
+
+ static int __vsc8584_init_ptp(struct phy_device *phydev)
+ {
+- struct vsc8531_private *vsc8531 = phydev->priv;
+ static const u32 ltc_seq_e[] = { 0, 400000, 0, 0, 0 };
+ static const u8 ltc_seq_a[] = { 8, 6, 5, 4, 2 };
+ u32 val;
+@@ -1514,17 +1513,7 @@ static int __vsc8584_init_ptp(struct phy_device *phydev)
+
+ vsc85xx_ts_eth_cmp1_sig(phydev);
+
+- vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
+- vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
+- vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
+- vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
+- phydev->mii_ts = &vsc8531->mii_ts;
+-
+- memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
+-
+- vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
+- &phydev->mdio.dev);
+- return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
++ return 0;
+ }
+
+ void vsc8584_config_ts_intr(struct phy_device *phydev)
+@@ -1551,6 +1540,16 @@ int vsc8584_ptp_init(struct phy_device *phydev)
+ return 0;
+ }
+
++void vsc8584_ptp_deinit(struct phy_device *phydev)
++{
++ struct vsc8531_private *vsc8531 = phydev->priv;
++
++ if (vsc8531->ptp->ptp_clock) {
++ ptp_clock_unregister(vsc8531->ptp->ptp_clock);
++ skb_queue_purge(&vsc8531->rx_skbs_list);
++ }
++}
++
+ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
+ {
+ struct vsc8531_private *priv = phydev->priv;
+@@ -1608,7 +1607,16 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
+
+ vsc8531->ptp->phydev = phydev;
+
+- return 0;
++ vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp;
++ vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp;
++ vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp;
++ vsc8531->mii_ts.ts_info = vsc85xx_ts_info;
++ phydev->mii_ts = &vsc8531->mii_ts;
++
++ memcpy(&vsc8531->ptp->caps, &vsc85xx_clk_caps, sizeof(vsc85xx_clk_caps));
++ vsc8531->ptp->ptp_clock = ptp_clock_register(&vsc8531->ptp->caps,
++ &phydev->mdio.dev);
++ return PTR_ERR_OR_ZERO(vsc8531->ptp->ptp_clock);
+ }
+
+ int vsc8584_ptp_probe_once(struct phy_device *phydev)
+--
+2.50.1
+
--- /dev/null
+From cfe438e147daae11209186e775761e2046c90a6b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 May 2025 10:11:04 +0530
+Subject: powerpc/kvm: Fix ifdef to remove build warning
+
+From: Madhavan Srinivasan <maddy@linux.ibm.com>
+
+[ Upstream commit 88688a2c8ac6c8036d983ad8b34ce191c46a10aa ]
+
+When compiling for pseries or powernv defconfig with "make C=1",
+these warning were reported bu sparse tool in powerpc/kernel/kvm.c
+
+arch/powerpc/kernel/kvm.c:635:9: warning: switch with no cases
+arch/powerpc/kernel/kvm.c:646:9: warning: switch with no cases
+
+Currently #ifdef were added after the switch case which are specific
+for BOOKE and PPC_BOOK3S_32. These are not enabled in pseries/powernv
+defconfig. Fix it by moving the #ifdef before switch(){}
+
+Fixes: cbe487fac7fc0 ("KVM: PPC: Add mtsrin PV code")
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20250518044107.39928-1-maddy@linux.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/kernel/kvm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
+index 5b3c093611baf..7209d00a9c257 100644
+--- a/arch/powerpc/kernel/kvm.c
++++ b/arch/powerpc/kernel/kvm.c
+@@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ #endif
+ }
+
+- switch (inst_no_rt & ~KVM_MASK_RB) {
+ #ifdef CONFIG_PPC_BOOK3S_32
++ switch (inst_no_rt & ~KVM_MASK_RB) {
+ case KVM_INST_MTSRIN:
+ if (features & KVM_MAGIC_FEAT_SR) {
+ u32 inst_rb = _inst & KVM_MASK_RB;
+ kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
+ }
+ break;
+-#endif
+ }
++#endif
+
+- switch (_inst) {
+ #ifdef CONFIG_BOOKE
++ switch (_inst) {
+ case KVM_INST_WRTEEI_0:
+ kvm_patch_ins_wrteei_0(inst);
+ break;
+@@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
+ case KVM_INST_WRTEEI_1:
+ kvm_patch_ins_wrtee(inst, 0, 1);
+ break;
+-#endif
+ }
++#endif
+ }
+
+ extern u32 kvm_template_start[];
+--
+2.50.1
+
--- /dev/null
+From a320809ab02399bdd639e1c8797621bf26bc94e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Aug 2025 14:13:14 +0000
+Subject: sctp: initialize more fields in sctp_v6_from_sk()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2e8750469242cad8f01f320131fd5a6f540dbb99 ]
+
+syzbot found that sin6_scope_id was not properly initialized,
+leading to undefined behavior.
+
+Clear sin6_scope_id and sin6_flowinfo.
+
+BUG: KMSAN: uninit-value in __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ __sctp_v6_cmp_addr+0x887/0x8c0 net/sctp/ipv6.c:649
+ sctp_inet6_cmp_addr+0x4f2/0x510 net/sctp/ipv6.c:983
+ sctp_bind_addr_conflict+0x22a/0x3b0 net/sctp/bind_addr.c:390
+ sctp_get_port_local+0x21eb/0x2440 net/sctp/socket.c:8452
+ sctp_get_port net/sctp/socket.c:8523 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x710/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+ x64_sys_call+0x271d/0x3e20 arch/x86/include/generated/asm/syscalls_64.h:51
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xd9/0x210 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Local variable addr.i.i created at:
+ sctp_get_port net/sctp/socket.c:8515 [inline]
+ sctp_listen_start net/sctp/socket.c:8567 [inline]
+ sctp_inet_listen+0x650/0xfd0 net/sctp/socket.c:8636
+ __sys_listen_socket net/socket.c:1912 [inline]
+ __sys_listen net/socket.c:1927 [inline]
+ __do_sys_listen net/socket.c:1932 [inline]
+ __se_sys_listen net/socket.c:1930 [inline]
+ __x64_sys_listen+0x343/0x4c0 net/socket.c:1930
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+e69f06a0f30116c68056@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/68adc0a2.050a0220.37038e.00c4.GAE@google.com/T/#u
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Acked-by: Xin Long <lucien.xin@gmail.com>
+Link: https://patch.msgid.link/20250826141314.1802610-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sctp/ipv6.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 717828e531621..0673857cb3d8b 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -547,7 +547,9 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+ {
+ addr->v6.sin6_family = AF_INET6;
+ addr->v6.sin6_port = 0;
++ addr->v6.sin6_flowinfo = 0;
+ addr->v6.sin6_addr = sk->sk_v6_rcv_saddr;
++ addr->v6.sin6_scope_id = 0;
+ }
+
+ /* Initialize sk->sk_rcv_saddr from sctp_addr. */
+--
+2.50.1
+
nfs-fold-nfs_page_group_lock_subrequests-into-nfs_lock_and_join_requests.patch
nfs-fix-a-race-when-updating-an-existing-write.patch
vhost-net-protect-ubufs-with-rcu-read-lock-in-vhost_net_ubuf_put.patch
+net-ipv4-fix-regression-in-local-broadcast-routes.patch
+drm-msm-defer-fd_install-in-submit-ioctl.patch
+powerpc-kvm-fix-ifdef-to-remove-build-warning.patch
+hid-input-rename-hidinput_set_battery_charge_status.patch
+hid-input-report-battery-status-changes-immediately.patch
+bluetooth-hci_event-treat-unknown_conn_id-on-disconn.patch
+bluetooth-hci_event-mark-connection-as-closed-during.patch
+bluetooth-hci_event-detect-if-hci_ev_num_comp_pkts-i.patch
+bluetooth-hci_sync-fix-set_local_name-race-condition.patch
+atm-atmtcp-prevent-arbitrary-write-in-atmtcp_recv_co.patch
+drm-nouveau-remove-unused-increment-in-gm200_flcn_pi.patch
+drm-nouveau-remove-unused-memory-target-test.patch
+ice-introduce-ice_xdp_buff.patch
+ice-gather-page_count-s-of-each-frag-right-before-xd.patch
+ice-stop-storing-xdp-verdict-within-ice_rx_buf.patch
+ice-fix-incorrect-counter-for-buffer-allocation-fail.patch
+dt-bindings-display-msm-qcom-mdp5-drop-lut-clock.patch
+net-dlink-fix-multicast-stats-being-counted-incorrec.patch
+phy-mscc-fix-when-ptp-clock-is-register-and-unregist.patch
+net-mlx5-reload-auxiliary-drivers-on-fw_activate.patch
+net-mlx5-add-device-cap-for-supporting-hot-reset-in-.patch
+net-mlx5-add-support-for-sync-reset-using-hot-reset.patch
+net-mlx5-fix-lockdep-assertion-on-sync-reset-unload-.patch
+net-mlx5-call-mlx5_sf_id_erase-once-in-mlx5_sf_deall.patch
+net-mlx5-use-devlink-port-pointer-to-get-the-pointer.patch
+net-mlx5-convert-sf-port_indices-xarray-to-function_.patch
+net-mlx5-nack-sync-reset-when-sfs-are-present.patch
+net-mlx5e-update-and-set-xon-xoff-upon-mtu-set.patch
+net-mlx5e-update-and-set-xon-xoff-upon-port-speed-se.patch
+net-mlx5e-set-local-xoff-after-fw-update.patch
+net-stmmac-xgmac-do-not-enable-rx-fifo-overflow-inte.patch
+net-stmmac-rename-phylink_get_caps-callback-to-updat.patch
+net-stmmac-xgmac-correct-supported-speed-modes.patch
+net-stmmac-set-cic-bit-only-for-tx-queues-with-coe.patch
+net-rose-split-remove-and-free-operations-in-rose_re.patch
+net-rose-convert-use-field-to-refcount_t.patch
+net-rose-include-node-references-in-rose_neigh-refco.patch
+sctp-initialize-more-fields-in-sctp_v6_from_sk.patch
+efivarfs-fix-slab-out-of-bounds-in-efivarfs_d_compar.patch