--- /dev/null
+From d1b706635c08a8bfee34e02d312459a9c8a09be2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 15:58:45 -0300
+Subject: apparmor: fix invalid deref of rawdata when export_binary is unset
+
+From: Georgia Garcia <georgia.garcia@canonical.com>
+
+[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ]
+
+If the export_binary parameter is disabled on runtime, profiles that
+were loaded before that will still have their rawdata stored in
+apparmorfs, with a symbolic link to the rawdata on the policy
+directory. When one of those profiles are replaced, the rawdata is set
+to NULL, but when trying to resolve the symbolic links to rawdata for
+that profile, it will try to dereference profile->rawdata->name when
+profile->rawdata is now NULL causing an oops. Fix it by checking if
+rawdata is set.
+
+[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088
+[ 168.657420] #PF: supervisor read access in kernel mode
+[ 168.660619] #PF: error_code(0x0000) - not-present page
+[ 168.663613] PGD 0 P4D 0
+[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI
+[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary)
+[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330
+[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8
+[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282
+[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158
+[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80
+[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000
+[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80
+[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0
+[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000
+[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0
+[ 168.701696] Call Trace:
+[ 168.702325] <TASK>
+[ 168.702995] rawdata_get_link_data+0x1c/0x30
+[ 168.704145] vfs_readlink+0xd4/0x160
+[ 168.705152] do_readlinkat+0x114/0x180
+[ 168.706214] __x64_sys_readlink+0x1e/0x30
+[ 168.708653] x64_sys_call+0x1d77/0x26b0
+[ 168.709525] do_syscall_64+0x81/0x500
+[ 168.710348] ? do_statx+0x72/0xb0
+[ 168.711109] ? putname+0x3e/0x80
+[ 168.711845] ? __x64_sys_statx+0xb7/0x100
+[ 168.712711] ? x64_sys_call+0x10fc/0x26b0
+[ 168.713577] ? do_syscall_64+0xbf/0x500
+[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0
+[ 168.715404] ? irqentry_exit+0xb2/0x740
+[ 168.716359] ? exc_page_fault+0x90/0x1b0
+[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement")
+Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/apparmorfs.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index 06eac22665656..e736936f4f0ba 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -1618,6 +1618,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry,
+
+ label = aa_get_label_rcu(&proxy->label);
+ profile = labels_profile(label);
++
++ /* rawdata can be null when aa_g_export_binary is unset during
++ * runtime and a profile is replaced
++ */
++ if (!profile->rawdata) {
++ aa_put_label(label);
++ return ERR_PTR(-ENOENT);
++ }
++
+ depth = profile_depth(profile);
+ target = gen_symlink_name(depth, profile->rawdata->name, name);
+ aa_put_label(label);
+--
+2.51.0
+
--- /dev/null
+From ce999fd775d3440d57c7eabf465f2d6a8cc63087 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 15:07:42 -0800
+Subject: apparmor: fix NULL sock in aa_sock_file_perm
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ]
+
+Deal with the potential that sock and sock-sk can be NULL during
+socket setup or teardown. This could lead to an oops. The fix for NULL
+pointer dereference in __unix_needs_revalidation shows this is at
+least possible for af_unix sockets. While the fix for af_unix sockets
+applies for newer mediation this is still the fall back path for older
+af_unix mediation and other sockets, so ensure it is covered.
+
+Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/net.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index fa0e85568450b..fbbfedd253f69 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -182,8 +182,10 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
+ struct socket *sock)
+ {
+ AA_BUG(!label);
+- AA_BUG(!sock);
+- AA_BUG(!sock->sk);
++
++ /* sock && sock->sk can be NULL for sockets being set up or torn down */
++ if (!sock || !sock->sk)
++ return 0;
+
+ return aa_label_sk_perm(label, op, request, sock->sk);
+ }
+--
+2.51.0
+
--- /dev/null
+From 254c935f4063985eebcb2bba21b1a749d3eb3ba8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:16:54 -0800
+Subject: apparmor: fix rlimit for posix cpu timers
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ]
+
+Posix cpu timers requires an additional step beyond setting the rlimit.
+Refactor the code so its clear when what code is setting the
+limit and conditionally update the posix cpu timers when appropriate.
+
+Fixes: baa73d9e478ff ("posix-timers: Make them configurable")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/resource.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index 1ae4874251a96..f94e416399441 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -182,6 +182,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
+ new->rlimits.limits[j].rlim_max);
+ /* soft limit should not exceed hard limit */
+ rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
++ if (j == RLIMIT_CPU &&
++ rlim->rlim_cur != RLIM_INFINITY &&
++ IS_ENABLED(CONFIG_POSIX_TIMERS))
++ (void) update_rlimit_cpu(current->group_leader,
++ rlim->rlim_cur);
+ }
+ }
+ }
+--
+2.51.0
+
--- /dev/null
+From 315b91d073e9a3225e4a2eae70abb1242d3c8a80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 06:09:19 +0000
+Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ]
+
+The ALB RX path may access rx_hashtbl concurrently with bond
+teardown. During rapid bond up/down cycles, rlb_deinitialize()
+frees rx_hashtbl while RX handlers are still running, leading
+to a null pointer dereference detected by KASAN.
+
+However, the root cause is that rlb_arp_recv() can still be accessed
+after setting recv_probe to NULL, which is actually a use-after-free
+(UAF) issue. That is the reason for using the referenced commit in the
+Fixes tag.
+
+[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI
+[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef]
+[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary)
+[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022
+[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding]
+[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6
+ 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00
+[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206
+[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e
+[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8
+[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8
+[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119
+[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810
+[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000
+[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0
+[ 214.310347] Call Trace:
+[ 214.313070] <IRQ>
+[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding]
+[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding]
+[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding]
+[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710
+[ 214.339199] ? __pfx_arp_process+0x10/0x10
+[ 214.343775] ? sched_balance_find_src_group+0x98/0x630
+[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10
+[ 214.356513] ? arp_rcv+0x307/0x690
+[ 214.360311] ? __pfx_arp_rcv+0x10/0x10
+[ 214.364499] ? __lock_acquire+0x58c/0xbd0
+[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0
+[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10
+[ 214.380743] ? lock_acquire+0x10b/0x140
+[ 214.385026] process_backlog+0x3f1/0x13a0
+[ 214.389502] ? process_backlog+0x3aa/0x13a0
+[ 214.394174] __napi_poll.constprop.0+0x9f/0x370
+[ 214.399233] net_rx_action+0x8c1/0xe60
+[ 214.403423] ? __pfx_net_rx_action+0x10/0x10
+[ 214.408193] ? lock_acquire.part.0+0xbd/0x260
+[ 214.413058] ? sched_clock_cpu+0x6c/0x540
+[ 214.417540] ? mark_held_locks+0x40/0x70
+[ 214.421920] handle_softirqs+0x1fd/0x860
+[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10
+[ 214.431264] ? __neigh_event_send+0x2d6/0xf50
+[ 214.436131] do_softirq+0xb1/0xf0
+[ 214.439830] </IRQ>
+
+The issue is reproducible by repeatedly running
+ip link set bond0 up/down while receiving ARP messages, where
+rlb_arp_recv() can race with rlb_deinitialize() and dereference
+a freed rx_hashtbl entry.
+
+Fix this by setting recv_probe to NULL and then calling
+synchronize_net() to wait for any concurrent RX processing to finish.
+This ensures that no RX handler can access rx_hashtbl after it is freed
+in bond_alb_deinitialize().
+
+Reported-by: Liang Li <liali@redhat.com>
+Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 1d8a6690527aa..87e23796680b3 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -3804,9 +3804,13 @@ static int bond_close(struct net_device *bond_dev)
+
+ bond_work_cancel_all(bond);
+ bond->send_peer_notif = 0;
++ WRITE_ONCE(bond->recv_probe, NULL);
++
++ /* Wait for any in-flight RX handlers */
++ synchronize_net();
++
+ if (bond_is_lb(bond))
+ bond_alb_deinitialize(bond);
+- bond->recv_probe = NULL;
+
+ if (bond_uses_primary(bond)) {
+ rcu_read_lock();
+--
+2.51.0
+
--- /dev/null
+From c0d8ebc4d6ccaa268ca7bb8f21ae5d5da33fa634 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 17:15:53 +0000
+Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not
+ found
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ]
+
+If btrfs_search_slot_for_read() returns 1, it means we did not find any
+key greater than or equals to the key we asked for, meaning we have
+reached the end of the tree and therefore the path is not valid. If
+this happens we need to break out of the loop and stop, instead of
+continuing and accessing an invalid path.
+
+Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/qgroup.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index 647feb72c8b0a..a252f6cca0027 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1090,11 +1090,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
+ }
+ if (ret > 0) {
+ /*
+- * Shouldn't happen, but in case it does we
+- * don't need to do the btrfs_next_item, just
+- * continue.
++ * Shouldn't happen because the key should still
++ * be there (return 0), but in case it does it
++ * means we have reached the end of the tree -
++ * there are no more leaves with items that have
++ * a key greater than or equals to @found_key,
++ * so just stop the search loop.
+ */
+- continue;
++ break;
+ }
+ }
+ ret = btrfs_next_item(tree_root, path);
+--
+2.51.0
+
--- /dev/null
+From 6aa845a0aeaf0875860b7900406d32d55e21dd10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 00:20:02 +0530
+Subject: cpuidle: Skip governor when only one idle state is available
+
+From: Aboorva Devarajan <aboorvad@linux.ibm.com>
+
+[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ]
+
+On certain platforms (PowerNV systems without a power-mgt DT node),
+cpuidle may register only a single idle state. In cases where that
+single state is a polling state (state 0), the ladder governor may
+incorrectly treat state 1 as the first usable state and pass an
+out-of-bounds index. This can lead to a NULL enter callback being
+invoked, ultimately resulting in a system crash.
+
+[ 13.342636] cpuidle-powernv : Only Snooze is available
+[ 13.351854] Faulting instruction address: 0x00000000
+[ 13.376489] NIP [0000000000000000] 0x0
+[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668
+
+Fix this by adding a bail-out in cpuidle_select() that returns state 0
+directly when state_count <= 1, bypassing the governor and keeping the
+tick running.
+
+Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol")
+Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
+Reviewed-by: Christian Loehle <christian.loehle@arm.com>
+Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/cpuidle.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
+index 1c1fa6ac9244a..87a57cee40fcb 100644
+--- a/drivers/cpuidle/cpuidle.c
++++ b/drivers/cpuidle/cpuidle.c
+@@ -319,6 +319,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
+ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+ bool *stop_tick)
+ {
++ /*
++ * If there is only a single idle state (or none), there is nothing
++ * meaningful for the governor to choose. Skip the governor and
++ * always use state 0 with the tick running.
++ */
++ if (drv->state_count <= 1) {
++ *stop_tick = false;
++ return 0;
++ }
++
+ return cpuidle_curr_governor->select(drv, dev, stop_tick);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 9a76957ed55decb0f0a5807a3980137e4838adc8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jan 2026 08:55:49 +0530
+Subject: drm/i915/acpi: free _DSM package when no connectors
+
+From: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+
+[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ]
+
+acpi_evaluate_dsm_typed() returns an ACPI package in pkg.
+When pkg->package.count == 0, we returned without freeing pkg,
+leaking memory. Free pkg before returning on the empty case.
+
+Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_acpi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c
+index 833d0c1be4f1d..1c01d8370fe94 100644
+--- a/drivers/gpu/drm/i915/display/intel_acpi.c
++++ b/drivers/gpu/drm/i915/display/intel_acpi.c
+@@ -86,6 +86,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle)
+
+ if (!pkg->package.count) {
+ DRM_DEBUG_DRIVER("no connection in _DSM\n");
++ ACPI_FREE(pkg);
+ return;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From bc57d951f90a9f9eb6c464f76a84a84f6455ee9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:22:02 +0000
+Subject: ipv6: fix a race in ip6_sock_set_v6only()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ]
+
+It is unlikely that this function will be ever called
+with isk->inet_num being not zero.
+
+Perform the check on isk->inet_num inside the locked section
+for complete safety.
+
+Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ipv6.h | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index 2909233427de0..d7b0710d0d9c1 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -1177,12 +1177,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
+
+ static inline int ip6_sock_set_v6only(struct sock *sk)
+ {
+- if (inet_sk(sk)->inet_num)
+- return -EINVAL;
++ int ret = 0;
++
+ lock_sock(sk);
+- sk->sk_ipv6only = true;
++ if (inet_sk(sk)->inet_num)
++ ret = -EINVAL;
++ else
++ sk->sk_ipv6only = true;
+ release_sock(sk);
+- return 0;
++ return ret;
+ }
+
+ static inline void ip6_sock_set_recverr(struct sock *sk)
+--
+2.51.0
+
--- /dev/null
+From f82790251ee323c944bfdff6768be06ec1949249 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:25:57 +0000
+Subject: macvlan: observe an RCU grace period in macvlan_common_newlink()
+ error path
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ]
+
+valis reported that a race condition still happens after my prior patch.
+
+macvlan_common_newlink() might have made @dev visible before
+detecting an error, and its caller will directly call free_netdev(dev).
+
+We must respect an RCU period, either in macvlan or the core networking
+stack.
+
+After adding a temporary mdelay(1000) in macvlan_forward_source_one()
+to open the race window, valis repro was:
+
+ip link add p1 type veth peer p2
+ip link set address 00:00:00:00:00:20 dev p1
+ip link set up dev p1
+ip link set up dev p2
+ip link add mv0 link p2 type macvlan mode source
+
+(ip link add invalid% link p2 type macvlan mode source macaddr add
+00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4
+PING 1.2.3.4 (1.2.3.4): 56 data bytes
+RTNETLINK answers: Invalid argument
+
+BUG: KASAN: slab-use-after-free in macvlan_forward_source
+(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+Read of size 8 at addr ffff888016bb89c0 by task e/175
+
+CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
+Call Trace:
+<IRQ>
+dump_stack_lvl (lib/dump_stack.c:123)
+print_report (mm/kasan/report.c:379 mm/kasan/report.c:482)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+kasan_report (mm/kasan/report.c:597)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+? tasklet_init (kernel/softirq.c:983)
+macvlan_handle_frame (drivers/net/macvlan.c:501)
+
+Allocated by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+__kasan_kmalloc (mm/kasan/common.c:419)
+__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657
+mm/slub.c:7140)
+alloc_netdev_mqs (net/core/dev.c:12012)
+rtnl_create_link (net/core/rtnetlink.c:3648)
+rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Freed by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+kasan_save_free_info (mm/kasan/generic.c:587)
+__kasan_slab_free (mm/kasan/common.c:287)
+kfree (mm/slub.c:6674 mm/slub.c:6882)
+rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: valis <sec@valis.email>
+Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macvlan.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index cae48b1b7020f..95ae47a7a69dd 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1524,6 +1524,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
+ if (create)
+ macvlan_port_destroy(port->dev);
+ }
++ /* @dev might have been made visible before an error was detected.
++ * Make sure to observe an RCU grace period before our caller
++ * (rtnl_newlink()) frees it.
++ */
++ synchronize_net();
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(macvlan_common_newlink);
+--
+2.51.0
+
--- /dev/null
+From 75d56c8462a848ed3c39e319534f8fae4e60f4f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:54:09 -0700
+Subject: net/rds: rds_sendmsg should not discard payload_len
+
+From: Allison Henderson <achender@kernel.org>
+
+[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ]
+
+Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with
+connection teardown") modifies rds_sendmsg to avoid enqueueing work
+while a tear down is in progress. However, it also changed the return
+value of rds_sendmsg to that of rds_send_xmit instead of the
+payload_len. This means the user may incorrectly receive errno values
+when it should have simply received a payload of 0 while the peer
+attempts a reconnections. So this patch corrects the teardown handling
+code to only use the out error path in that case, thus restoring the
+original payload_len return value.
+
+Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/send.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/rds/send.c b/net/rds/send.c
+index 1923eaa91e939..131c59cd5abb0 100644
+--- a/net/rds/send.c
++++ b/net/rds/send.c
+@@ -1383,9 +1383,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
+ else
+ queue_delayed_work(rds_wq, &cpath->cp_send_w, 1);
+ rcu_read_unlock();
++
++ if (ret)
++ goto out;
+ }
+- if (ret)
+- goto out;
++
+ rds_message_put(rm);
+
+ for (ind = 0; ind < vct.indx; ind++)
+--
+2.51.0
+
--- /dev/null
+From 45b6cb1a2915c2c3bb322d998e66e2bcbd74ac33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 21:41:54 +0000
+Subject: net: usb: catc: enable basic endpoint checking
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ]
+
+catc_probe() fills three URBs with hardcoded endpoint pipes without
+verifying the endpoint descriptors:
+
+ - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX
+ - usb_rcvintpipe(usbdev, 2) for interrupt status
+
+A malformed USB device can present these endpoints with transfer types
+that differ from what the driver assumes.
+
+Add a catc_usb_ep enum for endpoint numbers, replacing magic constants
+throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints()
+calls after usb_set_interface() to verify endpoint types before use,
+rejecting devices with mismatched descriptors at probe time.
+
+Similar to
+- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking")
+which fixed the issue in rtl8150.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Suggested-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------
+ 1 file changed, 31 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
+index 6502f78aeddaa..38951608dc572 100644
+--- a/drivers/net/usb/catc.c
++++ b/drivers/net/usb/catc.c
+@@ -64,6 +64,16 @@ static const char driver_name[] = "catc";
+ #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */
+ #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */
+
++/*
++ * USB endpoints.
++ */
++
++enum catc_usb_ep {
++ CATC_USB_EP_CONTROL = 0,
++ CATC_USB_EP_BULK = 1,
++ CATC_USB_EP_INT_IN = 2,
++};
++
+ /*
+ * Control requests.
+ */
+@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ u8 broadcast[ETH_ALEN];
+ u8 *macbuf;
+ int pktsz, ret = -ENOMEM;
++ static const u8 bulk_ep_addr[] = {
++ CATC_USB_EP_BULK | USB_DIR_OUT,
++ CATC_USB_EP_BULK | USB_DIR_IN,
++ 0};
++ static const u8 int_ep_addr[] = {
++ CATC_USB_EP_INT_IN | USB_DIR_IN,
++ 0};
+
+ macbuf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if (!macbuf)
+@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ goto fail_mem;;
+ }
+
++ /* Verify that all required endpoints are present */
++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
++ !usb_check_int_endpoints(intf, int_ep_addr)) {
++ dev_err(dev, "Missing or invalid endpoints\n");
++ ret = -ENODEV;
++ goto fail_mem;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct catc));
+ if (!netdev)
+ goto fail_mem;
+@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0),
+ NULL, NULL, 0, catc_ctrl_done, catc);
+
+- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1),
+- NULL, 0, catc_tx_done, catc);
++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK),
++ NULL, 0, catc_tx_done, catc);
+
+- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1),
+- catc->rx_buf, pktsz, catc_rx_done, catc);
++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK),
++ catc->rx_buf, pktsz, catc_rx_done, catc);
+
+- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2),
+- catc->irq_buf, 2, catc_irq_done, catc, 1);
++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN),
++ catc->irq_buf, 2, catc_irq_done, catc, 1);
+
+ if (!catc->is_f5u011) {
+ u32 *buf;
+--
+2.51.0
+
--- /dev/null
+From 4cb8b4e0ed6745bf8cb1e15a94bcefe64cf41bcd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 12:53:09 +0100
+Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ]
+
+Mihail Milev reports: Error: UNINIT (CWE-457):
+ net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl:
+ Declaring variable "tuple" without initializer.
+ net/netfilter/nf_conntrack_h323_main.c:1197:2:
+ uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find".
+ net/netfilter/nf_conntrack_expect.c:142:2:
+ read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash".
+
+ 1195| tuple.dst.protonum = IPPROTO_TCP;
+ 1196|
+ 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ 1198| if (exp && exp->master == ct)
+ 1199| return exp;
+
+Switch this to a C99 initialiser and set the l3num value.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_h323_main.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
+index 8ba037b76ad3a..106dea9b53a96 100644
+--- a/net/netfilter/nf_conntrack_h323_main.c
++++ b/net/netfilter/nf_conntrack_h323_main.c
+@@ -1228,13 +1228,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
+ {
+ struct net *net = nf_ct_net(ct);
+ struct nf_conntrack_expect *exp;
+- struct nf_conntrack_tuple tuple;
++ struct nf_conntrack_tuple tuple = {
++ .src.l3num = nf_ct_l3num(ct),
++ .dst.protonum = IPPROTO_TCP,
++ .dst.u.tcp.port = port,
++ };
+
+- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3));
+- tuple.src.u.tcp.port = 0;
+ memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3));
+- tuple.dst.u.tcp.port = port;
+- tuple.dst.protonum = IPPROTO_TCP;
+
+ exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ if (exp && exp->master == ct)
+--
+2.51.0
+
--- /dev/null
+From c4db528aa9b7cd95633cbab0d45fc5b5a6148e96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Feb 2023 10:52:37 +0100
+Subject: selftests: forwarding: tc_actions: cleanup temporary files when test
+ is aborted
+
+From: Davide Caratti <dcaratti@redhat.com>
+
+[ Upstream commit f58531716ced8975a4ade108ef4af35f98722af7 ]
+
+remove temporary files created by 'mirred_egress_to_ingress_tcp' test
+in the cleanup() handler. Also, change variable names to avoid clashing
+with globals from lib.sh.
+
+Suggested-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Davide Caratti <dcaratti@redhat.com>
+Link: https://lore.kernel.org/r/091649045a017fc00095ecbb75884e5681f7025f.1676368027.git.dcaratti@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 32b70e62034a ("selftests: tc_actions: don't dump 2MB of \0 to stdout")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/net/forwarding/tc_actions.sh | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index 1e27031288c81..9c2aca8a4b8de 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -155,10 +155,10 @@ gact_trap_test()
+
+ mirred_egress_to_ingress_tcp_test()
+ {
+- local tmpfile=$(mktemp) tmpfile1=$(mktemp)
++ mirred_e2i_tf1=$(mktemp) mirred_e2i_tf2=$(mktemp)
+
+ RET=0
+- dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$tmpfile
++ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred_e2i_tf1
+ tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \
+ $tcflags ip_proto tcp src_ip 192.0.2.1 dst_ip 192.0.2.2 \
+ action ct commit nat src addr 192.0.2.2 pipe \
+@@ -174,11 +174,11 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $tmpfile1 &
++ ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
+ local rpid=$!
+- ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$tmpfile
++ ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+- cmp -s $tmpfile $tmpfile1
++ cmp -s $mirred_e2i_tf1 $mirred_e2i_tf2
+ check_err $? "server output check failed"
+
+ $MZ $h1 -c 10 -p 64 -a $h1mac -b $h1mac -A 192.0.2.1 -B 192.0.2.1 \
+@@ -195,7 +195,7 @@ mirred_egress_to_ingress_tcp_test()
+ tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower
+ tc filter del dev $h1 ingress protocol ip pref 102 handle 102 flower
+
+- rm -f $tmpfile $tmpfile1
++ rm -f $mirred_e2i_tf1 $mirred_e2i_tf2
+ log_test "mirred_egress_to_ingress_tcp ($tcflags)"
+ }
+
+@@ -224,6 +224,8 @@ setup_prepare()
+
+ cleanup()
+ {
++ local tf
++
+ pre_cleanup
+
+ switch_destroy
+@@ -234,6 +236,8 @@ cleanup()
+
+ ip link set $swp2 address $swp2origmac
+ ip link set $swp1 address $swp1origmac
++
++ for tf in $mirred_e2i_tf1 $mirred_e2i_tf2; do rm -f $tf; done
+ }
+
+ mirred_egress_redirect_test()
+--
+2.51.0
+
--- /dev/null
+From 755dfbf185cd561969fde6a82b938bf0299a8ad2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Aug 2023 17:14:57 +0300
+Subject: selftests: forwarding: tc_actions: Use ncat instead of nc
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 5e8670610b93158ffacc3241f835454ff26a3469 ]
+
+The test relies on 'nc' being the netcat version from the nmap project.
+While this seems to be the case on Fedora, it is not the case on Ubuntu,
+resulting in failures such as [1].
+
+Fix by explicitly using the 'ncat' utility from the nmap project and the
+skip the test in case it is not installed.
+
+[1]
+ # timeout set to 0
+ # selftests: net/forwarding: tc_actions.sh
+ # TEST: gact drop and ok (skip_hw) [ OK ]
+ # TEST: mirred egress flower redirect (skip_hw) [ OK ]
+ # TEST: mirred egress flower mirror (skip_hw) [ OK ]
+ # TEST: mirred egress matchall mirror (skip_hw) [ OK ]
+ # TEST: mirred_egress_to_ingress (skip_hw) [ OK ]
+ # nc: invalid option -- '-'
+ # usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl]
+ # [-m minttl] [-O length] [-P proxy_username] [-p source_port]
+ # [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit]
+ # [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]]
+ # [destination] [port]
+ # nc: invalid option -- '-'
+ # usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl]
+ # [-m minttl] [-O length] [-P proxy_username] [-p source_port]
+ # [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit]
+ # [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]]
+ # [destination] [port]
+ # TEST: mirred_egress_to_ingress_tcp (skip_hw) [FAIL]
+ # server output check failed
+ # INFO: Could not test offloaded functionality
+ not ok 80 selftests: net/forwarding: tc_actions.sh # exit=1
+
+Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress")
+Reported-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
+Closes: https://lore.kernel.org/netdev/adc5e40d-d040-a65e-eb26-edf47dac5b02@alu.unizg.hr/
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Tested-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
+Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
+Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
+Link: https://lore.kernel.org/r/20230808141503.4060661-12-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 32b70e62034a ("selftests: tc_actions: don't dump 2MB of \0 to stdout")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/tc_actions.sh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index 9c2aca8a4b8de..dd02ed4cacacb 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -8,6 +8,8 @@ NUM_NETIFS=4
+ source tc_common.sh
+ source lib.sh
+
++require_command ncat
++
+ tcflags="skip_hw"
+
+ h1_create()
+@@ -174,9 +176,9 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
+ local rpid=$!
+- ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
++ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+ cmp -s $mirred_e2i_tf1 $mirred_e2i_tf2
+ check_err $? "server output check failed"
+--
+2.51.0
+
--- /dev/null
+From 76eeb913022a8624ffff5c12cc0064712ab3e524 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:05 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with
+ br_netfilter enabled
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv4 packet contains a zero IP header checksum. After VXLAN
+decapsulation, such packets do not pass sanity checks in br_netfilter
+and are dropped, which causes the test to fail.
+
+Fix this by calculating and setting a valid IPv4 header checksum for the
+encapsulated packet generated by mausezahn, so that the packet is accepted
+by br_netfilter. Fixed by using the payload_template_calc_checksum() /
+payload_template_expand_checksum() helpers that are only available
+in v6.3 and newer kernels.
+
+Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++-------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+index 0ccb1dda099ae..446e31477491c 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+@@ -559,6 +559,21 @@ vxlan_encapped_ping_do()
+ local inner_tos=$1; shift
+ local outer_tos=$1; shift
+
++ local ipv4hdr=$(:
++ )"45:"$( : IP version + IHL
++ )"$inner_tos:"$( : IP TOS
++ )"00:54:"$( : IP total length
++ )"99:83:"$( : IP identification
++ )"40:00:"$( : IP flags + frag off
++ )"40:"$( : IP TTL
++ )"01:"$( : IP proto
++ )"CHECKSUM:"$( : IP header csum
++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1
++ )
++ local checksum=$(payload_template_calc_checksum "$ipv4hdr")
++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum)
++
+ $MZ $dev -c $count -d 100msec -q \
+ -b $next_hop_mac -B $dest_ip \
+ -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(:
+@@ -569,16 +584,7 @@ vxlan_encapped_ping_do()
+ )"$dest_mac:"$( : ETH daddr
+ )"$(mac_get w2):"$( : ETH saddr
+ )"08:00:"$( : ETH type
+- )"45:"$( : IP version + IHL
+- )"$inner_tos:"$( : IP TOS
+- )"00:54:"$( : IP total length
+- )"99:83:"$( : IP identification
+- )"40:00:"$( : IP flags + frag off
+- )"40:"$( : IP TTL
+- )"01:"$( : IP proto
+- )"00:00:"$( : IP header csum
+- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
+- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1
++ )"$ipv4hdr:"$( : IPv4 header
+ )"08:"$( : ICMP type
+ )"00:"$( : ICMP code
+ )"8b:f2:"$( : ICMP csum
+--
+2.51.0
+
--- /dev/null
+From a672e0850f7feb5bd7294371491ab45331459178 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 14:53:53 +0100
+Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ]
+
+As explained in [1], iproute2 started rejecting tc-police burst sizes
+that result in an overflow. This can happen when the burst size is high
+enough and the rate is low enough.
+
+A couple of test cases specify such configurations, resulting in
+iproute2 errors and test failure.
+
+Fix by reducing the burst size so that the test will pass with both new
+and old iproute2 versions.
+
+[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/
+
+Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+index 553cb9fad5084..9547c0992d423 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+@@ -297,7 +297,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 0.5kbit burst 1m conform-exceed drop/ok
++ action police rate 0.5kbit burst 2k conform-exceed drop/ok
+ check_fail $? "Incorrect success to add police action with too low rate"
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+@@ -307,7 +307,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 1.5kbit burst 1m conform-exceed drop/ok
++ action police rate 1.5kbit burst 2k conform-exceed drop/ok
+ check_err $? "Failed to add police action with low rate"
+
+ tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
+--
+2.51.0
+
--- /dev/null
+From b75d703070e22b63b6d5cb86117b799e261bd121 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 19:51:59 -0800
+Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ]
+
+Since we started running selftests in NIPA we have been seeing
+tc_actions.sh generate a soft lockup warning on ~20% of the runs.
+On the pre-netdev foundation setup it was actually a missed irq
+splat from the console. Now it's either that or a lockup.
+
+I initially suspected a socket locking issue since the test
+is exercising local loopback with act_mirred.
+After hours of staring at this I noticed in strace that ncat
+when -o $file is specified _both_ saves the output to the file
+and still prints it to stdout. Because the file being sent
+is constructed with:
+
+ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred
+ ^^^^^^^^^
+
+the data printed is all \0. Most terminals don't display nul
+characters (and neither does vng output capture save them).
+But QEMU's serial console still has to poke them thru which
+is very slow and causes the lockup (if the file is >600kB).
+
+Replace the '-o $file' with '> $file'. This speeds the test up
+from 2m20s to 18s on debug kernels, and prevents the warnings.
+
+Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index dd02ed4cacacb..c25aaced2e1f0 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -176,7 +176,7 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 &
+ local rpid=$!
+ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+--
+2.51.0
+
ovl-fix-uninit-value-in-ovl_fill_real.patch
iio-sca3000-fix-a-resource-leak-in-sca3000_probe.patch
pinctrl-single-fix-refcount-leak-in-pcs_add_gpio_fun.patch
+cpuidle-skip-governor-when-only-one-idle-state-is-av.patch
+selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch
+usbb-catc-use-correct-api-for-mac-addresses.patch
+net-usb-catc-enable-basic-endpoint-checking.patch
+xen-netback-reject-zero-queue-configuration-from-gue.patch
+net-rds-rds_sendmsg-should-not-discard-payload_len.patch
+selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch
+netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch
+ipv6-fix-a-race-in-ip6_sock_set_v6only.patch
+selftests-forwarding-tc_actions-cleanup-temporary-fi.patch
+selftests-forwarding-tc_actions-use-ncat-instead-of-.patch
+selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch
+macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch
+bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch
+apparmor-fix-null-sock-in-aa_sock_file_perm.patch
+apparmor-fix-rlimit-for-posix-cpu-timers.patch
+apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch
+drm-i915-acpi-free-_dsm-package-when-no-connectors.patch
+btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch
--- /dev/null
+From c6e39422ee01a2b50e676bf8e257a43be0c48974 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 Oct 2021 16:11:21 +0200
+Subject: usbb: catc: use correct API for MAC addresses
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 7ce9a701ac8f44798e46dede02b924504dc65a5c ]
+
+Commit 406f42fa0d3c ("net-next: When a bond have a massive amount
+of VLANs...") introduced a rbtree for faster Ethernet address look
+up. To maintain netdev->dev_addr in this tree we need to make all
+the writes to it got through appropriate helpers.
+
+In the case of catc we need a new temporary buffer to conform
+to the rules for DMA coherency. That in turn necessitates
+a reworking of error handling in probe().
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 9e7021d2aeae ("net: usb: catc: enable basic endpoint checking")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/catc.c | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
+index 97ba67042d126..6502f78aeddaa 100644
+--- a/drivers/net/usb/catc.c
++++ b/drivers/net/usb/catc.c
+@@ -770,17 +770,23 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ struct net_device *netdev;
+ struct catc *catc;
+ u8 broadcast[ETH_ALEN];
+- int pktsz, ret;
++ u8 *macbuf;
++ int pktsz, ret = -ENOMEM;
++
++ macbuf = kmalloc(ETH_ALEN, GFP_KERNEL);
++ if (!macbuf)
++ goto error;
+
+ if (usb_set_interface(usbdev,
+ intf->altsetting->desc.bInterfaceNumber, 1)) {
+ dev_err(dev, "Can't set altsetting 1.\n");
+- return -EIO;
++ ret = -EIO;
++ goto fail_mem;;
+ }
+
+ netdev = alloc_etherdev(sizeof(struct catc));
+ if (!netdev)
+- return -ENOMEM;
++ goto fail_mem;
+
+ catc = netdev_priv(netdev);
+
+@@ -870,7 +876,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+
+ dev_dbg(dev, "Getting MAC from SEEROM.\n");
+
+- catc_get_mac(catc, netdev->dev_addr);
++ catc_get_mac(catc, macbuf);
++ eth_hw_addr_set(netdev, macbuf);
+
+ dev_dbg(dev, "Setting MAC into registers.\n");
+
+@@ -899,7 +906,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ } else {
+ dev_dbg(dev, "Performing reset\n");
+ catc_reset(catc);
+- catc_get_mac(catc, netdev->dev_addr);
++ catc_get_mac(catc, macbuf);
++ eth_hw_addr_set(netdev, macbuf);
+
+ dev_dbg(dev, "Setting RX Mode\n");
+ catc->rxmode[0] = RxEnable | RxPolarity | RxMultiCast;
+@@ -917,6 +925,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ if (ret)
+ goto fail_clear_intfdata;
+
++ kfree(macbuf);
+ return 0;
+
+ fail_clear_intfdata:
+@@ -927,6 +936,9 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ usb_free_urb(catc->rx_urb);
+ usb_free_urb(catc->irq_urb);
+ free_netdev(netdev);
++fail_mem:
++ kfree(macbuf);
++error:
+ return ret;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 377e986902357b29e2ecc9f719b2f2fde237fdb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 22:40:40 +0000
+Subject: xen-netback: reject zero-queue configuration from guest
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ]
+
+A malicious or buggy Xen guest can write "0" to the xenbus key
+"multi-queue-num-queues". The connect() function in the backend only
+validates the upper bound (requested_num_queues > xenvif_max_queues)
+but not zero, allowing requested_num_queues=0 to reach
+vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers
+WARN_ON_ONCE(!size) in __vmalloc_node_range().
+
+On systems with panic_on_warn=1, this allows a guest-to-host denial
+of service.
+
+The Xen network interface specification requires
+the queue count to be "greater than zero".
+
+Add a zero check to match the validation already present
+in xen-blkback, which has included this
+guard since its multi-queue support was added.
+
+Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/xen-netback/xenbus.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
+index 9ee9ce0493fe6..c47e327039a0a 100644
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -735,10 +735,11 @@ static void connect(struct backend_info *be)
+ */
+ requested_num_queues = xenbus_read_unsigned(dev->otherend,
+ "multi-queue-num-queues", 1);
+- if (requested_num_queues > xenvif_max_queues) {
++ if (requested_num_queues > xenvif_max_queues ||
++ requested_num_queues == 0) {
+ /* buggy or malicious guest */
+ xenbus_dev_fatal(dev, -EINVAL,
+- "guest requested %u queues, exceeding the maximum of %u.",
++ "guest requested %u queues, but valid range is 1 - %u.",
+ requested_num_queues, xenvif_max_queues);
+ return;
+ }
+--
+2.51.0
+
--- /dev/null
+From ceedd9d1ed7f1cda572ab188ead9141d79863c88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 21:22:54 +0000
+Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs
+
+From: Sean V Kelley <skelley@nvidia.com>
+
+[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all
+possible CPUs. In acpi_get_psd_map(), encountering an offline CPU
+returns -EFAULT, causing cppc_cpufreq initialization to fail.
+
+This breaks systems booted with "nosmt" or "nosmt=force".
+
+Fix by using for_each_online_cpu() in both functions.
+
+Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests")
+Signed-off-by: Sean V Kelley <skelley@nvidia.com>
+Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 0387b293ea76a..572d4d3815fae 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -336,7 +336,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
+ end:
+ if (cmd == CMD_WRITE) {
+ if (unlikely(ret)) {
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i);
+
+ if (!desc)
+@@ -477,7 +477,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data)
+ else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
+ cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ if (i == cpu)
+ continue;
+
+--
+2.51.0
+
--- /dev/null
+From f16de7c17c35be9d64ba6d7e839efb43fb90e73b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 15:58:45 -0300
+Subject: apparmor: fix invalid deref of rawdata when export_binary is unset
+
+From: Georgia Garcia <georgia.garcia@canonical.com>
+
+[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ]
+
+If the export_binary parameter is disabled on runtime, profiles that
+were loaded before that will still have their rawdata stored in
+apparmorfs, with a symbolic link to the rawdata on the policy
+directory. When one of those profiles are replaced, the rawdata is set
+to NULL, but when trying to resolve the symbolic links to rawdata for
+that profile, it will try to dereference profile->rawdata->name when
+profile->rawdata is now NULL causing an oops. Fix it by checking if
+rawdata is set.
+
+[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088
+[ 168.657420] #PF: supervisor read access in kernel mode
+[ 168.660619] #PF: error_code(0x0000) - not-present page
+[ 168.663613] PGD 0 P4D 0
+[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI
+[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary)
+[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330
+[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8
+[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282
+[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158
+[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80
+[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000
+[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80
+[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0
+[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000
+[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0
+[ 168.701696] Call Trace:
+[ 168.702325] <TASK>
+[ 168.702995] rawdata_get_link_data+0x1c/0x30
+[ 168.704145] vfs_readlink+0xd4/0x160
+[ 168.705152] do_readlinkat+0x114/0x180
+[ 168.706214] __x64_sys_readlink+0x1e/0x30
+[ 168.708653] x64_sys_call+0x1d77/0x26b0
+[ 168.709525] do_syscall_64+0x81/0x500
+[ 168.710348] ? do_statx+0x72/0xb0
+[ 168.711109] ? putname+0x3e/0x80
+[ 168.711845] ? __x64_sys_statx+0xb7/0x100
+[ 168.712711] ? x64_sys_call+0x10fc/0x26b0
+[ 168.713577] ? do_syscall_64+0xbf/0x500
+[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0
+[ 168.715404] ? irqentry_exit+0xb2/0x740
+[ 168.716359] ? exc_page_fault+0x90/0x1b0
+[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement")
+Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/apparmorfs.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index c70b86f17124a..bd822f13e3253 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -1618,6 +1618,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry,
+
+ label = aa_get_label_rcu(&proxy->label);
+ profile = labels_profile(label);
++
++ /* rawdata can be null when aa_g_export_binary is unset during
++ * runtime and a profile is replaced
++ */
++ if (!profile->rawdata) {
++ aa_put_label(label);
++ return ERR_PTR(-ENOENT);
++ }
++
+ depth = profile_depth(profile);
+ target = gen_symlink_name(depth, profile->rawdata->name, name);
+ aa_put_label(label);
+--
+2.51.0
+
--- /dev/null
+From 74ed46eb7da8880d97f41884181ec65039077dca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 15:07:42 -0800
+Subject: apparmor: fix NULL sock in aa_sock_file_perm
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ]
+
+Deal with the potential that sock and sock-sk can be NULL during
+socket setup or teardown. This could lead to an oops. The fix for NULL
+pointer dereference in __unix_needs_revalidation shows this is at
+least possible for af_unix sockets. While the fix for af_unix sockets
+applies for newer mediation this is still the fall back path for older
+af_unix mediation and other sockets, so ensure it is covered.
+
+Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/net.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index e0c1b50d6eddc..abdce5e52b026 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -182,8 +182,10 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
+ struct socket *sock)
+ {
+ AA_BUG(!label);
+- AA_BUG(!sock);
+- AA_BUG(!sock->sk);
++
++ /* sock && sock->sk can be NULL for sockets being set up or torn down */
++ if (!sock || !sock->sk)
++ return 0;
+
+ return aa_label_sk_perm(label, op, request, sock->sk);
+ }
+--
+2.51.0
+
--- /dev/null
+From dc22d9e5476a1b936f1cb77652579d8c741d2ceb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:16:54 -0800
+Subject: apparmor: fix rlimit for posix cpu timers
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ]
+
+Posix cpu timers requires an additional step beyond setting the rlimit.
+Refactor the code so its clear when what code is setting the
+limit and conditionally update the posix cpu timers when appropriate.
+
+Fixes: baa73d9e478ff ("posix-timers: Make them configurable")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/resource.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index 1ae4874251a96..f94e416399441 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -182,6 +182,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
+ new->rlimits.limits[j].rlim_max);
+ /* soft limit should not exceed hard limit */
+ rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
++ if (j == RLIMIT_CPU &&
++ rlim->rlim_cur != RLIM_INFINITY &&
++ IS_ENABLED(CONFIG_POSIX_TIMERS))
++ (void) update_rlimit_cpu(current->group_leader,
++ rlim->rlim_cur);
+ }
+ }
+ }
+--
+2.51.0
+
--- /dev/null
+From e9e6b8403db314958ee9356134d1830f3c9e16cb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 18:57:14 +0000
+Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ]
+
+This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()").
+
+The original patch attempted to acquire the card->controls_rwsem lock in
+fsl_xcvr_mode_put(). However, this function is called from the upper ALSA
+core function snd_ctl_elem_write(), which already holds the write lock on
+controls_rwsem for the whole put operation. So there is no need to simply
+hold the lock for fsl_xcvr_activate_ctl() again.
+
+Acquiring the read lock while holding the write lock in the same thread
+results in a deadlock and a hung task, as reported by Alexander Stein.
+
+Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()")
+Reported-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_xcvr.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
+index c4deb09c9a9bc..ae5960b2b6a95 100644
+--- a/sound/soc/fsl/fsl_xcvr.c
++++ b/sound/soc/fsl/fsl_xcvr.c
+@@ -203,13 +203,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,
+
+ xcvr->mode = snd_soc_enum_item_to_val(e, item[0]);
+
+- down_read(&card->snd_card->controls_rwsem);
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_ARC));
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_EARC));
+- up_read(&card->snd_card->controls_rwsem);
+-
+ /* Allow playback for SPDIF only */
+ rtd = snd_soc_get_pcm_runtime(card, card->dai_link);
+ rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
+--
+2.51.0
+
--- /dev/null
+From bad74ff3e98960478dddc6604fd593027b166ff7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 06:09:19 +0000
+Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ]
+
+The ALB RX path may access rx_hashtbl concurrently with bond
+teardown. During rapid bond up/down cycles, rlb_deinitialize()
+frees rx_hashtbl while RX handlers are still running, leading
+to a null pointer dereference detected by KASAN.
+
+However, the root cause is that rlb_arp_recv() can still be accessed
+after setting recv_probe to NULL, which is actually a use-after-free
+(UAF) issue. That is the reason for using the referenced commit in the
+Fixes tag.
+
+[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI
+[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef]
+[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary)
+[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022
+[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding]
+[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6
+ 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00
+[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206
+[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e
+[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8
+[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8
+[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119
+[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810
+[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000
+[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0
+[ 214.310347] Call Trace:
+[ 214.313070] <IRQ>
+[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding]
+[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding]
+[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding]
+[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710
+[ 214.339199] ? __pfx_arp_process+0x10/0x10
+[ 214.343775] ? sched_balance_find_src_group+0x98/0x630
+[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10
+[ 214.356513] ? arp_rcv+0x307/0x690
+[ 214.360311] ? __pfx_arp_rcv+0x10/0x10
+[ 214.364499] ? __lock_acquire+0x58c/0xbd0
+[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0
+[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10
+[ 214.380743] ? lock_acquire+0x10b/0x140
+[ 214.385026] process_backlog+0x3f1/0x13a0
+[ 214.389502] ? process_backlog+0x3aa/0x13a0
+[ 214.394174] __napi_poll.constprop.0+0x9f/0x370
+[ 214.399233] net_rx_action+0x8c1/0xe60
+[ 214.403423] ? __pfx_net_rx_action+0x10/0x10
+[ 214.408193] ? lock_acquire.part.0+0xbd/0x260
+[ 214.413058] ? sched_clock_cpu+0x6c/0x540
+[ 214.417540] ? mark_held_locks+0x40/0x70
+[ 214.421920] handle_softirqs+0x1fd/0x860
+[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10
+[ 214.431264] ? __neigh_event_send+0x2d6/0xf50
+[ 214.436131] do_softirq+0xb1/0xf0
+[ 214.439830] </IRQ>
+
+The issue is reproducible by repeatedly running
+ip link set bond0 up/down while receiving ARP messages, where
+rlb_arp_recv() can race with rlb_deinitialize() and dereference
+a freed rx_hashtbl entry.
+
+Fix this by setting recv_probe to NULL and then calling
+synchronize_net() to wait for any concurrent RX processing to finish.
+This ensures that no RX handler can access rx_hashtbl after it is freed
+in bond_alb_deinitialize().
+
+Reported-by: Liang Li <liali@redhat.com>
+Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 27ed164375411..1323a619db4d2 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4024,9 +4024,13 @@ static int bond_close(struct net_device *bond_dev)
+
+ bond_work_cancel_all(bond);
+ bond->send_peer_notif = 0;
++ WRITE_ONCE(bond->recv_probe, NULL);
++
++ /* Wait for any in-flight RX handlers */
++ synchronize_net();
++
+ if (bond_is_lb(bond))
+ bond_alb_deinitialize(bond);
+- bond->recv_probe = NULL;
+
+ if (bond_uses_primary(bond)) {
+ rcu_read_lock();
+--
+2.51.0
+
--- /dev/null
+From d3ee73b60d9a4330582c409d842e0b90afdabc45 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 11:41:50 -0800
+Subject: bpftool: Fix truncated netlink dumps
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ]
+
+Netlink requires that the recv buffer used during dumps is at least
+min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will
+get truncated. Make sure bpftool follows this requirement, avoid
+missing information on systems with large pages.
+
+Acked-by: Quentin Monnet <qmo@kernel.org>
+Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/net.c | 5 ++++-
+ tools/lib/bpf/netlink.c | 4 +++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c
+index 18e5e5faa2aa2..ef7fe8dd50984 100644
+--- a/tools/bpf/bpftool/net.c
++++ b/tools/bpf/bpftool/net.c
+@@ -143,7 +143,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ bool multipart = true;
+ struct nlmsgerr *err;
+ struct nlmsghdr *nh;
+- char buf[4096];
++ char buf[8192];
+ int len, ret;
+
+ while (multipart) {
+@@ -188,6 +188,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ return ret;
+ }
+ }
++
++ if (len)
++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len);
+ }
+ ret = 0;
+ done:
+diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
+index fadde7d80a51c..00ba40b0a57e2 100644
+--- a/tools/lib/bpf/netlink.c
++++ b/tools/lib/bpf/netlink.c
+@@ -127,7 +127,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ struct nlmsghdr *nh;
+ int len, ret;
+
+- ret = alloc_iov(&iov, 4096);
++ ret = alloc_iov(&iov, 8192);
+ if (ret)
+ goto done;
+
+@@ -196,6 +196,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ }
+ }
+ }
++ if (len)
++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len);
+ }
+ ret = 0;
+ done:
+--
+2.51.0
+
--- /dev/null
+From 885307b3a1f27cc4a6909539bc491d7c9d978c32 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 17:15:53 +0000
+Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not
+ found
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ]
+
+If btrfs_search_slot_for_read() returns 1, it means we did not find any
+key greater than or equals to the key we asked for, meaning we have
+reached the end of the tree and therefore the path is not valid. If
+this happens we need to break out of the loop and stop, instead of
+continuing and accessing an invalid path.
+
+Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/qgroup.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index 4593ca523490f..208c6813dc681 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1089,11 +1089,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
+ }
+ if (ret > 0) {
+ /*
+- * Shouldn't happen, but in case it does we
+- * don't need to do the btrfs_next_item, just
+- * continue.
++ * Shouldn't happen because the key should still
++ * be there (return 0), but in case it does it
++ * means we have reached the end of the tree -
++ * there are no more leaves with items that have
++ * a key greater than or equals to @found_key,
++ * so just stop the search loop.
+ */
+- continue;
++ break;
+ }
+ }
+ ret = btrfs_next_item(tree_root, path);
+--
+2.51.0
+
--- /dev/null
+From 29ab61ff586e9f7aec9443e5c8efa9312939ec6d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 00:20:02 +0530
+Subject: cpuidle: Skip governor when only one idle state is available
+
+From: Aboorva Devarajan <aboorvad@linux.ibm.com>
+
+[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ]
+
+On certain platforms (PowerNV systems without a power-mgt DT node),
+cpuidle may register only a single idle state. In cases where that
+single state is a polling state (state 0), the ladder governor may
+incorrectly treat state 1 as the first usable state and pass an
+out-of-bounds index. This can lead to a NULL enter callback being
+invoked, ultimately resulting in a system crash.
+
+[ 13.342636] cpuidle-powernv : Only Snooze is available
+[ 13.351854] Faulting instruction address: 0x00000000
+[ 13.376489] NIP [0000000000000000] 0x0
+[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668
+
+Fix this by adding a bail-out in cpuidle_select() that returns state 0
+directly when state_count <= 1, bypassing the governor and keeping the
+tick running.
+
+Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol")
+Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
+Reviewed-by: Christian Loehle <christian.loehle@arm.com>
+Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/cpuidle.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
+index e371d6972f8d9..20b9f77a8fb02 100644
+--- a/drivers/cpuidle/cpuidle.c
++++ b/drivers/cpuidle/cpuidle.c
+@@ -319,6 +319,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
+ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+ bool *stop_tick)
+ {
++ /*
++ * If there is only a single idle state (or none), there is nothing
++ * meaningful for the governor to choose. Skip the governor and
++ * always use state 0 with the tick running.
++ */
++ if (drv->state_count <= 1) {
++ *stop_tick = false;
++ return 0;
++ }
++
+ return cpuidle_curr_governor->select(drv, dev, stop_tick);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 0bfb19d035026bf62803e035c73cd0e583454c3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jan 2026 08:55:49 +0530
+Subject: drm/i915/acpi: free _DSM package when no connectors
+
+From: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+
+[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ]
+
+acpi_evaluate_dsm_typed() returns an ACPI package in pkg.
+When pkg->package.count == 0, we returned without freeing pkg,
+leaking memory. Free pkg before returning on the empty case.
+
+Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_acpi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c
+index 68abeaf2d7d4d..63c046cdbad6c 100644
+--- a/drivers/gpu/drm/i915/display/intel_acpi.c
++++ b/drivers/gpu/drm/i915/display/intel_acpi.c
+@@ -92,6 +92,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle)
+
+ if (!pkg->package.count) {
+ DRM_DEBUG_DRIVER("no connection in _DSM\n");
++ ACPI_FREE(pkg);
+ return;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 7cf13b7ca1f15590f7c9cae004bde438454e64a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jan 2026 16:50:24 +0000
+Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot
+
+From: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+
+[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ]
+
+In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the
+entry size ('esize') is retrieved from the log record without adequate
+bounds checking.
+
+Specifically, the code calculates the end of the entry ('e2') using:
+ e2 = Add2Ptr(e1, esize);
+
+It then calculates the size for memmove using 'PtrOffset(e2, ...)',
+which subtracts the end pointer from the buffer limit. If 'esize' is
+maliciously large, 'e2' exceeds the used buffer size. This results in
+a negative offset which, when cast to size_t for memmove, interprets
+as a massive unsigned integer, leading to a heap buffer overflow.
+
+This commit adds a check to ensure that the entry size ('esize') strictly
+fits within the remaining used space of the index header before performing
+memory operations.
+
+Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
+Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/fslog.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
+index 6fddedca71f32..d3d006b63b27e 100644
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -3434,6 +3434,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe,
+
+ e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off));
+ esize = le16_to_cpu(e1->size);
++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize)
++ goto dirty_vol;
++
+ e2 = Add2Ptr(e1, esize);
+
+ memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used)));
+--
+2.51.0
+
--- /dev/null
+From f4e6dfe6db8f3b51e290b18c9e07f54ba26157ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Dec 2025 11:53:25 +0800
+Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the
+ same
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ]
+
+When processing valid within the range [valid : pos), if valid cannot
+be retrieved correctly, for example, if the retrieved valid value is
+always the same, this can trigger a potential infinite loop, similar
+to the hung problem reported by syzbot [1].
+
+Adding a check for the valid value within the loop body, and terminating
+the loop and returning -EINVAL if the value is the same as the current
+value, can prevent this.
+
+[1]
+INFO: task syz.4.21:6056 blocked for more than 143 seconds.
+Call Trace:
+ rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244
+ inode_lock include/linux/fs.h:1027 [inline]
+ ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284
+
+Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
+Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/file.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index ffb31420085f4..25788df25deeb 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -932,8 +932,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from)
+ goto out;
+
+ if (lcn == SPARSE_LCN) {
+- ni->i_valid = valid =
+- frame_vbo + ((u64)clen << sbi->cluster_bits);
++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits);
++ if (ni->i_valid == valid) {
++ err = -EINVAL;
++ goto out;
++ }
++ ni->i_valid = valid;
+ continue;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From ceba0f3b24ea7a45584471a73c8d08a7e12be70c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:22:02 +0000
+Subject: ipv6: fix a race in ip6_sock_set_v6only()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ]
+
+It is unlikely that this function will be ever called
+with isk->inet_num being not zero.
+
+Perform the check on isk->inet_num inside the locked section
+for complete safety.
+
+Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ipv6.h | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index 608943944ce1a..dcae37154d3c2 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -1186,12 +1186,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
+
+ static inline int ip6_sock_set_v6only(struct sock *sk)
+ {
+- if (inet_sk(sk)->inet_num)
+- return -EINVAL;
++ int ret = 0;
++
+ lock_sock(sk);
+- sk->sk_ipv6only = true;
++ if (inet_sk(sk)->inet_num)
++ ret = -EINVAL;
++ else
++ sk->sk_ipv6only = true;
+ release_sock(sk);
+- return 0;
++ return ret;
+ }
+
+ static inline void ip6_sock_set_recverr(struct sock *sk)
+--
+2.51.0
+
--- /dev/null
+From 48f4fff82b1fca88ec72a9b94544688dc0ff7499 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:25:57 +0000
+Subject: macvlan: observe an RCU grace period in macvlan_common_newlink()
+ error path
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ]
+
+valis reported that a race condition still happens after my prior patch.
+
+macvlan_common_newlink() might have made @dev visible before
+detecting an error, and its caller will directly call free_netdev(dev).
+
+We must respect an RCU period, either in macvlan or the core networking
+stack.
+
+After adding a temporary mdelay(1000) in macvlan_forward_source_one()
+to open the race window, valis repro was:
+
+ip link add p1 type veth peer p2
+ip link set address 00:00:00:00:00:20 dev p1
+ip link set up dev p1
+ip link set up dev p2
+ip link add mv0 link p2 type macvlan mode source
+
+(ip link add invalid% link p2 type macvlan mode source macaddr add
+00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4
+PING 1.2.3.4 (1.2.3.4): 56 data bytes
+RTNETLINK answers: Invalid argument
+
+BUG: KASAN: slab-use-after-free in macvlan_forward_source
+(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+Read of size 8 at addr ffff888016bb89c0 by task e/175
+
+CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
+Call Trace:
+<IRQ>
+dump_stack_lvl (lib/dump_stack.c:123)
+print_report (mm/kasan/report.c:379 mm/kasan/report.c:482)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+kasan_report (mm/kasan/report.c:597)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+? tasklet_init (kernel/softirq.c:983)
+macvlan_handle_frame (drivers/net/macvlan.c:501)
+
+Allocated by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+__kasan_kmalloc (mm/kasan/common.c:419)
+__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657
+mm/slub.c:7140)
+alloc_netdev_mqs (net/core/dev.c:12012)
+rtnl_create_link (net/core/rtnetlink.c:3648)
+rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Freed by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+kasan_save_free_info (mm/kasan/generic.c:587)
+__kasan_slab_free (mm/kasan/common.c:287)
+kfree (mm/slub.c:6674 mm/slub.c:6882)
+rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: valis <sec@valis.email>
+Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macvlan.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index e92d7f2f28c17..f2fb958c1f232 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1532,6 +1532,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
+ if (create)
+ macvlan_port_destroy(port->dev);
+ }
++ /* @dev might have been made visible before an error was detected.
++ * Make sure to observe an RCU grace period before our caller
++ * (rtnl_newlink()) frees it.
++ */
++ synchronize_net();
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(macvlan_common_newlink);
+--
+2.51.0
+
--- /dev/null
+From 477499c4cd9cec5876ff062386e41bfa72881f10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:54:09 -0700
+Subject: net/rds: rds_sendmsg should not discard payload_len
+
+From: Allison Henderson <achender@kernel.org>
+
+[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ]
+
+Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with
+connection teardown") modifies rds_sendmsg to avoid enqueueing work
+while a tear down is in progress. However, it also changed the return
+value of rds_sendmsg to that of rds_send_xmit instead of the
+payload_len. This means the user may incorrectly receive errno values
+when it should have simply received a payload of 0 while the peer
+attempts a reconnections. So this patch corrects the teardown handling
+code to only use the out error path in that case, thus restoring the
+original payload_len return value.
+
+Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/send.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/rds/send.c b/net/rds/send.c
+index 85c27d9aa33a3..9a23f8f2bcfa7 100644
+--- a/net/rds/send.c
++++ b/net/rds/send.c
+@@ -1383,9 +1383,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
+ else
+ queue_delayed_work(rds_wq, &cpath->cp_send_w, 1);
+ rcu_read_unlock();
++
++ if (ret)
++ goto out;
+ }
+- if (ret)
+- goto out;
++
+ rds_message_put(rm);
+
+ for (ind = 0; ind < vct.indx; ind++)
+--
+2.51.0
+
--- /dev/null
+From 0bd08e52b1ed05f785056a0269d88b24ea74e8ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 12:56:39 +0100
+Subject: net: remove WARN_ON_ONCE when accessing forward path array
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ]
+
+Although unlikely, recent support for IPIP tunnels increases chances of
+reaching this WARN_ON_ONCE if userspace manages to build a sufficiently
+long forward path.
+
+Remove it.
+
+Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 977146a70b8c1..48abe997e6f3b 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -750,7 +750,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack)
+ {
+ int k = stack->num_paths++;
+
+- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX))
++ if (k >= NET_DEVICE_PATH_STACK_MAX)
+ return NULL;
+
+ return &stack->path[k];
+--
+2.51.0
+
--- /dev/null
+From 7f7cf2f6096e331f231caf5442bbdf17c37f0baa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 12:53:09 +0100
+Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ]
+
+Mihail Milev reports: Error: UNINIT (CWE-457):
+ net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl:
+ Declaring variable "tuple" without initializer.
+ net/netfilter/nf_conntrack_h323_main.c:1197:2:
+ uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find".
+ net/netfilter/nf_conntrack_expect.c:142:2:
+ read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash".
+
+ 1195| tuple.dst.protonum = IPPROTO_TCP;
+ 1196|
+ 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ 1198| if (exp && exp->master == ct)
+ 1199| return exp;
+
+Switch this to a C99 initialiser and set the l3num value.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_h323_main.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
+index 2eb31ffb3d141..b479dc148d7bf 100644
+--- a/net/netfilter/nf_conntrack_h323_main.c
++++ b/net/netfilter/nf_conntrack_h323_main.c
+@@ -1229,13 +1229,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
+ {
+ struct net *net = nf_ct_net(ct);
+ struct nf_conntrack_expect *exp;
+- struct nf_conntrack_tuple tuple;
++ struct nf_conntrack_tuple tuple = {
++ .src.l3num = nf_ct_l3num(ct),
++ .dst.protonum = IPPROTO_TCP,
++ .dst.u.tcp.port = port,
++ };
+
+- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3));
+- tuple.src.u.tcp.port = 0;
+ memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3));
+- tuple.dst.u.tcp.port = port;
+- tuple.dst.protonum = IPPROTO_TCP;
+
+ exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ if (exp && exp->master == ct)
+--
+2.51.0
+
--- /dev/null
+From 54d6c02ae2f33ba5a72619db201fc3c76b41a593 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:33:38 +0530
+Subject: octeontx2-af: Fix default entries mcam entry action
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ]
+
+As per design, AF should update the default MCAM action only when
+mcam_index is -1. A bug in the previous patch caused default entries
+to be changed even when the request was not for them.
+
+Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++---------
+ 1 file changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+index 84003243e3b75..ddc2879d81f35 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+@@ -1047,32 +1047,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
+ rvu_write64(rvu, blkaddr,
+ NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action);
+
+- /* update the VF flow rule action with the VF default entry action */
+- if (mcam_index < 0)
+- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
+- *(u64 *)&action);
+-
+ /* update the action change in default rule */
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+ if (pfvf->def_ucast_rule)
+ pfvf->def_ucast_rule->rx_action = action;
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_PROMISC_ENTRY);
++ if (mcam_index < 0) {
++ /* update the VF flow rule action with the VF default
++ * entry action
++ */
++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
++ *(u64 *)&action);
+
+- /* If PF's promiscuous entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_PROMISC_ENTRY);
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_ALLMULTI_ENTRY);
+- /* If PF's allmulti entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ /* If PF's promiscuous entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_ALLMULTI_ENTRY);
++ /* If PF's allmulti entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++ }
+ }
+
+ void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc,
+--
+2.51.0
+
--- /dev/null
+From 7b75c7643c5e1456760a2ce3863ba7f879c7661b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:05 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with
+ br_netfilter enabled
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv4 packet contains a zero IP header checksum. After VXLAN
+decapsulation, such packets do not pass sanity checks in br_netfilter
+and are dropped, which causes the test to fail.
+
+Fix this by calculating and setting a valid IPv4 header checksum for the
+encapsulated packet generated by mausezahn, so that the packet is accepted
+by br_netfilter. Fixed by using the payload_template_calc_checksum() /
+payload_template_expand_checksum() helpers that are only available
+in v6.3 and newer kernels.
+
+Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++-------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+index eb307ca37bfa6..002551451a728 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+@@ -559,6 +559,21 @@ vxlan_encapped_ping_do()
+ local inner_tos=$1; shift
+ local outer_tos=$1; shift
+
++ local ipv4hdr=$(:
++ )"45:"$( : IP version + IHL
++ )"$inner_tos:"$( : IP TOS
++ )"00:54:"$( : IP total length
++ )"99:83:"$( : IP identification
++ )"40:00:"$( : IP flags + frag off
++ )"40:"$( : IP TTL
++ )"01:"$( : IP proto
++ )"CHECKSUM:"$( : IP header csum
++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1
++ )
++ local checksum=$(payload_template_calc_checksum "$ipv4hdr")
++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum)
++
+ $MZ $dev -c $count -d 100msec -q \
+ -b $next_hop_mac -B $dest_ip \
+ -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(:
+@@ -569,16 +584,7 @@ vxlan_encapped_ping_do()
+ )"$dest_mac:"$( : ETH daddr
+ )"$(mac_get w2):"$( : ETH saddr
+ )"08:00:"$( : ETH type
+- )"45:"$( : IP version + IHL
+- )"$inner_tos:"$( : IP TOS
+- )"00:54:"$( : IP total length
+- )"99:83:"$( : IP identification
+- )"40:00:"$( : IP flags + frag off
+- )"40:"$( : IP TTL
+- )"01:"$( : IP proto
+- )"00:00:"$( : IP header csum
+- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
+- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1
++ )"$ipv4hdr:"$( : IPv4 header
+ )"08:"$( : ICMP type
+ )"00:"$( : ICMP code
+ )"8b:f2:"$( : ICMP csum
+--
+2.51.0
+
--- /dev/null
+From 83edc467c795d11eb9ef7087b3d2c9b3de32deba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 14:53:53 +0100
+Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ]
+
+As explained in [1], iproute2 started rejecting tc-police burst sizes
+that result in an overflow. This can happen when the burst size is high
+enough and the rate is low enough.
+
+A couple of test cases specify such configurations, resulting in
+iproute2 errors and test failure.
+
+Fix by reducing the burst size so that the test will pass with both new
+and old iproute2 versions.
+
+[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/
+
+Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+index 5ec3beb637c82..2e9669408d3b0 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+@@ -316,7 +316,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 0.5kbit burst 1m conform-exceed drop/ok
++ action police rate 0.5kbit burst 2k conform-exceed drop/ok
+ check_fail $? "Incorrect success to add police action with too low rate"
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+@@ -326,7 +326,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 1.5kbit burst 1m conform-exceed drop/ok
++ action police rate 1.5kbit burst 2k conform-exceed drop/ok
+ check_err $? "Failed to add police action with low rate"
+
+ tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
+--
+2.51.0
+
--- /dev/null
+From d45fe9433273fdc1294b0c1988dbec24248a23ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 19:51:59 -0800
+Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ]
+
+Since we started running selftests in NIPA we have been seeing
+tc_actions.sh generate a soft lockup warning on ~20% of the runs.
+On the pre-netdev foundation setup it was actually a missed irq
+splat from the console. Now it's either that or a lockup.
+
+I initially suspected a socket locking issue since the test
+is exercising local loopback with act_mirred.
+After hours of staring at this I noticed in strace that ncat
+when -o $file is specified _both_ saves the output to the file
+and still prints it to stdout. Because the file being sent
+is constructed with:
+
+ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred
+ ^^^^^^^^^
+
+the data printed is all \0. Most terminals don't display nul
+characters (and neither does vng output capture save them).
+But QEMU's serial console still has to poke them thru which
+is very slow and causes the lockup (if the file is >600kB).
+
+Replace the '-o $file' with '> $file'. This speeds the test up
+from 2m20s to 18s on debug kernels, and prevents the warnings.
+
+Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index dd02ed4cacacb..c25aaced2e1f0 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -176,7 +176,7 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 &
+ local rpid=$!
+ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+--
+2.51.0
+
pinctrl-qcom-sm8250-lpass-lpi-fix-i2s2_data_groups-d.patch
pinctrl-single-fix-refcount-leak-in-pcs_add_gpio_fun.patch
backlight-qcom-wled-support-ovp-values-for-pmi8994.patch
+fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch
+fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch
+acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch
+cpuidle-skip-governor-when-only-one-idle-state-is-av.patch
+selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch
+xen-netback-reject-zero-queue-configuration-from-gue.patch
+net-rds-rds_sendmsg-should-not-discard-payload_len.patch
+selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch
+netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch
+net-remove-warn_on_once-when-accessing-forward-path-.patch
+ipv6-fix-a-race-in-ip6_sock_set_v6only.patch
+bpftool-fix-truncated-netlink-dumps.patch
+selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch
+macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch
+octeontx2-af-fix-default-entries-mcam-entry-action.patch
+bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch
+apparmor-fix-null-sock-in-aa_sock_file_perm.patch
+apparmor-fix-rlimit-for-posix-cpu-timers.patch
+apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch
+asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch
+drm-i915-acpi-free-_dsm-package-when-no-connectors.patch
+btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch
--- /dev/null
+From ff694238d2d2a922a167f50b0249b3635b221194 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 22:40:40 +0000
+Subject: xen-netback: reject zero-queue configuration from guest
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ]
+
+A malicious or buggy Xen guest can write "0" to the xenbus key
+"multi-queue-num-queues". The connect() function in the backend only
+validates the upper bound (requested_num_queues > xenvif_max_queues)
+but not zero, allowing requested_num_queues=0 to reach
+vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers
+WARN_ON_ONCE(!size) in __vmalloc_node_range().
+
+On systems with panic_on_warn=1, this allows a guest-to-host denial
+of service.
+
+The Xen network interface specification requires
+the queue count to be "greater than zero".
+
+Add a zero check to match the validation already present
+in xen-blkback, which has included this
+guard since its multi-queue support was added.
+
+Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/xen-netback/xenbus.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
+index e85b3c5d4acce..5b78d9172aac9 100644
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -735,10 +735,11 @@ static void connect(struct backend_info *be)
+ */
+ requested_num_queues = xenbus_read_unsigned(dev->otherend,
+ "multi-queue-num-queues", 1);
+- if (requested_num_queues > xenvif_max_queues) {
++ if (requested_num_queues > xenvif_max_queues ||
++ requested_num_queues == 0) {
+ /* buggy or malicious guest */
+ xenbus_dev_fatal(dev, -EINVAL,
+- "guest requested %u queues, exceeding the maximum of %u.",
++ "guest requested %u queues, but valid range is 1 - %u.",
+ requested_num_queues, xenvif_max_queues);
+ return;
+ }
+--
+2.51.0
+
--- /dev/null
+From 2da86bef5424def69b442fa81770395f9c269037 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 21:22:54 +0000
+Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs
+
+From: Sean V Kelley <skelley@nvidia.com>
+
+[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all
+possible CPUs. In acpi_get_psd_map(), encountering an offline CPU
+returns -EFAULT, causing cppc_cpufreq initialization to fail.
+
+This breaks systems booted with "nosmt" or "nosmt=force".
+
+Fix by using for_each_online_cpu() in both functions.
+
+Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests")
+Signed-off-by: Sean V Kelley <skelley@nvidia.com>
+Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index c763c25424663..4382340fd9778 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -342,7 +342,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
+ end:
+ if (cmd == CMD_WRITE) {
+ if (unlikely(ret)) {
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i);
+
+ if (!desc)
+@@ -504,7 +504,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data)
+ else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
+ cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ if (i == cpu)
+ continue;
+
+--
+2.51.0
+
--- /dev/null
+From dd456ede3fc0777532444bd3615aa269ddda053e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Feb 2026 00:14:52 +0800
+Subject: ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO
+
+From: Zhai Can <bczhc0@126.com>
+
+[ Upstream commit cd7ef20ba8c6e936dba133b4136537a8ada22976 ]
+
+On the THUNDEROBOT ZERO laptop, the second NVMe slot and the discrete
+NVIDIA GPU are both controlled by power-resource PXP. Due to the SSDT table
+bug (lack of reference), PXP will be shut dow as an "unused" power resource
+during initialization, making the NVMe slot #2 + NVIDIA both inaccessible.
+
+This issue was introduced by commit a1224f34d72a ("ACPI: PM: Check
+states of power resources during initialization"). Here are test
+results on the three consecutive commits:
+
+(bad again!) a1224f34d72a ACPI: PM: Check states of power resources during initialization
+(good) bc2836859643 ACPI: PM: Do not turn off power resources in unknown state
+(bad) 519d81956ee2 Linux 5.15-rc6
+
+On commit bc2836859643 ("ACPI: PM: Do not turn off power resources in
+unknown state") this was not an issue because the power resource state
+left UNKNOWN thus being ignored.
+
+See also commit 9b04d99788cf ("ACPI: PM: Do not turn of unused power
+resources on the Toshiba Click Mini") which is another almost identical
+case to this one.
+
+Fixes: a1224f34d72a ("ACPI: PM: Check states of power resources during initialization")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221087
+Signed-off-by: Zhai Can <bczhc0@126.com>
+Link: https://patch.msgid.link/20260214161452.2849346-1-bczhc0@126.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/power.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
+index aea8c994caeac..db7b5534931be 100644
+--- a/drivers/acpi/power.c
++++ b/drivers/acpi/power.c
+@@ -1035,6 +1035,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
+ },
+ },
++ {
++ /*
++ * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power
++ * resource 'PXP' will be shut down on initialization, making
++ * the NVMe #2 and the NVIDIA dGPU both unavailable (they're
++ * both controlled by 'PXP').
++ */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"),
++ }
++
++ },
+ {}
+ };
+
+--
+2.51.0
+
--- /dev/null
+From d3ca5f15edafae7abf866b4885044f245173ad50 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 15:58:45 -0300
+Subject: apparmor: fix invalid deref of rawdata when export_binary is unset
+
+From: Georgia Garcia <georgia.garcia@canonical.com>
+
+[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ]
+
+If the export_binary parameter is disabled on runtime, profiles that
+were loaded before that will still have their rawdata stored in
+apparmorfs, with a symbolic link to the rawdata on the policy
+directory. When one of those profiles are replaced, the rawdata is set
+to NULL, but when trying to resolve the symbolic links to rawdata for
+that profile, it will try to dereference profile->rawdata->name when
+profile->rawdata is now NULL causing an oops. Fix it by checking if
+rawdata is set.
+
+[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088
+[ 168.657420] #PF: supervisor read access in kernel mode
+[ 168.660619] #PF: error_code(0x0000) - not-present page
+[ 168.663613] PGD 0 P4D 0
+[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI
+[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary)
+[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330
+[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8
+[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282
+[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158
+[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80
+[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000
+[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80
+[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0
+[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000
+[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0
+[ 168.701696] Call Trace:
+[ 168.702325] <TASK>
+[ 168.702995] rawdata_get_link_data+0x1c/0x30
+[ 168.704145] vfs_readlink+0xd4/0x160
+[ 168.705152] do_readlinkat+0x114/0x180
+[ 168.706214] __x64_sys_readlink+0x1e/0x30
+[ 168.708653] x64_sys_call+0x1d77/0x26b0
+[ 168.709525] do_syscall_64+0x81/0x500
+[ 168.710348] ? do_statx+0x72/0xb0
+[ 168.711109] ? putname+0x3e/0x80
+[ 168.711845] ? __x64_sys_statx+0xb7/0x100
+[ 168.712711] ? x64_sys_call+0x10fc/0x26b0
+[ 168.713577] ? do_syscall_64+0xbf/0x500
+[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0
+[ 168.715404] ? irqentry_exit+0xb2/0x740
+[ 168.716359] ? exc_page_fault+0x90/0x1b0
+[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement")
+Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/apparmorfs.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index ce7b2f43c3193..fa518cd82366a 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -1626,6 +1626,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry,
+
+ label = aa_get_label_rcu(&proxy->label);
+ profile = labels_profile(label);
++
++ /* rawdata can be null when aa_g_export_binary is unset during
++ * runtime and a profile is replaced
++ */
++ if (!profile->rawdata) {
++ aa_put_label(label);
++ return ERR_PTR(-ENOENT);
++ }
++
+ depth = profile_depth(profile);
+ target = gen_symlink_name(depth, profile->rawdata->name, name);
+ aa_put_label(label);
+--
+2.51.0
+
--- /dev/null
+From 48721e58f139ba11faedf899596f67132c6f2ad0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 15:07:42 -0800
+Subject: apparmor: fix NULL sock in aa_sock_file_perm
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ]
+
+Deal with the potential that sock and sock-sk can be NULL during
+socket setup or teardown. This could lead to an oops. The fix for NULL
+pointer dereference in __unix_needs_revalidation shows this is at
+least possible for af_unix sockets. While the fix for af_unix sockets
+applies for newer mediation this is still the fall back path for older
+af_unix mediation and other sockets, so ensure it is covered.
+
+Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/net.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index 7efe4d17273d9..0c980e62dbe7a 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -183,8 +183,10 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
+ struct socket *sock)
+ {
+ AA_BUG(!label);
+- AA_BUG(!sock);
+- AA_BUG(!sock->sk);
++
++ /* sock && sock->sk can be NULL for sockets being set up or torn down */
++ if (!sock || !sock->sk)
++ return 0;
+
+ return aa_label_sk_perm(label, op, request, sock->sk);
+ }
+--
+2.51.0
+
--- /dev/null
+From 9b6a63a67221d26db8d31a295265f33fe07411ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:16:54 -0800
+Subject: apparmor: fix rlimit for posix cpu timers
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ]
+
+Posix cpu timers requires an additional step beyond setting the rlimit.
+Refactor the code so its clear when what code is setting the
+limit and conditionally update the posix cpu timers when appropriate.
+
+Fixes: baa73d9e478ff ("posix-timers: Make them configurable")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/resource.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index 1ae4874251a96..f94e416399441 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -182,6 +182,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
+ new->rlimits.limits[j].rlim_max);
+ /* soft limit should not exceed hard limit */
+ rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
++ if (j == RLIMIT_CPU &&
++ rlim->rlim_cur != RLIM_INFINITY &&
++ IS_ENABLED(CONFIG_POSIX_TIMERS))
++ (void) update_rlimit_cpu(current->group_leader,
++ rlim->rlim_cur);
+ }
+ }
+ }
+--
+2.51.0
+
--- /dev/null
+From ad39853373cb2b2693c62fe7b88e38f562f7a35a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 18:57:14 +0000
+Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ]
+
+This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()").
+
+The original patch attempted to acquire the card->controls_rwsem lock in
+fsl_xcvr_mode_put(). However, this function is called from the upper ALSA
+core function snd_ctl_elem_write(), which already holds the write lock on
+controls_rwsem for the whole put operation. So there is no need to simply
+hold the lock for fsl_xcvr_activate_ctl() again.
+
+Acquiring the read lock while holding the write lock in the same thread
+results in a deadlock and a hung task, as reported by Alexander Stein.
+
+Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()")
+Reported-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_xcvr.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
+index e6c0e6609cbe0..5b61b93772d64 100644
+--- a/sound/soc/fsl/fsl_xcvr.c
++++ b/sound/soc/fsl/fsl_xcvr.c
+@@ -203,13 +203,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,
+
+ xcvr->mode = snd_soc_enum_item_to_val(e, item[0]);
+
+- down_read(&card->snd_card->controls_rwsem);
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_ARC));
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_EARC));
+- up_read(&card->snd_card->controls_rwsem);
+-
+ /* Allow playback for SPDIF only */
+ rtd = snd_soc_get_pcm_runtime(card, card->dai_link);
+ rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
+--
+2.51.0
+
--- /dev/null
+From a565a9bc5ac852f84a22c34d658934a15fefd996 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 15:18:34 -0500
+Subject: ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk
+
+From: Detlev Casanova <detlev.casanova@collabora.com>
+
+[ Upstream commit 0783052534f547f8f201dd4554b1df9f1f8615b5 ]
+
+Drivers will not always call set_sysclk() for all clocks, especially when
+default mclk-fs can be used.
+When that is the case, use the clock rate set in the params multiplied by the
+default mclk-fs.
+
+Fixes: 5323186e2e8d ("ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback")
+Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
+Reported-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Link: https://patch.msgid.link/20260218201834.924358-1-detlev.casanova@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/rockchip/rockchip_i2s_tdm.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
+index ff743ba0a9441..19eb82583d119 100644
+--- a/sound/soc/rockchip/rockchip_i2s_tdm.c
++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
+@@ -24,6 +24,7 @@
+
+ #define DRV_NAME "rockchip-i2s-tdm"
+
++#define DEFAULT_MCLK_FS 256
+ #define CH_GRP_MAX 4 /* The max channel 8 / 2 */
+ #define MULTIPLEX_CH_MAX 10
+
+@@ -689,6 +690,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
+ mclk_rate = i2s_tdm->mclk_rx_freq;
+ }
+
++ /*
++ * When the dai/component driver doesn't need to set mclk-fs for a specific
++ * clock, it can skip the call to set_sysclk() for that clock.
++ * In that case, simply use the clock rate from the params and multiply it by
++ * the default mclk-fs value.
++ */
++ if (!mclk_rate)
++ mclk_rate = DEFAULT_MCLK_FS * params_rate(params);
++
+ err = clk_set_rate(mclk, mclk_rate);
+ if (err)
+ return err;
+--
+2.51.0
+
--- /dev/null
+From ac21381e0b47152d4fbe51402b83dfcad5ae61e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 06:09:19 +0000
+Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ]
+
+The ALB RX path may access rx_hashtbl concurrently with bond
+teardown. During rapid bond up/down cycles, rlb_deinitialize()
+frees rx_hashtbl while RX handlers are still running, leading
+to a null pointer dereference detected by KASAN.
+
+However, the root cause is that rlb_arp_recv() can still be accessed
+after setting recv_probe to NULL, which is actually a use-after-free
+(UAF) issue. That is the reason for using the referenced commit in the
+Fixes tag.
+
+[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI
+[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef]
+[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary)
+[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022
+[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding]
+[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6
+ 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00
+[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206
+[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e
+[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8
+[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8
+[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119
+[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810
+[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000
+[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0
+[ 214.310347] Call Trace:
+[ 214.313070] <IRQ>
+[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding]
+[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding]
+[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding]
+[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710
+[ 214.339199] ? __pfx_arp_process+0x10/0x10
+[ 214.343775] ? sched_balance_find_src_group+0x98/0x630
+[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10
+[ 214.356513] ? arp_rcv+0x307/0x690
+[ 214.360311] ? __pfx_arp_rcv+0x10/0x10
+[ 214.364499] ? __lock_acquire+0x58c/0xbd0
+[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0
+[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10
+[ 214.380743] ? lock_acquire+0x10b/0x140
+[ 214.385026] process_backlog+0x3f1/0x13a0
+[ 214.389502] ? process_backlog+0x3aa/0x13a0
+[ 214.394174] __napi_poll.constprop.0+0x9f/0x370
+[ 214.399233] net_rx_action+0x8c1/0xe60
+[ 214.403423] ? __pfx_net_rx_action+0x10/0x10
+[ 214.408193] ? lock_acquire.part.0+0xbd/0x260
+[ 214.413058] ? sched_clock_cpu+0x6c/0x540
+[ 214.417540] ? mark_held_locks+0x40/0x70
+[ 214.421920] handle_softirqs+0x1fd/0x860
+[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10
+[ 214.431264] ? __neigh_event_send+0x2d6/0xf50
+[ 214.436131] do_softirq+0xb1/0xf0
+[ 214.439830] </IRQ>
+
+The issue is reproducible by repeatedly running
+ip link set bond0 up/down while receiving ARP messages, where
+rlb_arp_recv() can race with rlb_deinitialize() and dereference
+a freed rx_hashtbl entry.
+
+Fix this by setting recv_probe to NULL and then calling
+synchronize_net() to wait for any concurrent RX processing to finish.
+This ensures that no RX handler can access rx_hashtbl after it is freed
+in bond_alb_deinitialize().
+
+Reported-by: Liang Li <liali@redhat.com>
+Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 113a5504c9ebb..8ff1c34b4db63 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4343,9 +4343,13 @@ static int bond_close(struct net_device *bond_dev)
+
+ bond_work_cancel_all(bond);
+ bond->send_peer_notif = 0;
++ WRITE_ONCE(bond->recv_probe, NULL);
++
++ /* Wait for any in-flight RX handlers */
++ synchronize_net();
++
+ if (bond_is_lb(bond))
+ bond_alb_deinitialize(bond);
+- bond->recv_probe = NULL;
+
+ if (bond_uses_primary(bond)) {
+ rcu_read_lock();
+--
+2.51.0
+
--- /dev/null
+From 873c4ed7952e8f938a2154dd2ee604da5828c5ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 11:41:50 -0800
+Subject: bpftool: Fix truncated netlink dumps
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ]
+
+Netlink requires that the recv buffer used during dumps is at least
+min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will
+get truncated. Make sure bpftool follows this requirement, avoid
+missing information on systems with large pages.
+
+Acked-by: Quentin Monnet <qmo@kernel.org>
+Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/net.c | 5 ++++-
+ tools/lib/bpf/netlink.c | 4 +++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c
+index 7c9e86faab6ce..3863c2d986830 100644
+--- a/tools/bpf/bpftool/net.c
++++ b/tools/bpf/bpftool/net.c
+@@ -143,7 +143,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ bool multipart = true;
+ struct nlmsgerr *err;
+ struct nlmsghdr *nh;
+- char buf[4096];
++ char buf[8192];
+ int len, ret;
+
+ while (multipart) {
+@@ -188,6 +188,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ return ret;
+ }
+ }
++
++ if (len)
++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len);
+ }
+ ret = 0;
+ done:
+diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
+index 35104580870c0..ecd6e03b3ba53 100644
+--- a/tools/lib/bpf/netlink.c
++++ b/tools/lib/bpf/netlink.c
+@@ -135,7 +135,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ struct nlmsghdr *nh;
+ int len, ret;
+
+- ret = alloc_iov(&iov, 4096);
++ ret = alloc_iov(&iov, 8192);
+ if (ret)
+ goto done;
+
+@@ -204,6 +204,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ }
+ }
+ }
++ if (len)
++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len);
+ }
+ ret = 0;
+ done:
+--
+2.51.0
+
--- /dev/null
+From 8cce61a69e4f233761b9ece32df6c66257f64d29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 17:15:53 +0000
+Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not
+ found
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ]
+
+If btrfs_search_slot_for_read() returns 1, it means we did not find any
+key greater than or equals to the key we asked for, meaning we have
+reached the end of the tree and therefore the path is not valid. If
+this happens we need to break out of the loop and stop, instead of
+continuing and accessing an invalid path.
+
+Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/qgroup.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index b175d0a4b3826..e80d73ad08103 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1123,11 +1123,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
+ }
+ if (ret > 0) {
+ /*
+- * Shouldn't happen, but in case it does we
+- * don't need to do the btrfs_next_item, just
+- * continue.
++ * Shouldn't happen because the key should still
++ * be there (return 0), but in case it does it
++ * means we have reached the end of the tree -
++ * there are no more leaves with items that have
++ * a key greater than or equals to @found_key,
++ * so just stop the search loop.
+ */
+- continue;
++ break;
+ }
+ }
+ ret = btrfs_next_item(tree_root, path);
+--
+2.51.0
+
--- /dev/null
+From c353fd8008c6eb3f6a87f2698e3dd0b06b189fc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 00:20:02 +0530
+Subject: cpuidle: Skip governor when only one idle state is available
+
+From: Aboorva Devarajan <aboorvad@linux.ibm.com>
+
+[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ]
+
+On certain platforms (PowerNV systems without a power-mgt DT node),
+cpuidle may register only a single idle state. In cases where that
+single state is a polling state (state 0), the ladder governor may
+incorrectly treat state 1 as the first usable state and pass an
+out-of-bounds index. This can lead to a NULL enter callback being
+invoked, ultimately resulting in a system crash.
+
+[ 13.342636] cpuidle-powernv : Only Snooze is available
+[ 13.351854] Faulting instruction address: 0x00000000
+[ 13.376489] NIP [0000000000000000] 0x0
+[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668
+
+Fix this by adding a bail-out in cpuidle_select() that returns state 0
+directly when state_count <= 1, bypassing the governor and keeping the
+tick running.
+
+Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol")
+Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
+Reviewed-by: Christian Loehle <christian.loehle@arm.com>
+Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/cpuidle.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
+index fdd25271106a3..482bf87354a38 100644
+--- a/drivers/cpuidle/cpuidle.c
++++ b/drivers/cpuidle/cpuidle.c
+@@ -324,6 +324,16 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
+ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+ bool *stop_tick)
+ {
++ /*
++ * If there is only a single idle state (or none), there is nothing
++ * meaningful for the governor to choose. Skip the governor and
++ * always use state 0 with the tick running.
++ */
++ if (drv->state_count <= 1) {
++ *stop_tick = false;
++ return 0;
++ }
++
+ return cpuidle_curr_governor->select(drv, dev, stop_tick);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 9dff9eea1d2e4245dc2893a00545263c7876f461 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 23:38:28 +0100
+Subject: drm/amd/display: Use same max plane scaling limits for all 64 bpp
+ formats
+
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+
+[ Upstream commit f0157ce46cf0e5e2257e19d590c9b16036ce26d4 ]
+
+The plane scaling hw seems to have the same min/max plane scaling limits
+for all 16 bpc / 64 bpp interleaved pixel color formats.
+
+Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for
+all the 16 bpc fixed-point / unorm formats to use the same .fp16
+up/downscaling factor limits as used by the fp16 floating point formats.
+
+So far, 16 bpc unorm formats were not handled, and the default: path
+returned max/min factors for 32 bpp argb8888 formats, which were wrong
+and bigger than what many DCE / DCN hw generations could handle.
+
+The result sometimes was misscaling of framebuffers with
+DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616,
+DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested
+on Polaris11 / DCE-11.2.
+
+So far this went unnoticed, because only few userspace clients used such
+16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they
+did not experience this issue.
+
+With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL
+and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland
+compositor allowing for direct scanout of these formats, the scaling
+hw will be used on these formats if possible for HiDPI display scaling,
+so it is important to use the correct hw scaling limits to avoid wrong
+display.
+
+Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50
+on HiDPI displays with scaling enabled. The mutter Wayland compositor now
+correctly falls back to scaling via desktop compositing instead of direct
+scanout, thereby avoiding wrong image display. For unscaled mode, it
+correctly uses direct scanout.
+
+Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.")
+Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+index df4cbf81c6b50..b3a1dbeac4839 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+@@ -970,10 +970,15 @@ static void get_min_max_dc_plane_scaling(struct drm_device *dev,
+ *min_downscale = plane_cap->max_downscale_factor.nv12;
+ break;
+
++ /* All 64 bpp formats have the same fp16 scaling limits */
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ABGR16161616F:
++ case DRM_FORMAT_XRGB16161616:
++ case DRM_FORMAT_ARGB16161616:
++ case DRM_FORMAT_XBGR16161616:
++ case DRM_FORMAT_ABGR16161616:
+ *max_upscale = plane_cap->max_upscale_factor.fp16;
+ *min_downscale = plane_cap->max_downscale_factor.fp16;
+ break;
+--
+2.51.0
+
--- /dev/null
+From d8e6fb00b639fb94a1f796d0fb3b65012b493887 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jan 2026 08:55:49 +0530
+Subject: drm/i915/acpi: free _DSM package when no connectors
+
+From: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+
+[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ]
+
+acpi_evaluate_dsm_typed() returns an ACPI package in pkg.
+When pkg->package.count == 0, we returned without freeing pkg,
+leaking memory. Free pkg before returning on the empty case.
+
+Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_acpi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c
+index 9df78e7caa2bd..231b341d968ad 100644
+--- a/drivers/gpu/drm/i915/display/intel_acpi.c
++++ b/drivers/gpu/drm/i915/display/intel_acpi.c
+@@ -93,6 +93,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle)
+
+ if (!pkg->package.count) {
+ DRM_DEBUG_DRIVER("no connection in _DSM\n");
++ ACPI_FREE(pkg);
+ return;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 6f1cc64ea7858912a7be71844538b0a4dcfee919 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jan 2026 16:50:24 +0000
+Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot
+
+From: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+
+[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ]
+
+In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the
+entry size ('esize') is retrieved from the log record without adequate
+bounds checking.
+
+Specifically, the code calculates the end of the entry ('e2') using:
+ e2 = Add2Ptr(e1, esize);
+
+It then calculates the size for memmove using 'PtrOffset(e2, ...)',
+which subtracts the end pointer from the buffer limit. If 'esize' is
+maliciously large, 'e2' exceeds the used buffer size. This results in
+a negative offset which, when cast to size_t for memmove, interprets
+as a massive unsigned integer, leading to a heap buffer overflow.
+
+This commit adds a check to ensure that the entry size ('esize') strictly
+fits within the remaining used space of the index header before performing
+memory operations.
+
+Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
+Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/fslog.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
+index 339ce5aa3c75b..7e6937e7d471f 100644
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -3434,6 +3434,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe,
+
+ e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off));
+ esize = le16_to_cpu(e1->size);
++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize)
++ goto dirty_vol;
++
+ e2 = Add2Ptr(e1, esize);
+
+ memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used)));
+--
+2.51.0
+
--- /dev/null
+From ca782b5a179f21f9e02f8fbf1e8177538b92f4ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Dec 2025 11:53:25 +0800
+Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the
+ same
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ]
+
+When processing valid within the range [valid : pos), if valid cannot
+be retrieved correctly, for example, if the retrieved valid value is
+always the same, this can trigger a potential infinite loop, similar
+to the hung problem reported by syzbot [1].
+
+Adding a check for the valid value within the loop body, and terminating
+the loop and returning -EINVAL if the value is the same as the current
+value, can prevent this.
+
+[1]
+INFO: task syz.4.21:6056 blocked for more than 143 seconds.
+Call Trace:
+ rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244
+ inode_lock include/linux/fs.h:1027 [inline]
+ ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284
+
+Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
+Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/file.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index 6d9c1dfe9b1b6..f2d1df2c988a9 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -870,8 +870,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from)
+ goto out;
+
+ if (lcn == SPARSE_LCN) {
+- ni->i_valid = valid =
+- frame_vbo + ((u64)clen << sbi->cluster_bits);
++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits);
++ if (ni->i_valid == valid) {
++ err = -EINVAL;
++ goto out;
++ }
++ ni->i_valid = valid;
+ continue;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 1b9ddebe1d1b4d865baf4a694ac571e40f089e6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 14:46:41 +0000
+Subject: icmp: icmp_msgs_per_sec and icmp_msgs_burst sysctls become per netns
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit f17bf505ff89595df5147755e51441632a5dc563 ]
+
+Previous patch made ICMP rate limits per netns, it makes sense
+to allow each netns to change the associated sysctl.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20240829144641.3880376-4-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 034bbd806298 ("icmp: prevent possible overflow in icmp_global_allow()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip.h | 3 ---
+ include/net/netns/ipv4.h | 2 ++
+ net/ipv4/icmp.c | 9 ++++-----
+ net/ipv4/sysctl_net_ipv4.c | 32 ++++++++++++++++----------------
+ 4 files changed, 22 insertions(+), 24 deletions(-)
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 86ae58408148b..1b0722e9b55e4 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -788,9 +788,6 @@ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
+ bool icmp_global_allow(struct net *net);
+ void icmp_global_consume(struct net *net);
+
+-extern int sysctl_icmp_msgs_per_sec;
+-extern int sysctl_icmp_msgs_burst;
+-
+ #ifdef CONFIG_PROC_FS
+ int ip_misc_proc_init(void);
+ #endif
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 45988bea57cb2..091482aa76c32 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -83,6 +83,8 @@ struct netns_ipv4 {
+ u8 sysctl_icmp_errors_use_inbound_ifaddr;
+ int sysctl_icmp_ratelimit;
+ int sysctl_icmp_ratemask;
++ int sysctl_icmp_msgs_per_sec;
++ int sysctl_icmp_msgs_burst;
+ atomic_t icmp_global_credit;
+ u32 icmp_global_stamp;
+ u32 ip_rt_min_pmtu;
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index d1660c426a44a..d2c7509135a3f 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -221,9 +221,6 @@ static inline void icmp_xmit_unlock(struct sock *sk)
+ spin_unlock(&sk->sk_lock.slock);
+ }
+
+-int sysctl_icmp_msgs_per_sec __read_mostly = 1000;
+-int sysctl_icmp_msgs_burst __read_mostly = 50;
+-
+ /**
+ * icmp_global_allow - Are we allowed to send one more ICMP message ?
+ * @net: network namespace
+@@ -250,14 +247,14 @@ bool icmp_global_allow(struct net *net)
+ if (delta < HZ / 50)
+ return false;
+
+- incr = READ_ONCE(sysctl_icmp_msgs_per_sec) * delta / HZ;
++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ;
+ if (!incr)
+ return false;
+
+ if (cmpxchg(&net->ipv4.icmp_global_stamp, oldstamp, now) == oldstamp) {
+ old = atomic_read(&net->ipv4.icmp_global_credit);
+ do {
+- new = min(old + incr, READ_ONCE(sysctl_icmp_msgs_burst));
++ new = min(old + incr, READ_ONCE(net->ipv4.sysctl_icmp_msgs_burst));
+ } while (!atomic_try_cmpxchg(&net->ipv4.icmp_global_credit, &old, new));
+ }
+ return true;
+@@ -1510,6 +1507,8 @@ static int __net_init icmp_sk_init(struct net *net)
+ net->ipv4.sysctl_icmp_ratelimit = 1 * HZ;
+ net->ipv4.sysctl_icmp_ratemask = 0x1818;
+ net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr = 0;
++ net->ipv4.sysctl_icmp_msgs_per_sec = 1000;
++ net->ipv4.sysctl_icmp_msgs_burst = 50;
+
+ return 0;
+ }
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 73e5821584c18..6b4c9b0fc9abb 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -519,22 +519,6 @@ static struct ctl_table ipv4_table[] = {
+ .mode = 0444,
+ .proc_handler = proc_tcp_available_ulp,
+ },
+- {
+- .procname = "icmp_msgs_per_sec",
+- .data = &sysctl_icmp_msgs_per_sec,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = proc_dointvec_minmax,
+- .extra1 = SYSCTL_ZERO,
+- },
+- {
+- .procname = "icmp_msgs_burst",
+- .data = &sysctl_icmp_msgs_burst,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = proc_dointvec_minmax,
+- .extra1 = SYSCTL_ZERO,
+- },
+ {
+ .procname = "udp_mem",
+ .data = &sysctl_udp_mem,
+@@ -621,6 +605,22 @@ static struct ctl_table ipv4_net_table[] = {
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
++ {
++ .procname = "icmp_msgs_per_sec",
++ .data = &init_net.ipv4.sysctl_icmp_msgs_per_sec,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec_minmax,
++ .extra1 = SYSCTL_ZERO,
++ },
++ {
++ .procname = "icmp_msgs_burst",
++ .data = &init_net.ipv4.sysctl_icmp_msgs_burst,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec_minmax,
++ .extra1 = SYSCTL_ZERO,
++ },
+ {
+ .procname = "ping_group_range",
+ .data = &init_net.ipv4.ping_group_range.range,
+--
+2.51.0
+
--- /dev/null
+From 73d8f86cb4e620a3cb7fa954399c17a3c7f09bb7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 14:46:40 +0000
+Subject: icmp: move icmp_global.credit and icmp_global.stamp to per netns
+ storage
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b056b4cd9178f7a1d5d57f7b48b073c29729ddaa ]
+
+Host wide ICMP ratelimiter should be per netns, to provide better isolation.
+
+Following patch in this series makes the sysctl per netns.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20240829144641.3880376-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 034bbd806298 ("icmp: prevent possible overflow in icmp_global_allow()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip.h | 4 ++--
+ include/net/netns/ipv4.h | 3 ++-
+ net/ipv4/icmp.c | 26 +++++++++++---------------
+ net/ipv6/icmp.c | 4 ++--
+ 4 files changed, 17 insertions(+), 20 deletions(-)
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 4ee23eb0814a3..86ae58408148b 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -785,8 +785,8 @@ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
+ ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0);
+ }
+
+-bool icmp_global_allow(void);
+-void icmp_global_consume(void);
++bool icmp_global_allow(struct net *net);
++void icmp_global_consume(struct net *net);
+
+ extern int sysctl_icmp_msgs_per_sec;
+ extern int sysctl_icmp_msgs_burst;
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index ede2ff1da53a3..45988bea57cb2 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -83,7 +83,8 @@ struct netns_ipv4 {
+ u8 sysctl_icmp_errors_use_inbound_ifaddr;
+ int sysctl_icmp_ratelimit;
+ int sysctl_icmp_ratemask;
+-
++ atomic_t icmp_global_credit;
++ u32 icmp_global_stamp;
+ u32 ip_rt_min_pmtu;
+ int ip_rt_mtu_expires;
+ int ip_rt_min_advmss;
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index 56b240e7f083c..d1660c426a44a 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -224,19 +224,15 @@ static inline void icmp_xmit_unlock(struct sock *sk)
+ int sysctl_icmp_msgs_per_sec __read_mostly = 1000;
+ int sysctl_icmp_msgs_burst __read_mostly = 50;
+
+-static struct {
+- atomic_t credit;
+- u32 stamp;
+-} icmp_global;
+-
+ /**
+ * icmp_global_allow - Are we allowed to send one more ICMP message ?
++ * @net: network namespace
+ *
+ * Uses a token bucket to limit our ICMP messages to ~sysctl_icmp_msgs_per_sec.
+ * Returns false if we reached the limit and can not send another packet.
+ * Works in tandem with icmp_global_consume().
+ */
+-bool icmp_global_allow(void)
++bool icmp_global_allow(struct net *net)
+ {
+ u32 delta, now, oldstamp;
+ int incr, new, old;
+@@ -245,11 +241,11 @@ bool icmp_global_allow(void)
+ * Then later icmp_global_consume() could consume more credits,
+ * this is an acceptable race.
+ */
+- if (atomic_read(&icmp_global.credit) > 0)
++ if (atomic_read(&net->ipv4.icmp_global_credit) > 0)
+ return true;
+
+ now = jiffies;
+- oldstamp = READ_ONCE(icmp_global.stamp);
++ oldstamp = READ_ONCE(net->ipv4.icmp_global_stamp);
+ delta = min_t(u32, now - oldstamp, HZ);
+ if (delta < HZ / 50)
+ return false;
+@@ -258,23 +254,23 @@ bool icmp_global_allow(void)
+ if (!incr)
+ return false;
+
+- if (cmpxchg(&icmp_global.stamp, oldstamp, now) == oldstamp) {
+- old = atomic_read(&icmp_global.credit);
++ if (cmpxchg(&net->ipv4.icmp_global_stamp, oldstamp, now) == oldstamp) {
++ old = atomic_read(&net->ipv4.icmp_global_credit);
+ do {
+ new = min(old + incr, READ_ONCE(sysctl_icmp_msgs_burst));
+- } while (!atomic_try_cmpxchg(&icmp_global.credit, &old, new));
++ } while (!atomic_try_cmpxchg(&net->ipv4.icmp_global_credit, &old, new));
+ }
+ return true;
+ }
+ EXPORT_SYMBOL(icmp_global_allow);
+
+-void icmp_global_consume(void)
++void icmp_global_consume(struct net *net)
+ {
+ int credits = get_random_u32_below(3);
+
+ /* Note: this might make icmp_global.credit negative. */
+ if (credits)
+- atomic_sub(credits, &icmp_global.credit);
++ atomic_sub(credits, &net->ipv4.icmp_global_credit);
+ }
+ EXPORT_SYMBOL(icmp_global_consume);
+
+@@ -300,7 +296,7 @@ static bool icmpv4_global_allow(struct net *net, int type, int code,
+ if (icmpv4_mask_allow(net, type, code))
+ return true;
+
+- if (icmp_global_allow()) {
++ if (icmp_global_allow(net)) {
+ *apply_ratelimit = true;
+ return true;
+ }
+@@ -337,7 +333,7 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
+ if (!rc)
+ __ICMP_INC_STATS(net, ICMP_MIB_RATELIMITHOST);
+ else
+- icmp_global_consume();
++ icmp_global_consume(net);
+ return rc;
+ }
+
+diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
+index 7ba3c642ab3c3..ea1cdacbdcf1b 100644
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -181,7 +181,7 @@ static bool icmpv6_global_allow(struct net *net, int type,
+ if (icmpv6_mask_allow(net, type))
+ return true;
+
+- if (icmp_global_allow()) {
++ if (icmp_global_allow(net)) {
+ *apply_ratelimit = true;
+ return true;
+ }
+@@ -231,7 +231,7 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
+ __ICMP6_INC_STATS(net, ip6_dst_idev(dst),
+ ICMP6_MIB_RATELIMITHOST);
+ else
+- icmp_global_consume();
++ icmp_global_consume(net);
+ dst_release(dst);
+ return res;
+ }
+--
+2.51.0
+
--- /dev/null
+From fdc2d6979e528116457e540fbf150c1c9d8ef1d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:28 +0000
+Subject: icmp: prevent possible overflow in icmp_global_allow()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 034bbd806298e9ba4197dd1587b0348ee30996ea ]
+
+Following expression can overflow
+if sysctl_icmp_msgs_per_sec is big enough.
+
+sysctl_icmp_msgs_per_sec * delta / HZ;
+
+Fixes: 4cdf507d5452 ("icmp: add a global rate limitation")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216142832.3834174-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/icmp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index d2c7509135a3f..374ec3aba66e3 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -247,7 +247,8 @@ bool icmp_global_allow(struct net *net)
+ if (delta < HZ / 50)
+ return false;
+
+- incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ;
++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec);
++ incr = div_u64((u64)incr * delta, HZ);
+ if (!incr)
+ return false;
+
+--
+2.51.0
+
--- /dev/null
+From ced56e983f6d395a408560f46cc65346b29c5f88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Aug 2025 15:30:51 +0000
+Subject: inet: ping: check sock_net() in ping_get_port() and ping_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 59f26d86b2a16f1406f3b42025062b6d1fba5dd5 ]
+
+We need to check socket netns before considering them in ping_get_port().
+Otherwise, one malicious netns could 'consume' all ports.
+
+Add corresponding check in ping_lookup().
+
+Fixes: c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Reviewed-by: Yue Haibing <yuehaibing@huawei.com>
+Link: https://patch.msgid.link/20250829153054.474201-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: ad5dfde2a573 ("ping: annotate data-races in ping_lookup()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ping.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index aae5ad6303a97..ee0e2df5d62e0 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -77,6 +77,7 @@ static inline struct hlist_head *ping_hashslot(struct ping_table *table,
+
+ int ping_get_port(struct sock *sk, unsigned short ident)
+ {
++ struct net *net = sock_net(sk);
+ struct inet_sock *isk, *isk2;
+ struct hlist_head *hlist;
+ struct sock *sk2 = NULL;
+@@ -90,9 +91,10 @@ int ping_get_port(struct sock *sk, unsigned short ident)
+ for (i = 0; i < (1L << 16); i++, result++) {
+ if (!result)
+ result++; /* avoid zero */
+- hlist = ping_hashslot(&ping_table, sock_net(sk),
+- result);
++ hlist = ping_hashslot(&ping_table, net, result);
+ sk_for_each(sk2, hlist) {
++ if (!net_eq(sock_net(sk2), net))
++ continue;
+ isk2 = inet_sk(sk2);
+
+ if (isk2->inet_num == result)
+@@ -108,8 +110,10 @@ int ping_get_port(struct sock *sk, unsigned short ident)
+ if (i >= (1L << 16))
+ goto fail;
+ } else {
+- hlist = ping_hashslot(&ping_table, sock_net(sk), ident);
++ hlist = ping_hashslot(&ping_table, net, ident);
+ sk_for_each(sk2, hlist) {
++ if (!net_eq(sock_net(sk2), net))
++ continue;
+ isk2 = inet_sk(sk2);
+
+ /* BUG? Why is this reuse and not reuseaddr? ping.c
+@@ -129,7 +133,7 @@ int ping_get_port(struct sock *sk, unsigned short ident)
+ pr_debug("was not hashed\n");
+ sk_add_node_rcu(sk, hlist);
+ sock_set_flag(sk, SOCK_RCU_FREE);
+- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
++ sock_prot_inuse_add(net, sk->sk_prot, 1);
+ }
+ spin_unlock(&ping_table.lock);
+ return 0;
+@@ -188,6 +192,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ }
+
+ sk_for_each_rcu(sk, hslot) {
++ if (!net_eq(sock_net(sk), net))
++ continue;
+ isk = inet_sk(sk);
+
+ pr_debug("iterate\n");
+--
+2.51.0
+
--- /dev/null
+From 8927e093e9806e3da2f8fade2ae7719cb756f51d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:22:02 +0000
+Subject: ipv6: fix a race in ip6_sock_set_v6only()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ]
+
+It is unlikely that this function will be ever called
+with isk->inet_num being not zero.
+
+Perform the check on isk->inet_num inside the locked section
+for complete safety.
+
+Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ipv6.h | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index 517bdae78614b..3bf743d601e1c 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -1255,12 +1255,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
+
+ static inline int ip6_sock_set_v6only(struct sock *sk)
+ {
+- if (inet_sk(sk)->inet_num)
+- return -EINVAL;
++ int ret = 0;
++
+ lock_sock(sk);
+- sk->sk_ipv6only = true;
++ if (inet_sk(sk)->inet_num)
++ ret = -EINVAL;
++ else
++ sk->sk_ipv6only = true;
+ release_sock(sk);
+- return 0;
++ return ret;
+ }
+
+ static inline void ip6_sock_set_recverr(struct sock *sk)
+--
+2.51.0
+
--- /dev/null
+From c6786735d3a16fbb6428f83215354f7567a58688 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:25:57 +0000
+Subject: macvlan: observe an RCU grace period in macvlan_common_newlink()
+ error path
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ]
+
+valis reported that a race condition still happens after my prior patch.
+
+macvlan_common_newlink() might have made @dev visible before
+detecting an error, and its caller will directly call free_netdev(dev).
+
+We must respect an RCU period, either in macvlan or the core networking
+stack.
+
+After adding a temporary mdelay(1000) in macvlan_forward_source_one()
+to open the race window, valis repro was:
+
+ip link add p1 type veth peer p2
+ip link set address 00:00:00:00:00:20 dev p1
+ip link set up dev p1
+ip link set up dev p2
+ip link add mv0 link p2 type macvlan mode source
+
+(ip link add invalid% link p2 type macvlan mode source macaddr add
+00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4
+PING 1.2.3.4 (1.2.3.4): 56 data bytes
+RTNETLINK answers: Invalid argument
+
+BUG: KASAN: slab-use-after-free in macvlan_forward_source
+(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+Read of size 8 at addr ffff888016bb89c0 by task e/175
+
+CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
+Call Trace:
+<IRQ>
+dump_stack_lvl (lib/dump_stack.c:123)
+print_report (mm/kasan/report.c:379 mm/kasan/report.c:482)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+kasan_report (mm/kasan/report.c:597)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+? tasklet_init (kernel/softirq.c:983)
+macvlan_handle_frame (drivers/net/macvlan.c:501)
+
+Allocated by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+__kasan_kmalloc (mm/kasan/common.c:419)
+__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657
+mm/slub.c:7140)
+alloc_netdev_mqs (net/core/dev.c:12012)
+rtnl_create_link (net/core/rtnetlink.c:3648)
+rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Freed by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+kasan_save_free_info (mm/kasan/generic.c:587)
+__kasan_slab_free (mm/kasan/common.c:287)
+kfree (mm/slub.c:6674 mm/slub.c:6882)
+rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: valis <sec@valis.email>
+Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macvlan.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index 5fb956adc4260..24e36d78a23ae 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1544,6 +1544,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
+ if (create)
+ macvlan_port_destroy(port->dev);
+ }
++ /* @dev might have been made visible before an error was detected.
++ * Make sure to observe an RCU grace period before our caller
++ * (rtnl_newlink()) frees it.
++ */
++ synchronize_net();
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(macvlan_common_newlink);
+--
+2.51.0
+
--- /dev/null
+From fc8c1f353ffb7f37eeac38ab678e74030ad0cd3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:02 +0000
+Subject: net: mscc: ocelot: add missing lock protection in
+ ocelot_port_xmit_inj()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 026f6513c5880c2c89e38ad66bbec2868f978605 ]
+
+ocelot_port_xmit_inj() calls ocelot_can_inject() and
+ocelot_port_inject_frame() without holding the injection group lock.
+Both functions contain lockdep_assert_held() for the injection lock,
+and the correct caller felix_port_deferred_xmit() properly acquires
+the lock using ocelot_lock_inj_grp() before calling these functions.
+
+Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register
+injection path to fix the missing lock protection. The FDMA path is not
+affected as it uses its own locking mechanism.
+
+Fixes: c5e12ac3beb0 ("net: mscc: ocelot: serialize access to the injection/extraction groups")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-4-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index 14de948f72464..e4f4ea97c55b7 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -606,14 +606,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb,
+ int port = priv->port.index;
+ u32 rew_op = 0;
+
+- if (!ocelot_can_inject(ocelot, 0))
++ ocelot_lock_inj_grp(ocelot, 0);
++
++ if (!ocelot_can_inject(ocelot, 0)) {
++ ocelot_unlock_inj_grp(ocelot, 0);
+ return NETDEV_TX_BUSY;
++ }
+
+- if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) {
++ ocelot_unlock_inj_grp(ocelot, 0);
+ return NETDEV_TX_OK;
++ }
+
+ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
++ ocelot_unlock_inj_grp(ocelot, 0);
++
+ consume_skb(skb);
+
+ return NETDEV_TX_OK;
+--
+2.51.0
+
--- /dev/null
+From cf475e5585b6c59c748793c074198aba7d76e2f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:00 +0000
+Subject: net: mscc: ocelot: extract ocelot_xmit_timestamp() helper
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 29372f07f7969a2f0490793226ecf6c8c6bde0fa ]
+
+Extract the PTP timestamp handling logic from ocelot_port_xmit() into a
+separate ocelot_xmit_timestamp() helper function. This is a pure
+refactor with no behavioral change.
+
+The helper returns false if the skb was consumed (freed) due to a
+timestamp request failure, and true if the caller should continue with
+frame injection. The rew_op value is returned via pointer.
+
+This prepares for splitting ocelot_port_xmit() into separate FDMA and
+register injection paths in a subsequent patch.
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-2-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 36 ++++++++++++++++----------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index 50858cc10fef6..38d0c1af10a96 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -560,33 +560,41 @@ static int ocelot_port_stop(struct net_device *dev)
+ return 0;
+ }
+
+-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port,
++ struct sk_buff *skb, u32 *rew_op)
+ {
+- struct ocelot_port_private *priv = netdev_priv(dev);
+- struct ocelot_port *ocelot_port = &priv->port;
+- struct ocelot *ocelot = ocelot_port->ocelot;
+- int port = priv->port.index;
+- u32 rew_op = 0;
+-
+- if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
+- !ocelot_can_inject(ocelot, 0))
+- return NETDEV_TX_BUSY;
+-
+- /* Check if timestamping is needed */
+ if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ struct sk_buff *clone = NULL;
+
+ if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) {
+ kfree_skb(skb);
+- return NETDEV_TX_OK;
++ return false;
+ }
+
+ if (clone)
+ OCELOT_SKB_CB(skb)->clone = clone;
+
+- rew_op = ocelot_ptp_rew_op(skb);
++ *rew_op = ocelot_ptp_rew_op(skb);
+ }
+
++ return true;
++}
++
++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ struct ocelot_port_private *priv = netdev_priv(dev);
++ struct ocelot_port *ocelot_port = &priv->port;
++ struct ocelot *ocelot = ocelot_port->ocelot;
++ int port = priv->port.index;
++ u32 rew_op = 0;
++
++ if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
++ !ocelot_can_inject(ocelot, 0))
++ return NETDEV_TX_BUSY;
++
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ return NETDEV_TX_OK;
++
+ if (static_branch_unlikely(&ocelot_fdma_enabled)) {
+ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
+ } else {
+--
+2.51.0
+
--- /dev/null
+From b87c2fe91cfc6a078a62e07ed3672e1bab003d54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:01 +0000
+Subject: net: mscc: ocelot: split xmit into FDMA and register injection paths
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 47f79b20e7fb885aa1623b759a68e8e27401ec4d ]
+
+Split ocelot_port_xmit() into two separate functions:
+- ocelot_port_xmit_fdma(): handles the FDMA injection path
+- ocelot_port_xmit_inj(): handles the register-based injection path
+
+The top-level ocelot_port_xmit() now dispatches to the appropriate
+function based on the ocelot_fdma_enabled static key.
+
+This is a pure refactor with no behavioral change. Separating the two
+code paths makes each one simpler and prepares for adding proper locking
+to the register injection path without affecting the FDMA path.
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-3-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 39 ++++++++++++++++++++------
+ 1 file changed, 30 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index 38d0c1af10a96..14de948f72464 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -580,7 +580,25 @@ static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port,
+ return true;
+ }
+
+-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb,
++ struct net_device *dev)
++{
++ struct ocelot_port_private *priv = netdev_priv(dev);
++ struct ocelot_port *ocelot_port = &priv->port;
++ struct ocelot *ocelot = ocelot_port->ocelot;
++ int port = priv->port.index;
++ u32 rew_op = 0;
++
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ return NETDEV_TX_OK;
++
++ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
++
++ return NETDEV_TX_OK;
++}
++
++static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb,
++ struct net_device *dev)
+ {
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+@@ -588,24 +606,27 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
+ int port = priv->port.index;
+ u32 rew_op = 0;
+
+- if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
+- !ocelot_can_inject(ocelot, 0))
++ if (!ocelot_can_inject(ocelot, 0))
+ return NETDEV_TX_BUSY;
+
+ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
+ return NETDEV_TX_OK;
+
+- if (static_branch_unlikely(&ocelot_fdma_enabled)) {
+- ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
+- } else {
+- ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
++ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
+- consume_skb(skb);
+- }
++ consume_skb(skb);
+
+ return NETDEV_TX_OK;
+ }
+
++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ if (static_branch_unlikely(&ocelot_fdma_enabled))
++ return ocelot_port_xmit_fdma(skb, dev);
++
++ return ocelot_port_xmit_inj(skb, dev);
++}
++
+ enum ocelot_action_type {
+ OCELOT_MACT_LEARN,
+ OCELOT_MACT_FORGET,
+--
+2.51.0
+
--- /dev/null
+From b1817f119ac9636e9fc973fca7eb59033a326c43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:54:09 -0700
+Subject: net/rds: rds_sendmsg should not discard payload_len
+
+From: Allison Henderson <achender@kernel.org>
+
+[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ]
+
+Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with
+connection teardown") modifies rds_sendmsg to avoid enqueueing work
+while a tear down is in progress. However, it also changed the return
+value of rds_sendmsg to that of rds_send_xmit instead of the
+payload_len. This means the user may incorrectly receive errno values
+when it should have simply received a payload of 0 while the peer
+attempts a reconnections. So this patch corrects the teardown handling
+code to only use the out error path in that case, thus restoring the
+original payload_len return value.
+
+Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/send.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/rds/send.c b/net/rds/send.c
+index 0005fb43f2dfa..8aa06f7e4640c 100644
+--- a/net/rds/send.c
++++ b/net/rds/send.c
+@@ -1383,9 +1383,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
+ else
+ queue_delayed_work(rds_wq, &cpath->cp_send_w, 1);
+ rcu_read_unlock();
++
++ if (ret)
++ goto out;
+ }
+- if (ret)
+- goto out;
++
+ rds_message_put(rm);
+
+ for (ind = 0; ind < vct.indx; ind++)
+--
+2.51.0
+
--- /dev/null
+From aad5ab782f5b2ac6935235acbda3bccdef5813db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 12:56:39 +0100
+Subject: net: remove WARN_ON_ONCE when accessing forward path array
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ]
+
+Although unlikely, recent support for IPIP tunnels increases chances of
+reaching this WARN_ON_ONCE if userspace manages to build a sufficiently
+long forward path.
+
+Remove it.
+
+Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 69bb7ac73d047..c2ca0b45bd37d 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -695,7 +695,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack)
+ {
+ int k = stack->num_paths++;
+
+- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX))
++ if (k >= NET_DEVICE_PATH_STACK_MAX)
+ return NULL;
+
+ return &stack->path[k];
+--
+2.51.0
+
--- /dev/null
+From fbdfd52ef54aff85f3f00b6ff8923b0d1b9d10f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 14:44:01 +0100
+Subject: net: sparx5/lan969x: fix DWRR cost max to match hardware register
+ width
+
+From: Daniel Machon <daniel.machon@microchip.com>
+
+[ Upstream commit 6c28aa8dfdf24f554d4c5d4ff7d723a95360d94a ]
+
+DWRR (Deficit Weighted Round Robin) scheduling distributes bandwidth
+across traffic classes based on per-queue cost values, where lower cost
+means higher bandwidth share.
+
+The SPX5_DWRR_COST_MAX constant is 63 (6 bits) but the hardware
+register field HSCH_DWRR_ENTRY_DWRR_COST is GENMASK(24, 20), only
+5 bits wide (max 31). This causes sparx5_weight_to_hw_cost() to
+compute cost values that silently overflow via FIELD_PREP, resulting
+in incorrect scheduling weights.
+
+Set SPX5_DWRR_COST_MAX to 31 to match the hardware register width.
+
+Fixes: 211225428d65 ("net: microchip: sparx5: add support for offloading ets qdisc")
+Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260210-sparx5-fix-dwrr-cost-max-v1-1-58fbdbc25652@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
+index ced35033a6c5d..b1c6c5c6f16ca 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
+@@ -35,7 +35,7 @@
+ #define SPX5_SE_BURST_UNIT 4096
+
+ /* Dwrr */
+-#define SPX5_DWRR_COST_MAX 63
++#define SPX5_DWRR_COST_MAX 31
+
+ struct sparx5_shaper {
+ u32 mode;
+--
+2.51.0
+
--- /dev/null
+From 876abfc0b56c986d888d66210b67a51b2815eb19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 12:02:30 +0100
+Subject: net: sparx5/lan969x: fix PTP clock max_adj value
+
+From: Daniel Machon <daniel.machon@microchip.com>
+
+[ Upstream commit a49d2a2c37a6252c41cbdd505f9d1c58d5a3817a ]
+
+The max_adj field in ptp_clock_info tells userspace how much the PHC
+clock frequency can be adjusted. ptp4l reads this and will never request
+a correction larger than max_adj.
+
+On both sparx5 and lan969x the clock offset may never converge because
+the servo needs a frequency correction larger than the current max_adj
+of 200000 (200 ppm) allows. The servo rails at the max and the offset
+stays in the tens of microseconds.
+
+The hardware has no inherent max adjustment limit; frequency correction
+is done by writing a 64-bit clock period increment to CLK_PER_CFG, and
+the register has plenty of range. The 200000 value was just an overly
+conservative software limit. The max_adj is shared between sparx5 and
+lan969x, and the increased value is safe for both.
+
+Fix this by increasing max_adj to 10000000 (10000 ppm), giving the
+servo sufficient headroom.
+
+Fixes: 0933bd04047c ("net: sparx5: Add support for ptp clocks")
+Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260212-sparx5-ptp-max-adj-v2-v1-1-06b200e50ce3@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+index 69e76634f9aa8..9c602f19d43b0 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+@@ -565,7 +565,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+ static struct ptp_clock_info sparx5_ptp_clock_info = {
+ .owner = THIS_MODULE,
+ .name = "sparx5 ptp",
+- .max_adj = 200000,
++ .max_adj = 10000000,
+ .gettime64 = sparx5_ptp_gettime64,
+ .settime64 = sparx5_ptp_settime64,
+ .adjtime = sparx5_ptp_adjtime,
+--
+2.51.0
+
--- /dev/null
+From c7ab34984e996eab21806bebca059a434070d042 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 21:41:54 +0000
+Subject: net: usb: catc: enable basic endpoint checking
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ]
+
+catc_probe() fills three URBs with hardcoded endpoint pipes without
+verifying the endpoint descriptors:
+
+ - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX
+ - usb_rcvintpipe(usbdev, 2) for interrupt status
+
+A malformed USB device can present these endpoints with transfer types
+that differ from what the driver assumes.
+
+Add a catc_usb_ep enum for endpoint numbers, replacing magic constants
+throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints()
+calls after usb_set_interface() to verify endpoint types before use,
+rejecting devices with mismatched descriptors at probe time.
+
+Similar to
+- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking")
+which fixed the issue in rtl8150.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Suggested-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------
+ 1 file changed, 31 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
+index ff439ef535ac9..98346cb4ece01 100644
+--- a/drivers/net/usb/catc.c
++++ b/drivers/net/usb/catc.c
+@@ -64,6 +64,16 @@ static const char driver_name[] = "catc";
+ #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */
+ #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */
+
++/*
++ * USB endpoints.
++ */
++
++enum catc_usb_ep {
++ CATC_USB_EP_CONTROL = 0,
++ CATC_USB_EP_BULK = 1,
++ CATC_USB_EP_INT_IN = 2,
++};
++
+ /*
+ * Control requests.
+ */
+@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ u8 broadcast[ETH_ALEN];
+ u8 *macbuf;
+ int pktsz, ret = -ENOMEM;
++ static const u8 bulk_ep_addr[] = {
++ CATC_USB_EP_BULK | USB_DIR_OUT,
++ CATC_USB_EP_BULK | USB_DIR_IN,
++ 0};
++ static const u8 int_ep_addr[] = {
++ CATC_USB_EP_INT_IN | USB_DIR_IN,
++ 0};
+
+ macbuf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if (!macbuf)
+@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ goto fail_mem;
+ }
+
++ /* Verify that all required endpoints are present */
++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
++ !usb_check_int_endpoints(intf, int_ep_addr)) {
++ dev_err(dev, "Missing or invalid endpoints\n");
++ ret = -ENODEV;
++ goto fail_mem;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct catc));
+ if (!netdev)
+ goto fail_mem;
+@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0),
+ NULL, NULL, 0, catc_ctrl_done, catc);
+
+- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1),
+- NULL, 0, catc_tx_done, catc);
++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK),
++ NULL, 0, catc_tx_done, catc);
+
+- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1),
+- catc->rx_buf, pktsz, catc_rx_done, catc);
++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK),
++ catc->rx_buf, pktsz, catc_rx_done, catc);
+
+- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2),
+- catc->irq_buf, 2, catc_irq_done, catc, 1);
++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN),
++ catc->irq_buf, 2, catc_irq_done, catc, 1);
+
+ if (!catc->is_f5u011) {
+ u32 *buf;
+--
+2.51.0
+
--- /dev/null
+From 66893b72ae77860a5223e9346bbfb3eca5042dfb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 12:53:09 +0100
+Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ]
+
+Mihail Milev reports: Error: UNINIT (CWE-457):
+ net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl:
+ Declaring variable "tuple" without initializer.
+ net/netfilter/nf_conntrack_h323_main.c:1197:2:
+ uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find".
+ net/netfilter/nf_conntrack_expect.c:142:2:
+ read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash".
+
+ 1195| tuple.dst.protonum = IPPROTO_TCP;
+ 1196|
+ 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ 1198| if (exp && exp->master == ct)
+ 1199| return exp;
+
+Switch this to a C99 initialiser and set the l3num value.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_h323_main.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
+index 5a9bce24f3c3d..ed983421e2eb2 100644
+--- a/net/netfilter/nf_conntrack_h323_main.c
++++ b/net/netfilter/nf_conntrack_h323_main.c
+@@ -1186,13 +1186,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
+ {
+ struct net *net = nf_ct_net(ct);
+ struct nf_conntrack_expect *exp;
+- struct nf_conntrack_tuple tuple;
++ struct nf_conntrack_tuple tuple = {
++ .src.l3num = nf_ct_l3num(ct),
++ .dst.protonum = IPPROTO_TCP,
++ .dst.u.tcp.port = port,
++ };
+
+- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3));
+- tuple.src.u.tcp.port = 0;
+ memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3));
+- tuple.dst.u.tcp.port = port;
+- tuple.dst.protonum = IPPROTO_TCP;
+
+ exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ if (exp && exp->master == ct)
+--
+2.51.0
+
--- /dev/null
+From 1ea327247645ea488480c1e7dcdf5fcaf9802602 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 21:14:40 +0900
+Subject: netfilter: nf_tables: fix use-after-free in nf_tables_addchain()
+
+From: Inseo An <y0un9sa@gmail.com>
+
+[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ]
+
+nf_tables_addchain() publishes the chain to table->chains via
+list_add_tail_rcu() (in nft_chain_add()) before registering hooks.
+If nf_tables_register_hook() then fails, the error path calls
+nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy()
+with no RCU grace period in between.
+
+This creates two use-after-free conditions:
+
+ 1) Control-plane: nf_tables_dump_chains() traverses table->chains
+ under rcu_read_lock(). A concurrent dump can still be walking
+ the chain when the error path frees it.
+
+ 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly
+ installs the IPv4 hook before IPv6 registration fails. Packets
+ entering nft_do_chain() via the transient IPv4 hook can still be
+ dereferencing chain->blob_gen_X when the error path frees the
+ chain.
+
+Add synchronize_rcu() between nft_chain_del() and the chain destroy
+so that all RCU readers -- both dump threads and in-flight packet
+evaluation -- have finished before the chain is freed.
+
+Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain")
+Signed-off-by: Inseo An <y0un9sa@gmail.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 67729d7c913a4..ac36183956515 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -2510,6 +2510,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
+
+ err_register_hook:
+ nft_chain_del(chain);
++ synchronize_rcu();
+ err_chain_add:
+ nft_trans_destroy(trans);
+ err_trans:
+--
+2.51.0
+
--- /dev/null
+From ed70285c8ce7285d634be3e3cb41b8c030f934ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:33:38 +0530
+Subject: octeontx2-af: Fix default entries mcam entry action
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ]
+
+As per design, AF should update the default MCAM action only when
+mcam_index is -1. A bug in the previous patch caused default entries
+to be changed even when the request was not for them.
+
+Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++---------
+ 1 file changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+index 00ef6d201b973..9b8a6046e6dff 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+@@ -1070,32 +1070,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
+ rvu_write64(rvu, blkaddr,
+ NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action);
+
+- /* update the VF flow rule action with the VF default entry action */
+- if (mcam_index < 0)
+- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
+- *(u64 *)&action);
+-
+ /* update the action change in default rule */
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+ if (pfvf->def_ucast_rule)
+ pfvf->def_ucast_rule->rx_action = action;
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_PROMISC_ENTRY);
++ if (mcam_index < 0) {
++ /* update the VF flow rule action with the VF default
++ * entry action
++ */
++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
++ *(u64 *)&action);
+
+- /* If PF's promiscuous entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_PROMISC_ENTRY);
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_ALLMULTI_ENTRY);
+- /* If PF's allmulti entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ /* If PF's promiscuous entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_ALLMULTI_ENTRY);
++ /* If PF's allmulti entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++ }
+ }
+
+ void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc,
+--
+2.51.0
+
--- /dev/null
+From 308ea5f2a0f779b41f3637c85608d9d8b2e8e46b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:01:49 +0000
+Subject: ping: annotate data-races in ping_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit ad5dfde2a5733aaf652ea3e40c8c5e071e935901 ]
+
+isk->inet_num, isk->inet_rcv_saddr and sk->sk_bound_dev_if
+are read locklessly in ping_lookup().
+
+Add READ_ONCE()/WRITE_ONCE() annotations.
+
+The race on isk->inet_rcv_saddr is probably coming from IPv6 support,
+but does not deserve a specific backport.
+
+Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216100149.3319315-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ping.c | 31 +++++++++++++++++++------------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index ee0e2df5d62e0..effe91a19a7a2 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -159,7 +159,7 @@ void ping_unhash(struct sock *sk)
+ pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+ spin_lock(&ping_table.lock);
+ if (sk_del_node_init_rcu(sk)) {
+- isk->inet_num = 0;
++ WRITE_ONCE(isk->inet_num, 0);
+ isk->inet_sport = 0;
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+ }
+@@ -192,31 +192,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ }
+
+ sk_for_each_rcu(sk, hslot) {
++ int bound_dev_if;
++
+ if (!net_eq(sock_net(sk), net))
+ continue;
+ isk = inet_sk(sk);
+
+ pr_debug("iterate\n");
+- if (isk->inet_num != ident)
++ if (READ_ONCE(isk->inet_num) != ident)
+ continue;
+
++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+ if (skb->protocol == htons(ETH_P_IP) &&
+ sk->sk_family == AF_INET) {
++ __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr);
++
+ pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk,
+- (int) isk->inet_num, &isk->inet_rcv_saddr,
+- sk->sk_bound_dev_if);
++ ident, &rcv_saddr,
++ bound_dev_if);
+
+- if (isk->inet_rcv_saddr &&
+- isk->inet_rcv_saddr != ip_hdr(skb)->daddr)
++ if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr)
+ continue;
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (skb->protocol == htons(ETH_P_IPV6) &&
+ sk->sk_family == AF_INET6) {
+
+ pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk,
+- (int) isk->inet_num,
++ ident,
+ &sk->sk_v6_rcv_saddr,
+- sk->sk_bound_dev_if);
++ bound_dev_if);
+
+ if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) &&
+ !ipv6_addr_equal(&sk->sk_v6_rcv_saddr,
+@@ -227,8 +231,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ continue;
+ }
+
+- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
+- sk->sk_bound_dev_if != sdif)
++ if (bound_dev_if && bound_dev_if != dif &&
++ bound_dev_if != sdif)
+ continue;
+
+ goto exit;
+@@ -403,7 +407,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr *saddr)
+ if (saddr->sa_family == AF_INET) {
+ struct inet_sock *isk = inet_sk(sk);
+ struct sockaddr_in *addr = (struct sockaddr_in *) saddr;
+- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
++
++ isk->inet_saddr = addr->sin_addr.s_addr;
++ WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr);
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (saddr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr;
+@@ -865,7 +871,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
+ struct sk_buff *skb;
+ int copied, err;
+
+- pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
++ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk,
++ READ_ONCE(isk->inet_num));
+
+ err = -EOPNOTSUPP;
+ if (flags & MSG_OOB)
+--
+2.51.0
+
--- /dev/null
+From 0e97fd963474046c32a5bbbcb5de5d483a810371 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 May 2023 14:54:43 -0700
+Subject: ping: Convert hlist_nulls to plain hlist.
+
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+
+[ Upstream commit f1b5dfe63f6a9eb17948cbaee4da4b66f51ac794 ]
+
+Since introduced in commit c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP
+socket kind"), ping socket does not use SLAB_TYPESAFE_BY_RCU nor check
+nulls marker in loops.
+
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: ad5dfde2a573 ("ping: annotate data-races in ping_lookup()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ping.c | 41 +++++++++++++++--------------------------
+ 1 file changed, 15 insertions(+), 26 deletions(-)
+
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index cadf743ab4f52..aae5ad6303a97 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -49,13 +49,8 @@
+ #include <net/transp_v6.h>
+ #endif
+
+-#define ping_portaddr_for_each_entry(__sk, node, list) \
+- hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
+-#define ping_portaddr_for_each_entry_rcu(__sk, node, list) \
+- hlist_nulls_for_each_entry_rcu(__sk, node, list, sk_nulls_node)
+-
+ struct ping_table {
+- struct hlist_nulls_head hash[PING_HTABLE_SIZE];
++ struct hlist_head hash[PING_HTABLE_SIZE];
+ spinlock_t lock;
+ };
+
+@@ -74,17 +69,16 @@ static inline u32 ping_hashfn(const struct net *net, u32 num, u32 mask)
+ }
+ EXPORT_SYMBOL_GPL(ping_hash);
+
+-static inline struct hlist_nulls_head *ping_hashslot(struct ping_table *table,
+- struct net *net, unsigned int num)
++static inline struct hlist_head *ping_hashslot(struct ping_table *table,
++ struct net *net, unsigned int num)
+ {
+ return &table->hash[ping_hashfn(net, num, PING_HTABLE_MASK)];
+ }
+
+ int ping_get_port(struct sock *sk, unsigned short ident)
+ {
+- struct hlist_nulls_node *node;
+- struct hlist_nulls_head *hlist;
+ struct inet_sock *isk, *isk2;
++ struct hlist_head *hlist;
+ struct sock *sk2 = NULL;
+
+ isk = inet_sk(sk);
+@@ -98,7 +92,7 @@ int ping_get_port(struct sock *sk, unsigned short ident)
+ result++; /* avoid zero */
+ hlist = ping_hashslot(&ping_table, sock_net(sk),
+ result);
+- ping_portaddr_for_each_entry(sk2, node, hlist) {
++ sk_for_each(sk2, hlist) {
+ isk2 = inet_sk(sk2);
+
+ if (isk2->inet_num == result)
+@@ -115,7 +109,7 @@ int ping_get_port(struct sock *sk, unsigned short ident)
+ goto fail;
+ } else {
+ hlist = ping_hashslot(&ping_table, sock_net(sk), ident);
+- ping_portaddr_for_each_entry(sk2, node, hlist) {
++ sk_for_each(sk2, hlist) {
+ isk2 = inet_sk(sk2);
+
+ /* BUG? Why is this reuse and not reuseaddr? ping.c
+@@ -133,9 +127,8 @@ int ping_get_port(struct sock *sk, unsigned short ident)
+ isk->inet_num = ident;
+ if (sk_unhashed(sk)) {
+ pr_debug("was not hashed\n");
+- sock_hold(sk);
++ sk_add_node_rcu(sk, hlist);
+ sock_set_flag(sk, SOCK_RCU_FREE);
+- hlist_nulls_add_head_rcu(&sk->sk_nulls_node, hlist);
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+ }
+ spin_unlock(&ping_table.lock);
+@@ -161,9 +154,7 @@ void ping_unhash(struct sock *sk)
+
+ pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+ spin_lock(&ping_table.lock);
+- if (sk_hashed(sk)) {
+- hlist_nulls_del_init_rcu(&sk->sk_nulls_node);
+- sock_put(sk);
++ if (sk_del_node_init_rcu(sk)) {
+ isk->inet_num = 0;
+ isk->inet_sport = 0;
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+@@ -175,10 +166,9 @@ EXPORT_SYMBOL_GPL(ping_unhash);
+ /* Called under rcu_read_lock() */
+ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ {
+- struct hlist_nulls_head *hslot = ping_hashslot(&ping_table, net, ident);
++ struct hlist_head *hslot = ping_hashslot(&ping_table, net, ident);
+ struct sock *sk = NULL;
+ struct inet_sock *isk;
+- struct hlist_nulls_node *hnode;
+ int dif, sdif;
+
+ if (skb->protocol == htons(ETH_P_IP)) {
+@@ -197,7 +187,7 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ return NULL;
+ }
+
+- ping_portaddr_for_each_entry_rcu(sk, hnode, hslot) {
++ sk_for_each_rcu(sk, hslot) {
+ isk = inet_sk(sk);
+
+ pr_debug("iterate\n");
+@@ -1043,15 +1033,14 @@ static struct sock *ping_get_first(struct seq_file *seq, int start)
+
+ for (state->bucket = start; state->bucket < PING_HTABLE_SIZE;
+ ++state->bucket) {
+- struct hlist_nulls_node *node;
+- struct hlist_nulls_head *hslot;
++ struct hlist_head *hslot;
+
+ hslot = &ping_table.hash[state->bucket];
+
+- if (hlist_nulls_empty(hslot))
++ if (hlist_empty(hslot))
+ continue;
+
+- sk_nulls_for_each(sk, node, hslot) {
++ sk_for_each(sk, hslot) {
+ if (net_eq(sock_net(sk), net) &&
+ sk->sk_family == state->family)
+ goto found;
+@@ -1068,7 +1057,7 @@ static struct sock *ping_get_next(struct seq_file *seq, struct sock *sk)
+ struct net *net = seq_file_net(seq);
+
+ do {
+- sk = sk_nulls_next(sk);
++ sk = sk_next(sk);
+ } while (sk && (!net_eq(sock_net(sk), net)));
+
+ if (!sk)
+@@ -1204,6 +1193,6 @@ void __init ping_init(void)
+ int i;
+
+ for (i = 0; i < PING_HTABLE_SIZE; i++)
+- INIT_HLIST_NULLS_HEAD(&ping_table.hash[i], i);
++ INIT_HLIST_HEAD(&ping_table.hash[i]);
+ spin_lock_init(&ping_table.lock);
+ }
+--
+2.51.0
+
--- /dev/null
+From 95205166306b73bd8ff367fec4e3ecabeb19eff8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 1 Mar 2023 09:41:06 +0100
+Subject: s390/Kconfig: sort config S390 select list again
+
+From: Heiko Carstens <hca@linux.ibm.com>
+
+[ Upstream commit 6ca6b58107a8891e4b08087843188fdc5737ec08 ]
+
+Keep the config S390 select list sorted.
+
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Stable-dep-of: dd3411959b57 ("s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index ef87c38a7b841..bceed8361d051 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -120,8 +120,8 @@ config S390
+ select ARCH_WANTS_DYNAMIC_TASK_STRUCT
+ select ARCH_WANTS_NO_INSTR
+ select ARCH_WANT_DEFAULT_BPF_JIT
+- select ARCH_WANT_IPC_PARSE_VERSION
+ select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
++ select ARCH_WANT_IPC_PARSE_VERSION
+ select BUILDTIME_TABLE_SORT
+ select CLONE_BACKWARDS2
+ select DMA_OPS if PCI
+@@ -194,6 +194,7 @@ config S390
+ select HAVE_PERF_USER_STACK_DUMP
+ select HAVE_REGS_AND_STACK_ACCESS_API
+ select HAVE_RELIABLE_STACKTRACE
++ select HAVE_RETHOOK
+ select HAVE_RSEQ
+ select HAVE_SAMPLE_FTRACE_DIRECT
+ select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
+@@ -203,9 +204,9 @@ config S390
+ select HAVE_VIRT_CPU_ACCOUNTING_IDLE
+ select IOMMU_HELPER if PCI
+ select IOMMU_SUPPORT if PCI
++ select MMU_GATHER_MERGE_VMAS
+ select MMU_GATHER_NO_GATHER
+ select MMU_GATHER_RCU_TABLE_FREE
+- select MMU_GATHER_MERGE_VMAS
+ select MODULES_USE_ELF_RELA
+ select NEED_DMA_MAP_STATE if PCI
+ select NEED_SG_DMA_LENGTH if PCI
+--
+2.51.0
+
--- /dev/null
+From d0e348e682c13febce498f807c6fdd2f479087a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 07:29:16 +0100
+Subject: s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n
+
+From: Alexander Egorenkov <egorenar@linux.ibm.com>
+
+[ Upstream commit dd3411959b57df6e05a3ccbac67b0a836871c0c4 ]
+
+The commit c8424e776b09 ("MODSIGN: Export module signature definitions")
+replaced the dependency of KEXEC_SIG on SYSTEM_DATA_VERIFICATION with the
+dependency on MODULE_SIG_FORMAT. This change disables KEXEC_SIG in s390
+kernels built with MODULES=n if nothing else selects MODULE_SIG_FORMAT.
+
+Furthermore, the signature verification in s390 kexec does not require
+MODULE_SIG_FORMAT because it requires only the struct module_signature and,
+therefore, does not depend on code in kernel/module_signature.c.
+
+But making ARCH_SUPPORTS_KEXEC_SIG depend on SYSTEM_DATA_VERIFICATION is
+also incorrect because it makes KEXEC_SIG available on s390 only if some
+other arbitrary option (for instance a file system or device driver)
+selects it directly or indirectly.
+
+To properly make KEXEC_SIG available for s390 kernels built with MODULES=y
+as well as MODULES=n _and_ also not depend on arbitrary options selecting
+SYSTEM_DATA_VERIFICATION, set ARCH_SUPPORTS_KEXEC_SIG=y for s390 and select
+SYSTEM_DATA_VERIFICATION when KEXEC_SIG=y.
+
+Fixes: c8424e776b09 ("MODSIGN: Export module signature definitions")
+Suggested-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 645ab7c065c8d..f0f96ae84cc70 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -219,6 +219,7 @@ config S390
+ select SPARSE_IRQ
+ select SWIOTLB
+ select SYSCTL_EXCEPTION_TRACE
++ select SYSTEM_DATA_VERIFICATION if KEXEC_SIG
+ select THREAD_INFO_IN_TASK
+ select TRACE_IRQFLAGS_SUPPORT
+ select TTY
+@@ -245,7 +246,7 @@ config ARCH_SUPPORTS_KEXEC_FILE
+ def_bool CRYPTO && CRYPTO_SHA256 && CRYPTO_SHA256_S390
+
+ config ARCH_SUPPORTS_KEXEC_SIG
+- def_bool MODULE_SIG_FORMAT
++ def_bool y
+
+ config ARCH_HAS_KEXEC_PURGATORY
+ def_bool KEXEC_FILE
+--
+2.51.0
+
--- /dev/null
+From d6af6983bb2036fe740cb4127145d0fad0d5aa9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Jul 2023 12:15:43 -0400
+Subject: s390/kexec: refactor for kernel/Kconfig.kexec
+
+From: Eric DeVolder <eric.devolder@oracle.com>
+
+[ Upstream commit 75239cf775b811662f3a9e35e8ea0cd7a98e3fed ]
+
+The kexec and crash kernel options are provided in the common
+kernel/Kconfig.kexec. Utilize the common options and provide
+the ARCH_SUPPORTS_ and ARCH_SELECTS_ entries to recreate the
+equivalent set of KEXEC and CRASH options.
+
+Link: https://lkml.kernel.org/r/20230712161545.87870-13-eric.devolder@oracle.com
+Signed-off-by: Eric DeVolder <eric.devolder@oracle.com>
+Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: dd3411959b57 ("s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig | 69 ++++++++++++++++-------------------------------
+ 1 file changed, 23 insertions(+), 46 deletions(-)
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index bceed8361d051..645ab7c065c8d 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -204,6 +204,7 @@ config S390
+ select HAVE_VIRT_CPU_ACCOUNTING_IDLE
+ select IOMMU_HELPER if PCI
+ select IOMMU_SUPPORT if PCI
++ select KEXEC
+ select MMU_GATHER_MERGE_VMAS
+ select MMU_GATHER_NO_GATHER
+ select MMU_GATHER_RCU_TABLE_FREE
+@@ -234,6 +235,28 @@ config PGTABLE_LEVELS
+
+ source "kernel/livepatch/Kconfig"
+
++config ARCH_DEFAULT_KEXEC
++ def_bool y
++
++config ARCH_SUPPORTS_KEXEC
++ def_bool y
++
++config ARCH_SUPPORTS_KEXEC_FILE
++ def_bool CRYPTO && CRYPTO_SHA256 && CRYPTO_SHA256_S390
++
++config ARCH_SUPPORTS_KEXEC_SIG
++ def_bool MODULE_SIG_FORMAT
++
++config ARCH_HAS_KEXEC_PURGATORY
++ def_bool KEXEC_FILE
++
++config ARCH_SUPPORTS_CRASH_DUMP
++ def_bool y
++ help
++ Refer to <file:Documentation/s390/zfcpdump.rst> for more details on this.
++ This option also enables s390 zfcpdump.
++ See also <file:Documentation/s390/zfcpdump.rst>
++
+ menu "Processor type and features"
+
+ config HAVE_MARCH_Z10_FEATURES
+@@ -480,36 +503,6 @@ config SCHED_TOPOLOGY
+
+ source "kernel/Kconfig.hz"
+
+-config KEXEC
+- def_bool y
+- select KEXEC_CORE
+-
+-config KEXEC_FILE
+- bool "kexec file based system call"
+- select KEXEC_CORE
+- depends on CRYPTO
+- depends on CRYPTO_SHA256
+- depends on CRYPTO_SHA256_S390
+- help
+- Enable the kexec file based system call. In contrast to the normal
+- kexec system call this system call takes file descriptors for the
+- kernel and initramfs as arguments.
+-
+-config ARCH_HAS_KEXEC_PURGATORY
+- def_bool y
+- depends on KEXEC_FILE
+-
+-config KEXEC_SIG
+- bool "Verify kernel signature during kexec_file_load() syscall"
+- depends on KEXEC_FILE && MODULE_SIG_FORMAT
+- help
+- This option makes kernel signature verification mandatory for
+- the kexec_file_load() syscall.
+-
+- In addition to that option, you need to enable signature
+- verification for the corresponding kernel image type being
+- loaded in order for this to work.
+-
+ config KERNEL_NOBP
+ def_bool n
+ prompt "Enable modified branch prediction for the kernel by default"
+@@ -728,22 +721,6 @@ config VFIO_AP
+
+ endmenu
+
+-menu "Dump support"
+-
+-config CRASH_DUMP
+- bool "kernel crash dumps"
+- select KEXEC
+- help
+- Generate crash dump after being started by kexec.
+- Crash dump kernels are loaded in the main kernel with kexec-tools
+- into a specially reserved region and then later executed after
+- a crash by kdump/kexec.
+- Refer to <file:Documentation/s390/zfcpdump.rst> for more details on this.
+- This option also enables s390 zfcpdump.
+- See also <file:Documentation/s390/zfcpdump.rst>
+-
+-endmenu
+-
+ config CCW
+ def_bool y
+
+--
+2.51.0
+
--- /dev/null
+From 15f5cbe846e3035b2f30ae88bbf0d4f6c940711b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Jul 2022 11:08:37 +0200
+Subject: s390: select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
+
+From: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+
+[ Upstream commit 00a34d5a99c0631bd780b14cbe3813d0b39c3886 ]
+
+Enable HUGETLB_PAGE_OPTIMIZE_VMEMMAP for s390.
+
+With this, vmemmap pages used to back struct pages for compound tail
+pages of hugetlb pages are freed and remapped to compound head page
+frame as RO, see also Documentation/vm/vmemmap_dedup.rst.
+
+For 1M hugetlb pages, this results in freeing 3 of 4 vmemmap pages,
+saving 12K of memory for each 1M hugetlb page (~1.2%).
+/sys/kernel/debug/kernel_page_tables will show the impact:
+
+---[ vmemmap Area Start ]---
+[...]
+0x0000037202d84000-0x0000037202d85000 4K PTE RW NX
+0x0000037202d85000-0x0000037202d88000 12K PTE RO NX
+
+For 2G hugetlb pages, this results in freeing 8191 of 8192 vmemmap
+pages, saving 32764K of memory for each 2G hugetlb page (~1.6%)
+/sys/kernel/debug/kernel_page_tables will show the impact:
+
+---[ vmemmap Area Start ]---
+[...]
+0x000003720a000000-0x000003720a001000 4K PTE RW NX
+0x000003720a001000-0x000003720c000000 32764K PTE RO NX
+
+The memory savings come with some costs:
+- vmemmap mapping for compound hugetlb pages is not a PMD mapping any
+ more, but split to 4K PTE mappings, and it will not be coalesced back
+ to PMD mapping after freeing hugetlb pages from the pool.
+ Apart from theoretical performance impact, this will also (slightly)
+ relativize the memory savings because of additional 2K PTE pagetable
+ allocations.
+- Workload using "on the fly" hugetlb allocations via
+ "nr_overcommit_hugepages" instead of using the hugetlb pool via
+ "nr_hugepages" will suffer from considerably increased fault handling
+ time, see also description from commit 78f39084b41d
+ ("mm: hugetlb_vmemmap: add hugetlb_optimize_vmemmap sysctl").
+- Freeing hugetlb pages from the pool will require re-allocation of the
+ freed struct pages, and therefore needs some memory available to the
+ kernel. This might fail in memory constrained scenarios.
+- For the same reason, memory offline might fail even for ZONE_MOVABLE
+ when hugetlb pages are present (but not for s390, since we do not
+ support ARCH_ENABLE_HUGEPAGE_MIGRATION, and therefore cannot have
+ hugetlb pages in ZONE_MOVABLE).
+- General increased complexity and overhead in kernel handling of
+ compound (head) pages.
+
+Therefore, this feature is disabled by default, and has to be enabled
+explicitly either by adding "hugetlb_free_vmemmap=on" kernel parameter,
+or during run-time via "/proc/sys/vm/hugetlb_optimize_vmemmap" sysctl.
+
+Acked-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Stable-dep-of: dd3411959b57 ("s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index de575af02ffea..ef87c38a7b841 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -121,6 +121,7 @@ config S390
+ select ARCH_WANTS_NO_INSTR
+ select ARCH_WANT_DEFAULT_BPF_JIT
+ select ARCH_WANT_IPC_PARSE_VERSION
++ select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP
+ select BUILDTIME_TABLE_SORT
+ select CLONE_BACKWARDS2
+ select DMA_OPS if PCI
+--
+2.51.0
+
--- /dev/null
+From 90cea357a2a3759175455e5615e39542609c040f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:05 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with
+ br_netfilter enabled
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv4 packet contains a zero IP header checksum. After VXLAN
+decapsulation, such packets do not pass sanity checks in br_netfilter
+and are dropped, which causes the test to fail.
+
+Fix this by calculating and setting a valid IPv4 header checksum for the
+encapsulated packet generated by mausezahn, so that the packet is accepted
+by br_netfilter. Fixed by using the payload_template_calc_checksum() /
+payload_template_expand_checksum() helpers that are only available
+in v6.3 and newer kernels.
+
+Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++-------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+index eb307ca37bfa6..002551451a728 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+@@ -559,6 +559,21 @@ vxlan_encapped_ping_do()
+ local inner_tos=$1; shift
+ local outer_tos=$1; shift
+
++ local ipv4hdr=$(:
++ )"45:"$( : IP version + IHL
++ )"$inner_tos:"$( : IP TOS
++ )"00:54:"$( : IP total length
++ )"99:83:"$( : IP identification
++ )"40:00:"$( : IP flags + frag off
++ )"40:"$( : IP TTL
++ )"01:"$( : IP proto
++ )"CHECKSUM:"$( : IP header csum
++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1
++ )
++ local checksum=$(payload_template_calc_checksum "$ipv4hdr")
++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum)
++
+ $MZ $dev -c $count -d 100msec -q \
+ -b $next_hop_mac -B $dest_ip \
+ -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(:
+@@ -569,16 +584,7 @@ vxlan_encapped_ping_do()
+ )"$dest_mac:"$( : ETH daddr
+ )"$(mac_get w2):"$( : ETH saddr
+ )"08:00:"$( : ETH type
+- )"45:"$( : IP version + IHL
+- )"$inner_tos:"$( : IP TOS
+- )"00:54:"$( : IP total length
+- )"99:83:"$( : IP identification
+- )"40:00:"$( : IP flags + frag off
+- )"40:"$( : IP TTL
+- )"01:"$( : IP proto
+- )"00:00:"$( : IP header csum
+- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
+- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1
++ )"$ipv4hdr:"$( : IPv4 header
+ )"08:"$( : ICMP type
+ )"00:"$( : ICMP code
+ )"8b:f2:"$( : ICMP csum
+--
+2.51.0
+
--- /dev/null
+From 8fbd7b6fb4fc01665491deb8e05a1448e45db74f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:06 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with
+ br_netfilter enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit ce9f6aec0fb780dafc1dfc5f47c688422aff464a ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv6 packet has an incorrect payload length set in the IPv6 header.
+After VXLAN decapsulation, such packets do not pass sanity checks in
+br_netfilter and are dropped, which causes the test to fail.
+
+Fix this by setting the correct IPv6 payload length for the encapsulated
+packet generated by mausezahn, so that the packet is accepted
+by br_netfilter.
+
+tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+lines 698-706
+
+ )"00:03:"$( : Payload length
+ )"3a:"$( : Next header
+ )"04:"$( : Hop limit
+ )"$saddr:"$( : IP saddr
+ )"$daddr:"$( : IP daddr
+ )"80:"$( : ICMPv6.type
+ )"00:"$( : ICMPv6.code
+ )"00:"$( : ICMPv6.checksum
+ )
+
+Data after IPv6 header:
+• 80: — 1 byte (ICMPv6 type)
+• 00: — 1 byte (ICMPv6 code)
+• 00: — 1 byte (ICMPv6 checksum, truncated)
+
+Total: 3 bytes → 00:03 is correct. The old value 00:08 did not match
+the actual payload size.
+
+Fixes: b07e9957f220 ("selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for IPv6")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-3-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+index bd3f7d492af2b..28284a5aa07a9 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+@@ -695,7 +695,7 @@ vxlan_encapped_ping_do()
+ )"6"$( : IP version
+ )"$inner_tos"$( : Traffic class
+ )"0:00:00:"$( : Flow label
+- )"00:08:"$( : Payload length
++ )"00:03:"$( : Payload length
+ )"3a:"$( : Next header
+ )"04:"$( : Hop limit
+ )"$saddr:"$( : IP saddr
+--
+2.51.0
+
--- /dev/null
+From 4019b487622092c4074ba5c2b1ed32893e10c8f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 14:53:53 +0100
+Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ]
+
+As explained in [1], iproute2 started rejecting tc-police burst sizes
+that result in an overflow. This can happen when the burst size is high
+enough and the rate is low enough.
+
+A couple of test cases specify such configurations, resulting in
+iproute2 errors and test failure.
+
+Fix by reducing the burst size so that the test will pass with both new
+and old iproute2 versions.
+
+[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/
+
+Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+index 0441a18f098b1..aac8ef490feb8 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+@@ -317,7 +317,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 0.5kbit burst 1m conform-exceed drop/ok
++ action police rate 0.5kbit burst 2k conform-exceed drop/ok
+ check_fail $? "Incorrect success to add police action with too low rate"
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+@@ -327,7 +327,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 1.5kbit burst 1m conform-exceed drop/ok
++ action police rate 1.5kbit burst 2k conform-exceed drop/ok
+ check_err $? "Failed to add police action with low rate"
+
+ tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
+--
+2.51.0
+
--- /dev/null
+From ad1fbdecce232b59495a7e35fa36c013798caf83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 19:51:59 -0800
+Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ]
+
+Since we started running selftests in NIPA we have been seeing
+tc_actions.sh generate a soft lockup warning on ~20% of the runs.
+On the pre-netdev foundation setup it was actually a missed irq
+splat from the console. Now it's either that or a lockup.
+
+I initially suspected a socket locking issue since the test
+is exercising local loopback with act_mirred.
+After hours of staring at this I noticed in strace that ncat
+when -o $file is specified _both_ saves the output to the file
+and still prints it to stdout. Because the file being sent
+is constructed with:
+
+ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred
+ ^^^^^^^^^
+
+the data printed is all \0. Most terminals don't display nul
+characters (and neither does vng output capture save them).
+But QEMU's serial console still has to poke them thru which
+is very slow and causes the lockup (if the file is >600kB).
+
+Replace the '-o $file' with '> $file'. This speeds the test up
+from 2m20s to 18s on debug kernels, and prevents the warnings.
+
+Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index b0f5e55d2d0b2..0d891c2045802 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -222,7 +222,7 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 &
+ local rpid=$!
+ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+--
+2.51.0
+
io_uring-cancel-add-ioring_async_cancel_userdata.patch
io_uring-cancel-support-opcode-based-lookup-and-canc.patch
io_uring-cancel-de-unionize-file-and-user_data-in-st.patch
+fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch
+fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch
+acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch
+acpi-pm-add-unused-power-resource-quirk-for-thundero.patch
+cpuidle-skip-governor-when-only-one-idle-state-is-av.patch
+selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch
+net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch
+net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch
+net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch
+net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch
+net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch
+net-usb-catc-enable-basic-endpoint-checking.patch
+xen-netback-reject-zero-queue-configuration-from-gue.patch
+net-rds-rds_sendmsg-should-not-discard-payload_len.patch
+selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch
+selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch
+netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch
+net-remove-warn_on_once-when-accessing-forward-path-.patch
+netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch
+ipv6-fix-a-race-in-ip6_sock_set_v6only.patch
+bpftool-fix-truncated-netlink-dumps.patch
+ping-convert-hlist_nulls-to-plain-hlist.patch
+inet-ping-check-sock_net-in-ping_get_port-and-ping_l.patch
+ping-annotate-data-races-in-ping_lookup.patch
+selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch
+macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch
+icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch
+icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch
+icmp-prevent-possible-overflow-in-icmp_global_allow.patch
+octeontx2-af-fix-default-entries-mcam-entry-action.patch
+bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch
+apparmor-fix-null-sock-in-aa_sock_file_perm.patch
+apparmor-fix-rlimit-for-posix-cpu-timers.patch
+apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch
+asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch
+drm-i915-acpi-free-_dsm-package-when-no-connectors.patch
+s390-select-arch_want_hugetlb_page_optimize_vmemmap.patch
+s390-kconfig-sort-config-s390-select-list-again.patch
+s390-kexec-refactor-for-kernel-kconfig.kexec.patch
+s390-kexec-make-kexec_sig-available-when-config_modu.patch
+btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch
+asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch
+drm-amd-display-use-same-max-plane-scaling-limits-fo.patch
--- /dev/null
+From 83ac40857e452e5d2cedb9274b64a24790ef09d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 22:40:40 +0000
+Subject: xen-netback: reject zero-queue configuration from guest
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ]
+
+A malicious or buggy Xen guest can write "0" to the xenbus key
+"multi-queue-num-queues". The connect() function in the backend only
+validates the upper bound (requested_num_queues > xenvif_max_queues)
+but not zero, allowing requested_num_queues=0 to reach
+vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers
+WARN_ON_ONCE(!size) in __vmalloc_node_range().
+
+On systems with panic_on_warn=1, this allows a guest-to-host denial
+of service.
+
+The Xen network interface specification requires
+the queue count to be "greater than zero".
+
+Add a zero check to match the validation already present
+in xen-blkback, which has included this
+guard since its multi-queue support was added.
+
+Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/xen-netback/xenbus.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
+index 001636901ddae..a972b05da96fc 100644
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -735,10 +735,11 @@ static void connect(struct backend_info *be)
+ */
+ requested_num_queues = xenbus_read_unsigned(dev->otherend,
+ "multi-queue-num-queues", 1);
+- if (requested_num_queues > xenvif_max_queues) {
++ if (requested_num_queues > xenvif_max_queues ||
++ requested_num_queues == 0) {
+ /* buggy or malicious guest */
+ xenbus_dev_fatal(dev, -EINVAL,
+- "guest requested %u queues, exceeding the maximum of %u.",
++ "guest requested %u queues, but valid range is 1 - %u.",
+ requested_num_queues, xenvif_max_queues);
+ return;
+ }
+--
+2.51.0
+
--- /dev/null
+From 6a8ae58a1af4312d98a416626d5624a34584cab6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Dec 2025 14:55:09 +0100
+Subject: ACPI: button: Adjust event notification routines
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 93dc5db6d47aaa3b4b458ddfddfa3369c24e22f4 ]
+
+Adjust the event notification routines in the ACPI button driver to
+take a struct acpi_button pointer as an argument istead of a struct
+acpi_device one where applicable, which allows the use of
+acpi_driver_data() to be limited and will facilitate subsequent
+changes.
+
+No intentional functional impact.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://patch.msgid.link/2260995.Icojqenx9y@rafael.j.wysocki
+Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 67 +++++++++++++++++++++----------------------
+ 1 file changed, 33 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 3c6dd9b4ba0ad..09a6e4ffe9f20 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -169,6 +169,7 @@ static struct acpi_driver acpi_button_driver = {
+ };
+
+ struct acpi_button {
++ struct acpi_device *adev;
+ unsigned int type;
+ struct input_dev *input;
+ char phys[32]; /* for input device */
+@@ -202,9 +203,9 @@ static int acpi_lid_evaluate_state(struct acpi_device *device)
+ return lid_state ? 1 : 0;
+ }
+
+-static int acpi_lid_notify_state(struct acpi_device *device, int state)
++static int acpi_lid_notify_state(struct acpi_button *button, int state)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = button->adev;
+ ktime_t next_report;
+ bool do_update;
+
+@@ -287,18 +288,18 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state)
+ static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq,
+ void *offset)
+ {
+- struct acpi_device *device = seq->private;
++ struct acpi_button *button = seq->private;
+ int state;
+
+- state = acpi_lid_evaluate_state(device);
++ state = acpi_lid_evaluate_state(button->adev);
+ seq_printf(seq, "state: %s\n",
+ state < 0 ? "unsupported" : (state ? "open" : "closed"));
+ return 0;
+ }
+
+-static int acpi_button_add_fs(struct acpi_device *device)
++static int acpi_button_add_fs(struct acpi_button *button)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = button->adev;
+ struct proc_dir_entry *entry = NULL;
+ int ret = 0;
+
+@@ -333,7 +334,7 @@ static int acpi_button_add_fs(struct acpi_device *device)
+ /* create /proc/acpi/button/lid/LID/state */
+ entry = proc_create_single_data(ACPI_BUTTON_FILE_STATE, S_IRUGO,
+ acpi_device_dir(device), acpi_button_state_seq_show,
+- device);
++ button);
+ if (!entry) {
+ ret = -ENODEV;
+ goto remove_dev_dir;
+@@ -355,9 +356,9 @@ static int acpi_button_add_fs(struct acpi_device *device)
+ goto done;
+ }
+
+-static int acpi_button_remove_fs(struct acpi_device *device)
++static int acpi_button_remove_fs(struct acpi_button *button)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = button->adev;
+
+ if (button->type != ACPI_BUTTON_TYPE_LID)
+ return 0;
+@@ -385,9 +386,10 @@ int acpi_lid_open(void)
+ }
+ EXPORT_SYMBOL(acpi_lid_open);
+
+-static int acpi_lid_update_state(struct acpi_device *device,
++static int acpi_lid_update_state(struct acpi_button *button,
+ bool signal_wakeup)
+ {
++ struct acpi_device *device = button->adev;
+ int state;
+
+ state = acpi_lid_evaluate_state(device);
+@@ -397,19 +399,17 @@ static int acpi_lid_update_state(struct acpi_device *device,
+ if (state && signal_wakeup)
+ acpi_pm_wakeup_event(&device->dev);
+
+- return acpi_lid_notify_state(device, state);
++ return acpi_lid_notify_state(button, state);
+ }
+
+-static void acpi_lid_initialize_state(struct acpi_device *device)
++static void acpi_lid_initialize_state(struct acpi_button *button)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
+-
+ switch (lid_init_state) {
+ case ACPI_BUTTON_LID_INIT_OPEN:
+- (void)acpi_lid_notify_state(device, 1);
++ (void)acpi_lid_notify_state(button, 1);
+ break;
+ case ACPI_BUTTON_LID_INIT_METHOD:
+- (void)acpi_lid_update_state(device, false);
++ (void)acpi_lid_update_state(button, false);
+ break;
+ case ACPI_BUTTON_LID_INIT_IGNORE:
+ default:
+@@ -421,8 +421,8 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
+
+ static void acpi_lid_notify(acpi_handle handle, u32 event, void *data)
+ {
+- struct acpi_device *device = data;
+- struct acpi_button *button;
++ struct acpi_button *button = data;
++ struct acpi_device *device = button->adev;
+
+ if (event != ACPI_BUTTON_NOTIFY_STATUS) {
+ acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
+@@ -430,17 +430,16 @@ static void acpi_lid_notify(acpi_handle handle, u32 event, void *data)
+ return;
+ }
+
+- button = acpi_driver_data(device);
+ if (!button->lid_state_initialized)
+ return;
+
+- acpi_lid_update_state(device, true);
++ acpi_lid_update_state(button, true);
+ }
+
+ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+ {
+- struct acpi_device *device = data;
+- struct acpi_button *button;
++ struct acpi_button *button = data;
++ struct acpi_device *device = button->adev;
+ struct input_dev *input;
+ int keycode;
+
+@@ -457,7 +456,6 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+
+ acpi_pm_wakeup_event(&device->dev);
+
+- button = acpi_driver_data(device);
+ if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE)
+ return;
+
+@@ -505,7 +503,7 @@ static int acpi_button_resume(struct device *dev)
+ if (button->type == ACPI_BUTTON_TYPE_LID) {
+ button->last_state = !!acpi_lid_evaluate_state(device);
+ button->last_time = ktime_get();
+- acpi_lid_initialize_state(device);
++ acpi_lid_initialize_state(button);
+ }
+
+ if (button->type == ACPI_BUTTON_TYPE_POWER) {
+@@ -521,12 +519,12 @@ static int acpi_button_resume(struct device *dev)
+
+ static int acpi_lid_input_open(struct input_dev *input)
+ {
+- struct acpi_device *device = input_get_drvdata(input);
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_button *button = input_get_drvdata(input);
++ struct acpi_device *device = button->adev;
+
+ button->last_state = !!acpi_lid_evaluate_state(device);
+ button->last_time = ktime_get();
+- acpi_lid_initialize_state(device);
++ acpi_lid_initialize_state(button);
+
+ return 0;
+ }
+@@ -551,6 +549,7 @@ static int acpi_button_add(struct acpi_device *device)
+
+ device->driver_data = button;
+
++ button->adev = device;
+ button->input = input = input_allocate_device();
+ if (!input) {
+ error = -ENOMEM;
+@@ -587,7 +586,7 @@ static int acpi_button_add(struct acpi_device *device)
+ }
+
+ if (!error)
+- error = acpi_button_add_fs(device);
++ error = acpi_button_add_fs(button);
+
+ if (error) {
+ input_free_device(input);
+@@ -617,7 +616,7 @@ static int acpi_button_add(struct acpi_device *device)
+ break;
+ }
+
+- input_set_drvdata(input, device);
++ input_set_drvdata(input, button);
+ error = input_register_device(input);
+ if (error) {
+ input_free_device(input);
+@@ -628,17 +627,17 @@ static int acpi_button_add(struct acpi_device *device)
+ case ACPI_BUS_TYPE_POWER_BUTTON:
+ status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_button_event,
+- device);
++ button);
+ break;
+ case ACPI_BUS_TYPE_SLEEP_BUTTON:
+ status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_button_event,
+- device);
++ button);
+ break;
+ default:
+ status = acpi_install_notify_handler(device->handle,
+ ACPI_ALL_NOTIFY, handler,
+- device);
++ button);
+ break;
+ }
+ if (ACPI_FAILURE(status)) {
+@@ -661,7 +660,7 @@ static int acpi_button_add(struct acpi_device *device)
+ err_input_unregister:
+ input_unregister_device(input);
+ err_remove_fs:
+- acpi_button_remove_fs(device);
++ acpi_button_remove_fs(button);
+ err_free_button:
+ kfree(button);
+ return error;
+@@ -689,7 +688,7 @@ static void acpi_button_remove(struct acpi_device *device)
+ }
+ acpi_os_wait_events_complete();
+
+- acpi_button_remove_fs(device);
++ acpi_button_remove_fs(button);
+ input_unregister_device(button->input);
+ kfree(button);
+ }
+--
+2.51.0
+
--- /dev/null
+From 9064761fe082ebf68c6b4f05799c6c7a80afa943 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 15:13:26 +0100
+Subject: ACPI: button: Call device_init_wakeup() earlier during probe
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit e91f8c5305b92b63c8bac315f95c535d5c1e8fec ]
+
+Calling device_init_wakeup() after installing a notify handler in which
+wakeup events are signaled may cause a wakeup event to be missed if the
+device is probed right before a system suspend.
+
+To avoid this, move the device_init_wakeup() call in acpi_button_probe()
+before the notify handler installation and add a corresponding cleanup
+to the error path.
+
+Also carry out wakeup cleanup for the button in acpi_button_remove()
+because after that point the notify handler will not run for it and
+wakeup events coming from it will not be signaled.
+
+Fixes: 0d51157dfaac ("ACPI: button: Eliminate the driver notify callback")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://patch.msgid.link/12854922.O9o76ZdvQC@rafael.j.wysocki
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index b899b8745fedd..38bc64d6bdaf3 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -625,6 +625,8 @@ static int acpi_button_probe(struct platform_device *pdev)
+ goto err_remove_fs;
+ }
+
++ device_init_wakeup(&pdev->dev, true);
++
+ switch (device->device_type) {
+ case ACPI_BUS_TYPE_POWER_BUTTON:
+ status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+@@ -655,11 +657,11 @@ static int acpi_button_probe(struct platform_device *pdev)
+ lid_device = device;
+ }
+
+- device_init_wakeup(&pdev->dev, true);
+ pr_info("%s [%s]\n", name, acpi_device_bid(device));
+ return 0;
+
+ err_input_unregister:
++ device_init_wakeup(&pdev->dev, false);
+ input_unregister_device(input);
+ err_remove_fs:
+ acpi_button_remove_fs(button);
+@@ -691,6 +693,8 @@ static void acpi_button_remove(struct platform_device *pdev)
+ }
+ acpi_os_wait_events_complete();
+
++ device_init_wakeup(&pdev->dev, false);
++
+ acpi_button_remove_fs(button);
+ input_unregister_device(button->input);
+ kfree(button);
+--
+2.51.0
+
--- /dev/null
+From 6ce5fd8429d01ae657c5536d6605406e1cdc3036 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Dec 2025 14:57:57 +0100
+Subject: ACPI: button: Convert the driver to a platform one
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 52d86401963666423cb9a56d117136c846093db0 ]
+
+While binding drivers directly to struct acpi_device objects allows
+basic functionality to be provided, at least in the majority of cases,
+there are some problems with it, related to general consistency, sysfs
+layout, power management operation ordering, and code cleanliness.
+
+Overall, it is better to bind drivers to platform devices than to their
+ACPI companions, so convert the ACPI button driver to a platform one.
+
+While this is not expected to alter functionality, it changes sysfs
+layout and so it will be visible to user space.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://patch.msgid.link/2461734.NG923GbCHz@rafael.j.wysocki
+Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 61 +++++++++++++++++++++++--------------------
+ 1 file changed, 32 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 09a6e4ffe9f20..b899b8745fedd 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -19,6 +19,7 @@
+ #include <linux/slab.h>
+ #include <linux/acpi.h>
+ #include <linux/dmi.h>
++#include <linux/platform_device.h>
+ #include <acpi/button.h>
+
+ #define ACPI_BUTTON_CLASS "button"
+@@ -145,8 +146,8 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
+ {}
+ };
+
+-static int acpi_button_add(struct acpi_device *device);
+-static void acpi_button_remove(struct acpi_device *device);
++static int acpi_button_probe(struct platform_device *pdev);
++static void acpi_button_remove(struct platform_device *pdev);
+
+ #ifdef CONFIG_PM_SLEEP
+ static int acpi_button_suspend(struct device *dev);
+@@ -157,19 +158,19 @@ static int acpi_button_resume(struct device *dev);
+ #endif
+ static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
+
+-static struct acpi_driver acpi_button_driver = {
+- .name = "button",
+- .class = ACPI_BUTTON_CLASS,
+- .ids = button_device_ids,
+- .ops = {
+- .add = acpi_button_add,
+- .remove = acpi_button_remove,
++static struct platform_driver acpi_button_driver = {
++ .probe = acpi_button_probe,
++ .remove = acpi_button_remove,
++ .driver = {
++ .name = "acpi-button",
++ .acpi_match_table = button_device_ids,
++ .pm = &acpi_button_pm,
+ },
+- .drv.pm = &acpi_button_pm,
+ };
+
+ struct acpi_button {
+ struct acpi_device *adev;
++ struct platform_device *pdev;
+ unsigned int type;
+ struct input_dev *input;
+ char phys[32]; /* for input device */
+@@ -397,7 +398,7 @@ static int acpi_lid_update_state(struct acpi_button *button,
+ return state;
+
+ if (state && signal_wakeup)
+- acpi_pm_wakeup_event(&device->dev);
++ acpi_pm_wakeup_event(&button->pdev->dev);
+
+ return acpi_lid_notify_state(button, state);
+ }
+@@ -454,7 +455,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+ return;
+ }
+
+- acpi_pm_wakeup_event(&device->dev);
++ acpi_pm_wakeup_event(&button->pdev->dev);
+
+ if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE)
+ return;
+@@ -486,8 +487,7 @@ static u32 acpi_button_event(void *data)
+ #ifdef CONFIG_PM_SLEEP
+ static int acpi_button_suspend(struct device *dev)
+ {
+- struct acpi_device *device = to_acpi_device(dev);
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_button *button = dev_get_drvdata(dev);
+
+ button->suspended = true;
+ return 0;
+@@ -495,9 +495,9 @@ static int acpi_button_suspend(struct device *dev)
+
+ static int acpi_button_resume(struct device *dev)
+ {
++ struct acpi_button *button = dev_get_drvdata(dev);
++ struct acpi_device *device = ACPI_COMPANION(dev);
+ struct input_dev *input;
+- struct acpi_device *device = to_acpi_device(dev);
+- struct acpi_button *button = acpi_driver_data(device);
+
+ button->suspended = false;
+ if (button->type == ACPI_BUTTON_TYPE_LID) {
+@@ -529,8 +529,9 @@ static int acpi_lid_input_open(struct input_dev *input)
+ return 0;
+ }
+
+-static int acpi_button_add(struct acpi_device *device)
++static int acpi_button_probe(struct platform_device *pdev)
+ {
++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+ acpi_notify_handler handler;
+ struct acpi_button *button;
+ struct input_dev *input;
+@@ -547,8 +548,9 @@ static int acpi_button_add(struct acpi_device *device)
+ if (!button)
+ return -ENOMEM;
+
+- device->driver_data = button;
++ platform_set_drvdata(pdev, button);
+
++ button->pdev = pdev;
+ button->adev = device;
+ button->input = input = input_allocate_device();
+ if (!input) {
+@@ -599,7 +601,7 @@ static int acpi_button_add(struct acpi_device *device)
+ input->phys = button->phys;
+ input->id.bustype = BUS_HOST;
+ input->id.product = button->type;
+- input->dev.parent = &device->dev;
++ input->dev.parent = &pdev->dev;
+
+ switch (button->type) {
+ case ACPI_BUTTON_TYPE_POWER:
+@@ -653,7 +655,7 @@ static int acpi_button_add(struct acpi_device *device)
+ lid_device = device;
+ }
+
+- device_init_wakeup(&device->dev, true);
++ device_init_wakeup(&pdev->dev, true);
+ pr_info("%s [%s]\n", name, acpi_device_bid(device));
+ return 0;
+
+@@ -666,9 +668,10 @@ static int acpi_button_add(struct acpi_device *device)
+ return error;
+ }
+
+-static void acpi_button_remove(struct acpi_device *device)
++static void acpi_button_remove(struct platform_device *pdev)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
++ struct acpi_button *button = platform_get_drvdata(pdev);
+
+ switch (device->device_type) {
+ case ACPI_BUS_TYPE_POWER_BUTTON:
+@@ -727,7 +730,7 @@ module_param_call(lid_init_state,
+ NULL, 0644);
+ MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state");
+
+-static int acpi_button_register_driver(struct acpi_driver *driver)
++static int __init acpi_button_init(void)
+ {
+ const struct dmi_system_id *dmi_id;
+
+@@ -743,20 +746,20 @@ static int acpi_button_register_driver(struct acpi_driver *driver)
+ * Modules such as nouveau.ko and i915.ko have a link time dependency
+ * on acpi_lid_open(), and would therefore not be loadable on ACPI
+ * capable kernels booted in non-ACPI mode if the return value of
+- * acpi_bus_register_driver() is returned from here with ACPI disabled
++ * platform_driver_register() is returned from here with ACPI disabled
+ * when this driver is built as a module.
+ */
+ if (acpi_disabled)
+ return 0;
+
+- return acpi_bus_register_driver(driver);
++ return platform_driver_register(&acpi_button_driver);
+ }
+
+-static void acpi_button_unregister_driver(struct acpi_driver *driver)
++static void __exit acpi_button_exit(void)
+ {
+ if (!acpi_disabled)
+- acpi_bus_unregister_driver(driver);
++ platform_driver_unregister(&acpi_button_driver);
+ }
+
+-module_driver(acpi_button_driver, acpi_button_register_driver,
+- acpi_button_unregister_driver);
++module_init(acpi_button_init);
++module_exit(acpi_button_exit);
+--
+2.51.0
+
--- /dev/null
+From b61cd528a0a6ee4360fa1690867410116cb9f211 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 15:27:09 -0600
+Subject: ACPI: button: Install notifier for system events as well
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit a7e23ec17feecc7bac0d500cea900cace7b50129 ]
+
+On some systems when the system is put to sleep pressing the ACPI power
+button will cause the EC SCI to try to wake the system by a Notify(DEV, 0x2)
+with an intention to wake the system up from suspend.
+
+This behavior matches the ACPI specification in ACPI 6.4 section
+4.8.3.1.1.2 which describes that the AML handler would generate a Notify()
+with a code of 0x2 to indicate it was responsible for waking the system.
+
+This currently doesn't work because acpi_button_add() only configured
+`ACPI_DEVICE_NOTIFY` which means that device handler notifications
+0x80 through 0xFF are handled.
+
+To fix the wakeups on such systems, adjust the ACPI button handler to
+use `ACPI_ALL_NOTIFY` which will handle all events 0x00 through 0x7F.
+
+Reported-by: Yijun Shen <Yijun.Shen@dell.com>
+Tested-by: Richard Gong <Richard.Gong@amd.com>
+Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/04_ACPI_Hardware_Specification/ACPI_Hardware_Specification.html?highlight=0x2#control-method-power-button
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Tested-by: Yijun Shen <Yijun_Shen@Dell.com>
+Link: https://patch.msgid.link/20250303212719.4153485-1-superm1@kernel.org
+[ rjw: Removed uneeded semicolon ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 6d7c413982167..7c45b5dc2da73 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -24,6 +24,7 @@
+ #define ACPI_BUTTON_CLASS "button"
+ #define ACPI_BUTTON_FILE_STATE "state"
+ #define ACPI_BUTTON_TYPE_UNKNOWN 0x00
++#define ACPI_BUTTON_NOTIFY_WAKE 0x02
+ #define ACPI_BUTTON_NOTIFY_STATUS 0x80
+
+ #define ACPI_BUTTON_SUBCLASS_POWER "power"
+@@ -443,7 +444,12 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+ struct input_dev *input;
+ int keycode;
+
+- if (event != ACPI_BUTTON_NOTIFY_STATUS) {
++ switch (event) {
++ case ACPI_BUTTON_NOTIFY_STATUS:
++ break;
++ case ACPI_BUTTON_NOTIFY_WAKE:
++ break;
++ default:
+ acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
+ event);
+ return;
+@@ -631,7 +637,7 @@ static int acpi_button_add(struct acpi_device *device)
+ break;
+ default:
+ status = acpi_install_notify_handler(device->handle,
+- ACPI_DEVICE_NOTIFY, handler,
++ ACPI_ALL_NOTIFY, handler,
+ device);
+ break;
+ }
+--
+2.51.0
+
--- /dev/null
+From 324f3ad8127ce1ca957c4f1ad1c14d3fa2bd7860 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 09:50:22 -0500
+Subject: ACPI: button: Only send `KEY_POWER` for `ACPI_BUTTON_NOTIFY_STATUS`
+
+From: Mario Limonciello <mario.limonciello@amd.com>
+
+[ Upstream commit a8605b0ed187f53f077a769ce2b52ddb97f3eb42 ]
+
+Commit a7e23ec17feec ("ACPI: button: Install notifier for system
+events as well") modified the ACPI button behavior to send
+`ACPI_BUTTON_NOTIFY_WAKE` events.
+
+This caused a regression on Dell Optiplex 3040 sending `KEY_POWER`
+randomly at runtime.
+
+Adjust logic so that the `ACPI_BUTTON_NOTIFY_WAKE` event will never
+send `KEY_POWER`.
+
+Fixes: a7e23ec17feec ("ACPI: button: Install notifier for system events as well")
+Reported-by: Ian Laurie <nixuser@mail.com>
+Closes: https://lore.kernel.org/linux-acpi/CAJZ5v0hbA6bqxHupTh4NZR-GVSb9M5RL7JSb2yQgvYYJg+z2aQ@mail.gmail.com/T/#md8071e480212201f23e4929607386750d3b6bc13
+Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2357044
+Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+Tested-by: Ian Laurie <nixuser@mail.com>
+Link: https://patch.msgid.link/20250404145034.2608574-1-superm1@kernel.org
+[ rjw: Changelog edits ]
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 7c45b5dc2da73..3c6dd9b4ba0ad 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -458,7 +458,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+ acpi_pm_wakeup_event(&device->dev);
+
+ button = acpi_driver_data(device);
+- if (button->suspended)
++ if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE)
+ return;
+
+ input = button->input;
+--
+2.51.0
+
--- /dev/null
+From 45d8f2791ce9698768971a6a80d51186e6329729 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 21:22:54 +0000
+Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs
+
+From: Sean V Kelley <skelley@nvidia.com>
+
+[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all
+possible CPUs. In acpi_get_psd_map(), encountering an offline CPU
+returns -EFAULT, causing cppc_cpufreq initialization to fail.
+
+This breaks systems booted with "nosmt" or "nosmt=force".
+
+Fix by using for_each_online_cpu() in both functions.
+
+Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests")
+Signed-off-by: Sean V Kelley <skelley@nvidia.com>
+Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 1e8e2002f81af..c90121cae628a 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -349,7 +349,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
+ end:
+ if (cmd == CMD_WRITE) {
+ if (unlikely(ret)) {
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i);
+
+ if (!desc)
+@@ -511,7 +511,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data)
+ else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
+ cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ if (i == cpu)
+ continue;
+
+--
+2.51.0
+
--- /dev/null
+From c4d4eeba9f998d5b57f5dea554047af304d8dc0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Feb 2026 00:14:52 +0800
+Subject: ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO
+
+From: Zhai Can <bczhc0@126.com>
+
+[ Upstream commit cd7ef20ba8c6e936dba133b4136537a8ada22976 ]
+
+On the THUNDEROBOT ZERO laptop, the second NVMe slot and the discrete
+NVIDIA GPU are both controlled by power-resource PXP. Due to the SSDT table
+bug (lack of reference), PXP will be shut dow as an "unused" power resource
+during initialization, making the NVMe slot #2 + NVIDIA both inaccessible.
+
+This issue was introduced by commit a1224f34d72a ("ACPI: PM: Check
+states of power resources during initialization"). Here are test
+results on the three consecutive commits:
+
+(bad again!) a1224f34d72a ACPI: PM: Check states of power resources during initialization
+(good) bc2836859643 ACPI: PM: Do not turn off power resources in unknown state
+(bad) 519d81956ee2 Linux 5.15-rc6
+
+On commit bc2836859643 ("ACPI: PM: Do not turn off power resources in
+unknown state") this was not an issue because the power resource state
+left UNKNOWN thus being ignored.
+
+See also commit 9b04d99788cf ("ACPI: PM: Do not turn of unused power
+resources on the Toshiba Click Mini") which is another almost identical
+case to this one.
+
+Fixes: a1224f34d72a ("ACPI: PM: Check states of power resources during initialization")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221087
+Signed-off-by: Zhai Can <bczhc0@126.com>
+Link: https://patch.msgid.link/20260214161452.2849346-1-bczhc0@126.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/power.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
+index c2c70139c4f1d..ff5fcd541e50f 100644
+--- a/drivers/acpi/power.c
++++ b/drivers/acpi/power.c
+@@ -1035,6 +1035,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
+ },
+ },
++ {
++ /*
++ * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power
++ * resource 'PXP' will be shut down on initialization, making
++ * the NVMe #2 and the NVIDIA dGPU both unavailable (they're
++ * both controlled by 'PXP').
++ */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"),
++ }
++
++ },
+ {}
+ };
+
+--
+2.51.0
+
--- /dev/null
+From 1ad6696bb01b57981666096931ecdfb8a2d1080e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:11:07 +0100
+Subject: AppArmor: Allow apparmor to handle unaligned dfa tables
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Helge Deller <deller@kernel.org>
+
+[ Upstream commit 64802f731214a51dfe3c6c27636b3ddafd003eb0 ]
+
+The dfa tables can originate from kernel or userspace and 8-byte alignment
+isn't always guaranteed and as such may trigger unaligned memory accesses
+on various architectures. Resulting in the following
+
+[Â Â 73.901376] WARNING: CPU: 0 PID: 341 at security/apparmor/match.c:316 aa_dfa_unpack+0x6cc/0x720
+[Â Â 74.015867] Modules linked in: binfmt_misc evdev flash sg drm drm_panel_orientation_quirks backlight i2c_core configfs nfnetlink autofs4 ext4 crc16 mbcache jbd2 hid_generic usbhid sr_mod hid cdrom
+sd_mod ata_generic ohci_pci ehci_pci ehci_hcd ohci_hcd pata_ali libata sym53c8xx scsi_transport_spi tg3 scsi_mod usbcore libphy scsi_common mdio_bus usb_common
+[Â Â 74.428977] CPU: 0 UID: 0 PID: 341 Comm: apparmor_parser Not tainted 6.18.0-rc6+ #9 NONE
+[Â Â 74.536543] Call Trace:
+[Â Â 74.568561] [<0000000000434c24>] dump_stack+0x8/0x18
+[Â Â 74.633757] [<0000000000476438>] __warn+0xd8/0x100
+[Â Â 74.696664] [<00000000004296d4>] warn_slowpath_fmt+0x34/0x74
+[Â Â 74.771006] [<00000000008db28c>] aa_dfa_unpack+0x6cc/0x720
+[Â Â 74.843062] [<00000000008e643c>] unpack_pdb+0xbc/0x7e0
+[Â Â 74.910545] [<00000000008e7740>] unpack_profile+0xbe0/0x1300
+[Â Â 74.984888] [<00000000008e82e0>] aa_unpack+0xe0/0x6a0
+[Â Â 75.051226] [<00000000008e3ec4>] aa_replace_profiles+0x64/0x1160
+[Â Â 75.130144] [<00000000008d4d90>] policy_update+0xf0/0x280
+[Â Â 75.201057] [<00000000008d4fc8>] profile_replace+0xa8/0x100
+[Â Â 75.274258] [<0000000000766bd0>] vfs_write+0x90/0x420
+[Â Â 75.340594] [<00000000007670cc>] ksys_write+0x4c/0xe0
+[Â Â 75.406932] [<0000000000767174>] sys_write+0x14/0x40
+[Â Â 75.472126] [<0000000000406174>] linux_sparc_syscall+0x34/0x44
+[Â Â 75.548802] ---[ end trace 0000000000000000 ]---
+[Â Â 75.609503] dfa blob stream 0xfff0000008926b96 not aligned.
+[Â Â 75.682695] Kernel unaligned access at TPC[8db2a8] aa_dfa_unpack+0x6e8/0x720
+
+Work around it by using the get_unaligned_xx() helpers.
+
+Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack")
+Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+Closes: https://github.com/sparclinux/issues/issues/30
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/match.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/security/apparmor/match.c b/security/apparmor/match.c
+index 12e036f8ce0f7..4f998715d2942 100644
+--- a/security/apparmor/match.c
++++ b/security/apparmor/match.c
+@@ -15,6 +15,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/err.h>
+ #include <linux/kref.h>
++#include <linux/unaligned.h>
+
+ #include "include/lib.h"
+ #include "include/match.h"
+@@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
+ /* loaded td_id's start at 1, subtract 1 now to avoid doing
+ * it every time we use td_id as an index
+ */
+- th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
++ th.td_id = get_unaligned_be16(blob) - 1;
+ if (th.td_id > YYTD_ID_MAX)
+ goto out;
+- th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
+- th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
++ th.td_flags = get_unaligned_be16(blob + 2);
++ th.td_lolen = get_unaligned_be32(blob + 8);
+ blob += sizeof(struct table_header);
+
+ if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
+@@ -277,14 +278,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
+ if (size < sizeof(struct table_set_header))
+ goto fail;
+
+- if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
++ if (get_unaligned_be32(data) != YYTH_MAGIC)
+ goto fail;
+
+- hsize = ntohl(*(__be32 *) (data + 4));
++ hsize = get_unaligned_be32(data + 4);
+ if (size < hsize)
+ goto fail;
+
+- dfa->flags = ntohs(*(__be16 *) (data + 12));
++ dfa->flags = get_unaligned_be16(data + 12);
+ if (dfa->flags & ~(YYTH_FLAGS))
+ goto fail;
+
+@@ -293,7 +294,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
+ * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
+ * if (hsize < 16 + 4)
+ * goto fail;
+- * dfa->max_oob = ntol(*(__be32 *) (data + 16));
++ * dfa->max_oob = get_unaligned_be32(data + 16);
+ * if (dfa->max <= MAX_OOB_SUPPORTED) {
+ * pr_err("AppArmor DFA OOB greater than supported\n");
+ * goto fail;
+--
+2.51.0
+
--- /dev/null
+From 8af6641c353af911365e75fa533361253e27e0d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jan 2026 19:03:07 -0500
+Subject: apparmor: avoid per-cpu hold underflow in aa_get_buffer
+
+From: Zhengmian Hu <huzhengmian@gmail.com>
+
+[ Upstream commit 640cf2f09575c9dc344b3f7be2498d31e3923ead ]
+
+When aa_get_buffer() pulls from the per-cpu list it unconditionally
+decrements cache->hold. If hold reaches 0 while count is still non-zero,
+the unsigned decrement wraps to UINT_MAX. This keeps hold non-zero for a
+very long time, so aa_put_buffer() never returns buffers to the global
+list, which can starve other CPUs and force repeated kmalloc(aa_g_path_max)
+allocations.
+
+Guard the decrement so hold never underflows.
+Fixes: ea9bae12d028 ("apparmor: cache buffers on percpu list if there is lock contention")
+
+Signed-off-by: Zhengmian Hu <huzhengmian@gmail.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index 9a78fd36542d6..8855fb4b88342 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -1863,7 +1863,8 @@ char *aa_get_buffer(bool in_atomic)
+ if (!list_empty(&cache->head)) {
+ aa_buf = list_first_entry(&cache->head, union aa_buffer, list);
+ list_del(&aa_buf->list);
+- cache->hold--;
++ if (cache->hold)
++ cache->hold--;
+ cache->count--;
+ put_cpu_ptr(&aa_local_buffers);
+ return &aa_buf->buffer[0];
+--
+2.51.0
+
--- /dev/null
+From d4a5477a36615b09a6447cee7a0fa3ac48664712 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 04:12:02 -0800
+Subject: apparmor: fix aa_label to return state from compount and component
+ match
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 9058798652c8bc0584ed1fb0766a1015046c06e8 ]
+
+aa-label_match is not correctly returning the state in all cases.
+The only reason this didn't cause a error is that all callers currently
+ignore the return value.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202602020631.wXgZosyU-lkp@intel.com/
+Fixes: a4c9efa4dbad6 ("apparmor: make label_match return a consistent value")
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 0a96ac6137b02..af25ca6b6b83f 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1346,7 +1346,7 @@ static int label_compound_match(struct aa_profile *profile,
+ * @request: permissions to request
+ * @perms: an initialized perms struct to add accumulation to
+ *
+- * Returns: 0 on success else ERROR
++ * Returns: the state the match finished in, may be the none matching state
+ *
+ * For the label A//&B//&C this does the perm match for each of A and B and C
+ * @perms should be preinitialized with allperms OR a previous permission
+@@ -1374,7 +1374,7 @@ static int label_components_match(struct aa_profile *profile,
+ }
+
+ /* no subcomponents visible - no change in perms */
+- return 0;
++ return state;
+
+ next:
+ tmp = *aa_lookup_perms(rules->policy, state);
+@@ -1390,13 +1390,13 @@ static int label_components_match(struct aa_profile *profile,
+ }
+
+ if ((perms->allow & request) != request)
+- return -EACCES;
++ return DFA_NOMATCH;
+
+- return 0;
++ return state;
+
+ fail:
+ *perms = nullperms;
+- return -EACCES;
++ return DFA_NOMATCH;
+ }
+
+ /**
+@@ -1418,7 +1418,7 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns,
+ request, perms);
+ if ((perms->allow & request) == request)
+- return 0;
++ return tmp;
+
+ /* failed compound_match try component matches */
+ *perms = allperms;
+--
+2.51.0
+
--- /dev/null
+From f1c00bca5c7ce315cddeb83035d0c6094a94e9c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 15:58:45 -0300
+Subject: apparmor: fix invalid deref of rawdata when export_binary is unset
+
+From: Georgia Garcia <georgia.garcia@canonical.com>
+
+[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ]
+
+If the export_binary parameter is disabled on runtime, profiles that
+were loaded before that will still have their rawdata stored in
+apparmorfs, with a symbolic link to the rawdata on the policy
+directory. When one of those profiles are replaced, the rawdata is set
+to NULL, but when trying to resolve the symbolic links to rawdata for
+that profile, it will try to dereference profile->rawdata->name when
+profile->rawdata is now NULL causing an oops. Fix it by checking if
+rawdata is set.
+
+[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088
+[ 168.657420] #PF: supervisor read access in kernel mode
+[ 168.660619] #PF: error_code(0x0000) - not-present page
+[ 168.663613] PGD 0 P4D 0
+[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI
+[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary)
+[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330
+[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8
+[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282
+[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158
+[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80
+[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000
+[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80
+[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0
+[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000
+[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0
+[ 168.701696] Call Trace:
+[ 168.702325] <TASK>
+[ 168.702995] rawdata_get_link_data+0x1c/0x30
+[ 168.704145] vfs_readlink+0xd4/0x160
+[ 168.705152] do_readlinkat+0x114/0x180
+[ 168.706214] __x64_sys_readlink+0x1e/0x30
+[ 168.708653] x64_sys_call+0x1d77/0x26b0
+[ 168.709525] do_syscall_64+0x81/0x500
+[ 168.710348] ? do_statx+0x72/0xb0
+[ 168.711109] ? putname+0x3e/0x80
+[ 168.711845] ? __x64_sys_statx+0xb7/0x100
+[ 168.712711] ? x64_sys_call+0x10fc/0x26b0
+[ 168.713577] ? do_syscall_64+0xbf/0x500
+[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0
+[ 168.715404] ? irqentry_exit+0xb2/0x740
+[ 168.716359] ? exc_page_fault+0x90/0x1b0
+[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement")
+Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/apparmorfs.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index 01b923d97a446..584b40718ecb7 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -1631,6 +1631,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry,
+
+ label = aa_get_label_rcu(&proxy->label);
+ profile = labels_profile(label);
++
++ /* rawdata can be null when aa_g_export_binary is unset during
++ * runtime and a profile is replaced
++ */
++ if (!profile->rawdata) {
++ aa_put_label(label);
++ return ERR_PTR(-ENOENT);
++ }
++
+ depth = profile_depth(profile);
+ target = gen_symlink_name(depth, profile->rawdata->name, name);
+ aa_put_label(label);
+--
+2.51.0
+
--- /dev/null
+From f97f5c9199c499837d690575a1296941add2dab4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 15:07:42 -0800
+Subject: apparmor: fix NULL sock in aa_sock_file_perm
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ]
+
+Deal with the potential that sock and sock-sk can be NULL during
+socket setup or teardown. This could lead to an oops. The fix for NULL
+pointer dereference in __unix_needs_revalidation shows this is at
+least possible for af_unix sockets. While the fix for af_unix sockets
+applies for newer mediation this is still the fall back path for older
+af_unix mediation and other sockets, so ensure it is covered.
+
+Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/net.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index 77413a5191179..f6f749191f601 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -190,8 +190,10 @@ int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label,
+ const char *op, u32 request, struct socket *sock)
+ {
+ AA_BUG(!label);
+- AA_BUG(!sock);
+- AA_BUG(!sock->sk);
++
++ /* sock && sock->sk can be NULL for sockets being set up or torn down */
++ if (!sock || !sock->sk)
++ return 0;
+
+ return aa_label_sk_perm(subj_cred, label, op, request, sock->sk);
+ }
+--
+2.51.0
+
--- /dev/null
+From cf304558a56dddabe48b36896dd620090269291d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 21:15:04 +0100
+Subject: apparmor: Fix & Optimize table creation from possibly unaligned
+ memory
+
+From: Helge Deller <deller@kernel.org>
+
+[ Upstream commit 6fc367bfd4c8886e6b1742aabbd1c0bdc310db3a ]
+
+Source blob may come from userspace and might be unaligned.
+Try to optize the copying process by avoiding unaligned memory accesses.
+
+- Added Fixes tag
+- Added "Fix &" to description as this doesn't just optimize but fixes
+ a potential unaligned memory access
+Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack")
+Signed-off-by: Helge Deller <deller@gmx.de>
+[jj: remove duplicate word "convert" in comment trigger checkpatch warning]
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/include/match.h | 12 +++++++-----
+ security/apparmor/match.c | 7 +++----
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
+index ae31a8a631fc6..dfc93631b43d8 100644
+--- a/security/apparmor/include/match.h
++++ b/security/apparmor/include/match.h
+@@ -102,16 +102,18 @@ struct aa_dfa {
+ struct table_header *tables[YYTD_ID_TSIZE];
+ };
+
+-#define byte_to_byte(X) (X)
+-
+ #define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX) \
+ do { \
+ typeof(LEN) __i; \
+ TTYPE *__t = (TTYPE *) TABLE; \
+ BTYPE *__b = (BTYPE *) BLOB; \
+- for (__i = 0; __i < LEN; __i++) { \
+- __t[__i] = NTOHX(__b[__i]); \
+- } \
++ BUILD_BUG_ON(sizeof(TTYPE) != sizeof(BTYPE)); \
++ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) \
++ memcpy(__t, __b, (LEN) * sizeof(BTYPE)); \
++ else /* copy & convert from big-endian */ \
++ for (__i = 0; __i < LEN; __i++) { \
++ __t[__i] = NTOHX(&__b[__i]); \
++ } \
+ } while (0)
+
+ static inline size_t table_size(size_t len, size_t el_size)
+diff --git a/security/apparmor/match.c b/security/apparmor/match.c
+index 4f998715d2942..fae26953619a7 100644
+--- a/security/apparmor/match.c
++++ b/security/apparmor/match.c
+@@ -67,14 +67,13 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
+ table->td_flags = th.td_flags;
+ table->td_lolen = th.td_lolen;
+ if (th.td_flags == YYTD_DATA8)
+- UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+- u8, u8, byte_to_byte);
++ memcpy(table->td_data, blob, th.td_lolen);
+ else if (th.td_flags == YYTD_DATA16)
+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+- u16, __be16, be16_to_cpu);
++ u16, __be16, get_unaligned_be16);
+ else if (th.td_flags == YYTD_DATA32)
+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+- u32, __be32, be32_to_cpu);
++ u32, __be32, get_unaligned_be32);
+ else
+ goto fail;
+ /* if table was vmalloced make sure the page tables are synced
+--
+2.51.0
+
--- /dev/null
+From 06992da97d4d87377d0d029eb98c0054f2660090 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:16:54 -0800
+Subject: apparmor: fix rlimit for posix cpu timers
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ]
+
+Posix cpu timers requires an additional step beyond setting the rlimit.
+Refactor the code so its clear when what code is setting the
+limit and conditionally update the posix cpu timers when appropriate.
+
+Fixes: baa73d9e478ff ("posix-timers: Make them configurable")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/resource.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index dcc94c3153d51..a7eee815f1215 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -201,6 +201,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
+ rules->rlimits.limits[j].rlim_max);
+ /* soft limit should not exceed hard limit */
+ rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
++ if (j == RLIMIT_CPU &&
++ rlim->rlim_cur != RLIM_INFINITY &&
++ IS_ENABLED(CONFIG_POSIX_TIMERS))
++ (void) update_rlimit_cpu(current->group_leader,
++ rlim->rlim_cur);
+ }
+ }
+ }
+--
+2.51.0
+
--- /dev/null
+From 388117496f08de95aaf378729a1aa613da47ab55 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Nov 2025 23:59:38 -0800
+Subject: apparmor: make label_match return a consistent value
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit a4c9efa4dbad6dacad6e8b274e30e814c8353097 ]
+
+compound match is inconsistent in returning a state or an integer error
+this is problemati if the error is ever used as a state in the state
+machine
+
+Fixes: f1bd904175e81 ("apparmor: add the base fns() for domain labels")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 81548248440aa..0a96ac6137b02 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1290,7 +1290,7 @@ static inline aa_state_t match_component(struct aa_profile *profile,
+ * @request: permissions to request
+ * @perms: perms struct to set
+ *
+- * Returns: 0 on success else ERROR
++ * Returns: state match stopped at or DFA_NOMATCH if aborted early
+ *
+ * For the label A//&B//&C this does the perm match for A//&B//&C
+ * @perms should be preinitialized with allperms OR a previous permission
+@@ -1317,7 +1317,7 @@ static int label_compound_match(struct aa_profile *profile,
+
+ /* no component visible */
+ *perms = allperms;
+- return 0;
++ return state;
+
+ next:
+ label_for_each_cont(i, label, tp) {
+@@ -1329,14 +1329,11 @@ static int label_compound_match(struct aa_profile *profile,
+ goto fail;
+ }
+ *perms = *aa_lookup_perms(rules->policy, state);
+- if ((perms->allow & request) != request)
+- return -EACCES;
+-
+- return 0;
++ return state;
+
+ fail:
+ *perms = nullperms;
+- return state;
++ return DFA_NOMATCH;
+ }
+
+ /**
+@@ -1418,11 +1415,12 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+ struct aa_label *label, aa_state_t state, bool subns,
+ u32 request, struct aa_perms *perms)
+ {
+- int error = label_compound_match(profile, rules, label, state, subns,
+- request, perms);
+- if (!error)
+- return error;
++ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns,
++ request, perms);
++ if ((perms->allow & request) == request)
++ return 0;
+
++ /* failed compound_match try component matches */
+ *perms = allperms;
+ return label_components_match(profile, rules, label, state, subns,
+ request, perms);
+--
+2.51.0
+
--- /dev/null
+From d4fb16102ea0b421cc5322d7236e501a91c27193 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Nov 2025 00:14:36 -0800
+Subject: apparmor: remove apply_modes_to_perms from label_match
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit b2e27be2948f2f8c38421cd554b5fc9383215648 ]
+
+The modes shouldn't be applied at the point of label match, it just
+results in them being applied multiple times. Instead they should be
+applied after which is already being done by all callers so it can
+just be dropped from label_match.
+
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index c71e4615dd460..81548248440aa 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1329,7 +1329,6 @@ static int label_compound_match(struct aa_profile *profile,
+ goto fail;
+ }
+ *perms = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, perms);
+ if ((perms->allow & request) != request)
+ return -EACCES;
+
+@@ -1382,7 +1381,6 @@ static int label_components_match(struct aa_profile *profile,
+
+ next:
+ tmp = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ label_for_each_cont(i, label, tp) {
+ if (!aa_ns_visible(profile->ns, tp->ns, subns))
+@@ -1391,7 +1389,6 @@ static int label_components_match(struct aa_profile *profile,
+ if (!state)
+ goto fail;
+ tmp = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 4c06525f7bc29d5235ecaeee48a82fe565d4165c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jan 2026 09:35:57 -0800
+Subject: apparmor: return -ENOMEM in unpack_perms_table upon alloc failure
+
+From: Ryan Lee <ryan.lee@canonical.com>
+
+[ Upstream commit 74b7105e53e80a4072bd3e1a50be7aa15e3f0a01 ]
+
+In policy_unpack.c:unpack_perms_table, the perms struct is allocated via
+kcalloc, with the position being reset if the allocation fails. However,
+the error path results in -EPROTO being retured instead of -ENOMEM. Fix
+this to return the correct error code.
+
+Reported-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
+Fixes: fd1b2b95a2117 ("apparmor: add the ability for policy to specify a permission table")
+Reviewed-by: Tyler Hicks <code@tyhicks.com>
+Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy_unpack.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index 3483c595f999f..8f7d6ff5aef60 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -683,8 +683,10 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms)
+ if (!aa_unpack_array(e, NULL, &size))
+ goto fail_reset;
+ *perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL);
+- if (!*perms)
+- goto fail_reset;
++ if (!*perms) {
++ e->pos = pos;
++ return -ENOMEM;
++ }
+ for (i = 0; i < size; i++) {
+ if (!unpack_perm(e, version, &(*perms)[i]))
+ goto fail;
+--
+2.51.0
+
--- /dev/null
+From ce2f1844d8b9b2b3c14b218eeaf34f53a4539651 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 11:27:32 +0100
+Subject: ASoC: codecs: aw88261: Fix erroneous bitmask logic in Awinic init
+
+From: Alexandre Ferrieux <alexandre.ferrieux@orange.com>
+
+[ Upstream commit b82fa9b0c26eeb2fde6017f7de2c3c544484efef ]
+
+The aw88261_dev_reg_update() function sets the Awinic registers in a
+rather nonuniform way:
+ - most registers get directly overwritten from the firmware blob
+ - but a handful of them need more delicate logic to preserve
+ some bits from their current value, according to a register-
+ specific mask
+For the latter, the logic is basically
+ NEW = (OLD & MASK) | (VAL & ~MASK)
+However, the ~MASK value is hand-computed, and in the specific case
+of the SYSCTRL register, in a buggy way.
+This patch restores the proper ~MASK value.
+
+Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver")
+Signed-off-by: Alexandre Ferrieux <alexandre.ferrieux@orange.com>
+Link: https://patch.msgid.link/20260211-aw88261-fwname-v1-1-e24e833a019d@fairphone.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/aw88261.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c
+index fb99871578c5a..38f362b022aa3 100644
+--- a/sound/soc/codecs/aw88261.c
++++ b/sound/soc/codecs/aw88261.c
+@@ -423,9 +423,10 @@ static int aw88261_dev_reg_update(struct aw88261 *aw88261,
+ if (ret)
+ break;
+
++ /* keep all three bits from current hw status */
+ read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) |
+ (~AW88261_HMUTE_MASK);
+- reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK);
++ reg_val &= (AW88261_AMPPD_MASK & AW88261_PWDN_MASK & AW88261_HMUTE_MASK);
+ reg_val |= read_val;
+
+ /* enable uls hmute */
+--
+2.51.0
+
--- /dev/null
+From 2b32ec98a143638cc25e791229ccc37468f5c610 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 18:57:14 +0000
+Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ]
+
+This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()").
+
+The original patch attempted to acquire the card->controls_rwsem lock in
+fsl_xcvr_mode_put(). However, this function is called from the upper ALSA
+core function snd_ctl_elem_write(), which already holds the write lock on
+controls_rwsem for the whole put operation. So there is no need to simply
+hold the lock for fsl_xcvr_activate_ctl() again.
+
+Acquiring the read lock while holding the write lock in the same thread
+results in a deadlock and a hung task, as reported by Alexander Stein.
+
+Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()")
+Reported-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_xcvr.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
+index d6f00920391d1..656a4d619cdf1 100644
+--- a/sound/soc/fsl/fsl_xcvr.c
++++ b/sound/soc/fsl/fsl_xcvr.c
+@@ -216,13 +216,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,
+
+ xcvr->mode = snd_soc_enum_item_to_val(e, item[0]);
+
+- down_read(&card->snd_card->controls_rwsem);
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_ARC));
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_EARC));
+- up_read(&card->snd_card->controls_rwsem);
+-
+ /* Allow playback for SPDIF only */
+ rtd = snd_soc_get_pcm_runtime(card, card->dai_link);
+ rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
+--
+2.51.0
+
--- /dev/null
+From 5916a67367aae1d6ed0017eef97305193ae5a20b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 15:18:34 -0500
+Subject: ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk
+
+From: Detlev Casanova <detlev.casanova@collabora.com>
+
+[ Upstream commit 0783052534f547f8f201dd4554b1df9f1f8615b5 ]
+
+Drivers will not always call set_sysclk() for all clocks, especially when
+default mclk-fs can be used.
+When that is the case, use the clock rate set in the params multiplied by the
+default mclk-fs.
+
+Fixes: 5323186e2e8d ("ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback")
+Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
+Reported-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Link: https://patch.msgid.link/20260218201834.924358-1-detlev.casanova@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/rockchip/rockchip_i2s_tdm.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
+index 7feefeb6b876d..46c338ddefe9f 100644
+--- a/sound/soc/rockchip/rockchip_i2s_tdm.c
++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
+@@ -22,6 +22,7 @@
+
+ #define DRV_NAME "rockchip-i2s-tdm"
+
++#define DEFAULT_MCLK_FS 256
+ #define CH_GRP_MAX 4 /* The max channel 8 / 2 */
+ #define MULTIPLEX_CH_MAX 10
+
+@@ -693,6 +694,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
+ mclk_rate = i2s_tdm->mclk_rx_freq;
+ }
+
++ /*
++ * When the dai/component driver doesn't need to set mclk-fs for a specific
++ * clock, it can skip the call to set_sysclk() for that clock.
++ * In that case, simply use the clock rate from the params and multiply it by
++ * the default mclk-fs value.
++ */
++ if (!mclk_rate)
++ mclk_rate = DEFAULT_MCLK_FS * params_rate(params);
++
+ err = clk_set_rate(mclk, mclk_rate);
+ if (err)
+ return err;
+--
+2.51.0
+
--- /dev/null
+From bdb60d3dcbdeb46eb6fe2416fe12b02ccd86aa95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 06:09:19 +0000
+Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ]
+
+The ALB RX path may access rx_hashtbl concurrently with bond
+teardown. During rapid bond up/down cycles, rlb_deinitialize()
+frees rx_hashtbl while RX handlers are still running, leading
+to a null pointer dereference detected by KASAN.
+
+However, the root cause is that rlb_arp_recv() can still be accessed
+after setting recv_probe to NULL, which is actually a use-after-free
+(UAF) issue. That is the reason for using the referenced commit in the
+Fixes tag.
+
+[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI
+[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef]
+[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary)
+[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022
+[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding]
+[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6
+ 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00
+[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206
+[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e
+[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8
+[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8
+[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119
+[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810
+[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000
+[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0
+[ 214.310347] Call Trace:
+[ 214.313070] <IRQ>
+[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding]
+[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding]
+[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding]
+[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710
+[ 214.339199] ? __pfx_arp_process+0x10/0x10
+[ 214.343775] ? sched_balance_find_src_group+0x98/0x630
+[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10
+[ 214.356513] ? arp_rcv+0x307/0x690
+[ 214.360311] ? __pfx_arp_rcv+0x10/0x10
+[ 214.364499] ? __lock_acquire+0x58c/0xbd0
+[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0
+[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10
+[ 214.380743] ? lock_acquire+0x10b/0x140
+[ 214.385026] process_backlog+0x3f1/0x13a0
+[ 214.389502] ? process_backlog+0x3aa/0x13a0
+[ 214.394174] __napi_poll.constprop.0+0x9f/0x370
+[ 214.399233] net_rx_action+0x8c1/0xe60
+[ 214.403423] ? __pfx_net_rx_action+0x10/0x10
+[ 214.408193] ? lock_acquire.part.0+0xbd/0x260
+[ 214.413058] ? sched_clock_cpu+0x6c/0x540
+[ 214.417540] ? mark_held_locks+0x40/0x70
+[ 214.421920] handle_softirqs+0x1fd/0x860
+[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10
+[ 214.431264] ? __neigh_event_send+0x2d6/0xf50
+[ 214.436131] do_softirq+0xb1/0xf0
+[ 214.439830] </IRQ>
+
+The issue is reproducible by repeatedly running
+ip link set bond0 up/down while receiving ARP messages, where
+rlb_arp_recv() can race with rlb_deinitialize() and dereference
+a freed rx_hashtbl entry.
+
+Fix this by setting recv_probe to NULL and then calling
+synchronize_net() to wait for any concurrent RX processing to finish.
+This ensures that no RX handler can access rx_hashtbl after it is freed
+in bond_alb_deinitialize().
+
+Reported-by: Liang Li <liali@redhat.com>
+Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 95456a753b184..dd1f8cad953bf 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4478,9 +4478,13 @@ static int bond_close(struct net_device *bond_dev)
+
+ bond_work_cancel_all(bond);
+ bond->send_peer_notif = 0;
++ WRITE_ONCE(bond->recv_probe, NULL);
++
++ /* Wait for any in-flight RX handlers */
++ synchronize_net();
++
+ if (bond_is_lb(bond))
+ bond_alb_deinitialize(bond);
+- bond->recv_probe = NULL;
+
+ if (bond_uses_primary(bond)) {
+ rcu_read_lock();
+--
+2.51.0
+
--- /dev/null
+From 0145936c3c55486f616ee57e3fe3dc837efc5328 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 11:41:50 -0800
+Subject: bpftool: Fix truncated netlink dumps
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ]
+
+Netlink requires that the recv buffer used during dumps is at least
+min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will
+get truncated. Make sure bpftool follows this requirement, avoid
+missing information on systems with large pages.
+
+Acked-by: Quentin Monnet <qmo@kernel.org>
+Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/net.c | 5 ++++-
+ tools/lib/bpf/netlink.c | 4 +++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c
+index 39f208928cdb5..587403a19af3a 100644
+--- a/tools/bpf/bpftool/net.c
++++ b/tools/bpf/bpftool/net.c
+@@ -156,7 +156,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ bool multipart = true;
+ struct nlmsgerr *err;
+ struct nlmsghdr *nh;
+- char buf[4096];
++ char buf[8192];
+ int len, ret;
+
+ while (multipart) {
+@@ -201,6 +201,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ return ret;
+ }
+ }
++
++ if (len)
++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len);
+ }
+ ret = 0;
+ done:
+diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
+index 68a2def171751..6f16c4f7b3a43 100644
+--- a/tools/lib/bpf/netlink.c
++++ b/tools/lib/bpf/netlink.c
+@@ -143,7 +143,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ struct nlmsghdr *nh;
+ int len, ret;
+
+- ret = alloc_iov(&iov, 4096);
++ ret = alloc_iov(&iov, 8192);
+ if (ret)
+ goto done;
+
+@@ -212,6 +212,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ }
+ }
+ }
++ if (len)
++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len);
+ }
+ ret = 0;
+ done:
+--
+2.51.0
+
--- /dev/null
+From 0e382b30df484f243a10c067f31de9a966ab1be3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 17:15:53 +0000
+Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not
+ found
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ]
+
+If btrfs_search_slot_for_read() returns 1, it means we did not find any
+key greater than or equals to the key we asked for, meaning we have
+reached the end of the tree and therefore the path is not valid. If
+this happens we need to break out of the loop and stop, instead of
+continuing and accessing an invalid path.
+
+Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/qgroup.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index 4df0ba100f9de..71ccba22752cb 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1199,11 +1199,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info,
+ }
+ if (ret > 0) {
+ /*
+- * Shouldn't happen, but in case it does we
+- * don't need to do the btrfs_next_item, just
+- * continue.
++ * Shouldn't happen because the key should still
++ * be there (return 0), but in case it does it
++ * means we have reached the end of the tree -
++ * there are no more leaves with items that have
++ * a key greater than or equals to @found_key,
++ * so just stop the search loop.
+ */
+- continue;
++ break;
+ }
+ }
+ ret = btrfs_next_item(tree_root, path);
+--
+2.51.0
+
--- /dev/null
+From 15f17282fde4fa6c4f8036b7cf54ff4fa482ce65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 18:03:35 +0000
+Subject: btrfs: use the correct type to initialize block reserve for delayed
+ refs
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 2155d0c0a761a56ce7ede83a26eb23ea0f935260 ]
+
+When initializing the delayed refs block reserve for a transaction handle
+we are passing a type of BTRFS_BLOCK_RSV_DELOPS, which is meant for
+delayed items and not for delayed refs. The correct type for delayed refs
+is BTRFS_BLOCK_RSV_DELREFS.
+
+On release of any excess space reserved in a local delayed refs reserve,
+we also should transfer that excess space to the global block reserve
+(it it's full, we return to the space info for general availability).
+
+By initializing a transaction's local delayed refs block reserve with a
+type of BTRFS_BLOCK_RSV_DELOPS, we were also causing any excess space
+released from the delayed block reserve (fs_info->delayed_block_rsv, used
+for delayed inodes and items) to be transferred to the global block
+reserve instead of the global delayed refs block reserve. This was an
+unintentional change in commit 28270e25c69a ("btrfs: always reserve space
+for delayed refs when starting transaction"), but it's not particularly
+serious as things tend to cancel out each other most of the time and it's
+relatively rare to be anywhere near exhaustion of the global reserve.
+
+Fix this by initializing a transaction's local delayed refs reserve with
+a type of BTRFS_BLOCK_RSV_DELREFS and making btrfs_block_rsv_release()
+attempt to transfer unused space from such a reserve into the global block
+reserve, just as we did before that commit for when the block reserve is
+a delayed refs rsv.
+
+Reported-by: Alex Lyakas <alex.lyakas@zadara.com>
+Link: https://lore.kernel.org/linux-btrfs/CAOcd+r0FHG5LWzTSu=LknwSoqxfw+C00gFAW7fuX71+Z5AfEew@mail.gmail.com/
+Fixes: 28270e25c69a ("btrfs: always reserve space for delayed refs when starting transaction")
+Reviewed-by: Alex Lyakas <alex.lyakas@zadara.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-rsv.c | 7 ++++---
+ fs/btrfs/transaction.c | 2 +-
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c
+index a07b9594dc706..a578bd3b32bb0 100644
+--- a/fs/btrfs/block-rsv.c
++++ b/fs/btrfs/block-rsv.c
+@@ -280,10 +280,11 @@ u64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
+ struct btrfs_block_rsv *target = NULL;
+
+ /*
+- * If we are a delayed block reserve then push to the global rsv,
+- * otherwise dump into the global delayed reserve if it is not full.
++ * If we are a delayed refs block reserve then push to the global
++ * reserve, otherwise dump into the global delayed refs reserve if it is
++ * not full.
+ */
+- if (block_rsv->type == BTRFS_BLOCK_RSV_DELOPS)
++ if (block_rsv->type == BTRFS_BLOCK_RSV_DELREFS)
+ target = global_rsv;
+ else if (block_rsv != global_rsv && !btrfs_block_rsv_full(delayed_rsv))
+ target = delayed_rsv;
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index b7679f3399407..0ee6b40af65ee 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -726,7 +726,7 @@ start_transaction(struct btrfs_root *root, unsigned int num_items,
+
+ h->type = type;
+ INIT_LIST_HEAD(&h->new_bgs);
+- btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELOPS);
++ btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELREFS);
+
+ smp_mb();
+ if (cur_trans->state >= TRANS_STATE_COMMIT_START &&
+--
+2.51.0
+
--- /dev/null
+From 2cf5eb593262ad4f6dcd28d6bc15d540225e9124 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 00:20:02 +0530
+Subject: cpuidle: Skip governor when only one idle state is available
+
+From: Aboorva Devarajan <aboorvad@linux.ibm.com>
+
+[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ]
+
+On certain platforms (PowerNV systems without a power-mgt DT node),
+cpuidle may register only a single idle state. In cases where that
+single state is a polling state (state 0), the ladder governor may
+incorrectly treat state 1 as the first usable state and pass an
+out-of-bounds index. This can lead to a NULL enter callback being
+invoked, ultimately resulting in a system crash.
+
+[ 13.342636] cpuidle-powernv : Only Snooze is available
+[ 13.351854] Faulting instruction address: 0x00000000
+[ 13.376489] NIP [0000000000000000] 0x0
+[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668
+
+Fix this by adding a bail-out in cpuidle_select() that returns state 0
+directly when state_count <= 1, bypassing the governor and keeping the
+tick running.
+
+Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol")
+Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
+Reviewed-by: Christian Loehle <christian.loehle@arm.com>
+Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/cpuidle.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
+index 0e1bbc966135d..2cb11e5a11251 100644
+--- a/drivers/cpuidle/cpuidle.c
++++ b/drivers/cpuidle/cpuidle.c
+@@ -353,6 +353,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
+ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+ bool *stop_tick)
+ {
++ /*
++ * If there is only a single idle state (or none), there is nothing
++ * meaningful for the governor to choose. Skip the governor and
++ * always use state 0 with the tick running.
++ */
++ if (drv->state_count <= 1) {
++ *stop_tick = false;
++ return 0;
++ }
++
+ return cpuidle_curr_governor->select(drv, dev, stop_tick);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 124b4b435e70d432febfc7e493aa29459889c1d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 20:49:23 +0530
+Subject: drm/amd/display: Fix out-of-bounds stream encoder index v3
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit abde491143e4e12eecc41337910aace4e8d59603 ]
+
+eng_id can be negative and that stream_enc_regs[]
+can be indexed out of bounds.
+
+eng_id is used directly as an index into stream_enc_regs[], which has
+only 5 entries. When eng_id is 5 (ENGINE_ID_DIGF) or negative, this can
+access memory past the end of the array.
+
+Add a bounds check using ARRAY_SIZE() before using eng_id as an index.
+The unsigned cast also rejects negative values.
+
+This avoids out-of-bounds access.
+
+Fixes the below smatch error:
+dcn*_resource.c: stream_encoder_create() may index
+stream_enc_regs[eng_id] out of bounds (size 5).
+
+drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn351/dcn351_resource.c
+ 1246 static struct stream_encoder *dcn35_stream_encoder_create(
+ 1247 enum engine_id eng_id,
+ 1248 struct dc_context *ctx)
+ 1249 {
+
+ ...
+
+ 1255
+ 1256 /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+ 1257 if (eng_id <= ENGINE_ID_DIGF) {
+
+ENGINE_ID_DIGF is 5. should <= be <?
+
+Unrelated but, ugh, why is Smatch saying that "eng_id" can be negative?
+end_id is type signed long, but there are checks in the caller which prevent it from being negative.
+
+ 1258 vpg_inst = eng_id;
+ 1259 afmt_inst = eng_id;
+ 1260 } else
+ 1261 return NULL;
+ 1262
+
+ ...
+
+ 1281
+ 1282 dcn35_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
+ 1283 eng_id, vpg, afmt,
+--> 1284 &stream_enc_regs[eng_id],
+ ^^^^^^^^^^^^^^^^^^^^^^^ This stream_enc_regs[] array has 5 elements so we are one element beyond the end of the array.
+
+ ...
+
+ 1287 return &enc1->base;
+ 1288 }
+
+v2: use explicit bounds check as suggested by Roman/Dan; avoid unsigned int cast
+
+v3: The compiler already knows how to compare the two values, so the
+ cast (int) is not needed. (Roman)
+
+Fixes: 2728e9c7c842 ("drm/amd/display: add DC changes for DCN351")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Mario Limonciello <superm1@kernel.org>
+Cc: Alex Hung <alex.hung@amd.com>
+Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Cc: ChiaHsuan Chung <chiahsuan.chung@amd.com>
+Cc: Roman Li <roman.li@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Roman Li <roman.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/dc/resource/dcn315/dcn315_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn316/dcn316_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn32/dcn32_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn321/dcn321_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 8 ++++----
+ 6 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+index 9cb72805b8d1a..ad3f229f39cba 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+@@ -1227,12 +1227,12 @@ static struct stream_encoder *dcn315_stream_encoder_create(
+ /*PHYB is wired off in HW, allow front end to remapping, otherwise needs more changes*/
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+index af82e13029c9e..b2d8383411b21 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+@@ -1221,12 +1221,12 @@ static struct stream_encoder *dcn316_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+index 6b889c8be0ca3..62dbb0f3073c0 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+@@ -1207,12 +1207,12 @@ static struct stream_encoder *dcn32_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn32_vpg_create(ctx, vpg_inst);
+ afmt = dcn32_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+index 74113c578bac4..84aaa7a5ae30f 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+@@ -1190,12 +1190,12 @@ static struct stream_encoder *dcn321_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn321_vpg_create(ctx, vpg_inst);
+ afmt = dcn321_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+index 92d5e3252d2d4..90d63e3174344 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+@@ -1272,12 +1272,12 @@ static struct stream_encoder *dcn35_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+index 6e27226cec289..9c72e87b606a2 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+@@ -1252,12 +1252,12 @@ static struct stream_encoder *dcn35_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+--
+2.51.0
+
--- /dev/null
+From 1e53305523998d46f731657cac406abe8ed50ce4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jan 2026 15:57:41 +0100
+Subject: drm/amd/display: Reject cursor plane on DCE when scaled differently
+ than primary
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit 41af6215cdbcecd12920f211239479027904abf3 ]
+
+Currently DCE doesn't support the overlay cursor, so the
+dm_crtc_get_cursor_mode() function returns DM_CURSOR_NATIVE_MODE
+unconditionally. The outcome is that it doesn't check for the
+conditions that would necessitate the overlay cursor, meaning
+that it doesn't reject cases where the native cursor mode isn't
+supported on DCE.
+
+Remove the early return from dm_crtc_get_cursor_mode() for
+DCE and instead let it perform the necessary checks and
+return DM_CURSOR_OVERLAY_MODE. Add a later check that rejects
+when DM_CURSOR_OVERLAY_MODE would be used with DCE.
+
+Fixes: 1b04dcca4fb1 ("drm/amd/display: Introduce overlay cursor mode")
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4600
+Suggested-by: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Reviewed-by: Rodrigo Siqueira <siqueira@igalia.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index b146b0529ae7f..45297715f76cf 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -11492,10 +11492,9 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev,
+
+ /* Overlay cursor not supported on HW before DCN
+ * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions
+- * as previous DCN generations, so enable native mode on DCN401 in addition to DCE
++ * as previous DCN generations, so enable native mode on DCN401
+ */
+- if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 ||
+- amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {
++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {
+ *cursor_mode = DM_CURSOR_NATIVE_MODE;
+ return 0;
+ }
+@@ -11815,6 +11814,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+ * need to be added for DC to not disable a plane by mistake
+ */
+ if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE) {
++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) {
++ drm_dbg(dev, "Overlay cursor not supported on DCE\n");
++ ret = -EINVAL;
++ goto fail;
++ }
++
+ ret = drm_atomic_add_affected_planes(state, crtc);
+ if (ret)
+ goto fail;
+--
+2.51.0
+
--- /dev/null
+From 70c32b1b0f7a2a69e912c19e5f9248619e2b8e34 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 23:38:28 +0100
+Subject: drm/amd/display: Use same max plane scaling limits for all 64 bpp
+ formats
+
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+
+[ Upstream commit f0157ce46cf0e5e2257e19d590c9b16036ce26d4 ]
+
+The plane scaling hw seems to have the same min/max plane scaling limits
+for all 16 bpc / 64 bpp interleaved pixel color formats.
+
+Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for
+all the 16 bpc fixed-point / unorm formats to use the same .fp16
+up/downscaling factor limits as used by the fp16 floating point formats.
+
+So far, 16 bpc unorm formats were not handled, and the default: path
+returned max/min factors for 32 bpp argb8888 formats, which were wrong
+and bigger than what many DCE / DCN hw generations could handle.
+
+The result sometimes was misscaling of framebuffers with
+DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616,
+DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested
+on Polaris11 / DCE-11.2.
+
+So far this went unnoticed, because only few userspace clients used such
+16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they
+did not experience this issue.
+
+With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL
+and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland
+compositor allowing for direct scanout of these formats, the scaling
+hw will be used on these formats if possible for HiDPI display scaling,
+so it is important to use the correct hw scaling limits to avoid wrong
+display.
+
+Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50
+on HiDPI displays with scaling enabled. The mutter Wayland compositor now
+correctly falls back to scaling via desktop compositing instead of direct
+scanout, thereby avoiding wrong image display. For unscaled mode, it
+correctly uses direct scanout.
+
+Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.")
+Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+index 62e30942f735d..d98c0efe5608d 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+@@ -1055,10 +1055,15 @@ static void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev,
+ *min_downscale = plane_cap->max_downscale_factor.nv12;
+ break;
+
++ /* All 64 bpp formats have the same fp16 scaling limits */
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ABGR16161616F:
++ case DRM_FORMAT_XRGB16161616:
++ case DRM_FORMAT_ARGB16161616:
++ case DRM_FORMAT_XBGR16161616:
++ case DRM_FORMAT_ABGR16161616:
+ *max_upscale = plane_cap->max_upscale_factor.fp16;
+ *min_downscale = plane_cap->max_downscale_factor.fp16;
+ break;
+--
+2.51.0
+
--- /dev/null
+From 290620d7aa998734523bb7c1c41a0094e7e24465 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 09:25:32 +0000
+Subject: drm/amdgpu: Fix memory leak in amdgpu_acpi_enumerate_xcc()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit c9be63d565789b56ca7b0197e2cb78a3671f95a8 ]
+
+In amdgpu_acpi_enumerate_xcc(), if amdgpu_acpi_dev_init() returns -ENOMEM,
+the function returns directly without releasing the allocated xcc_info,
+resulting in a memory leak.
+
+Fix this by ensuring that xcc_info is properly freed in the error paths.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: 4d5275ab0b18 ("drm/amdgpu: Add parsing of acpi xcc objects")
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+index bebfbc1497d8e..d484804181756 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+@@ -1132,8 +1132,10 @@ static int amdgpu_acpi_enumerate_xcc(void)
+ if (!dev_info)
+ ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, sbdf);
+
+- if (ret == -ENOMEM)
++ if (ret == -ENOMEM) {
++ kfree(xcc_info);
+ return ret;
++ }
+
+ if (!dev_info) {
+ kfree(xcc_info);
+--
+2.51.0
+
--- /dev/null
+From b1b04edc3dcb97b78db26bf88fd0b6c238c7751c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 08:35:15 +0000
+Subject: drm/amdgpu: Fix memory leak in amdgpu_ras_init()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit ee41e5b63c8210525c936ee637a2c8d185ce873c ]
+
+When amdgpu_nbio_ras_sw_init() fails in amdgpu_ras_init(), the function
+returns directly without freeing the allocated con structure, leading
+to a memory leak.
+
+Fix this by jumping to the release_con label to properly clean up the
+allocated memory before returning the error code.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: fdc94d3a8c88 ("drm/amdgpu: Rework pcie_bif ras sw_init")
+Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+index d9cdc89d4cde1..bf563904b3fa9 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+@@ -3643,7 +3643,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
+ * to handle fatal error */
+ r = amdgpu_nbio_ras_sw_init(adev);
+ if (r)
+- return r;
++ goto release_con;
+
+ if (adev->nbio.ras &&
+ adev->nbio.ras->init_ras_controller_interrupt) {
+--
+2.51.0
+
--- /dev/null
+From 93e37d05c9ba7d81d5c63aa40d953f1fa32d5ad3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 09:05:42 +0000
+Subject: drm/amdgpu: Use kvfree instead of kfree in
+ amdgpu_gmc_get_nps_memranges()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit 0c44d61945c4a80775292d96460aa2f22e62f86c ]
+
+amdgpu_discovery_get_nps_info() internally allocates memory for ranges
+using kvcalloc(), which may use vmalloc() for large allocation. Using
+kfree() to release vmalloc memory will lead to a memory corruption.
+
+Use kvfree() to safely handle both kmalloc and vmalloc allocations.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: b194d21b9bcc ("drm/amdgpu: Use NPS ranges from discovery table")
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+index f159641271672..c57893cce9e3d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+@@ -1260,7 +1260,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
+ }
+
+ err:
+- kfree(ranges);
++ kvfree(ranges);
+
+ return ret;
+ }
+--
+2.51.0
+
--- /dev/null
+From 7d93e95419a101fb834af2d9ff040c550fa1bd85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 21:18:11 +0530
+Subject: drm/amdkfd: Fix watch_id bounds checking in debug address watch v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit 5a19302cab5cec7ae7f1a60c619951e6c17d8742 ]
+
+The address watch clear code receives watch_id as an unsigned value
+(u32), but some helper functions were using a signed int and checked
+bits by shifting with watch_id.
+
+If a very large watch_id is passed from userspace, it can be converted
+to a negative value. This can cause invalid shifts and may access
+memory outside the watch_points array.
+
+drm/amdkfd: Fix watch_id bounds checking in debug address watch v2
+
+Fix this by checking that watch_id is within MAX_WATCH_ADDRESSES before
+using it. Also use BIT(watch_id) to test and clear bits safely.
+
+This keeps the behavior unchanged for valid watch IDs and avoids
+undefined behavior for invalid ones.
+
+Fixes the below:
+drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c:448
+kfd_dbg_trap_clear_dev_address_watch() error: buffer overflow
+'pdd->watch_points' 4 <= u32max user_rl='0-3,2147483648-u32max' uncapped
+
+drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c
+ 433 int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd,
+ 434 uint32_t watch_id)
+ 435 {
+ 436 int r;
+ 437
+ 438 if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id))
+
+kfd_dbg_owns_dev_watch_id() doesn't check for negative values so if
+watch_id is larger than INT_MAX it leads to a buffer overflow.
+(Negative shifts are undefined).
+
+ 439 return -EINVAL;
+ 440
+ 441 if (!pdd->dev->kfd->shared_resources.enable_mes) {
+ 442 r = debug_lock_and_unmap(pdd->dev->dqm);
+ 443 if (r)
+ 444 return r;
+ 445 }
+ 446
+ 447 amdgpu_gfx_off_ctrl(pdd->dev->adev, false);
+--> 448 pdd->watch_points[watch_id] = pdd->dev->kfd2kgd->clear_address_watch(
+ 449 pdd->dev->adev,
+ 450 watch_id);
+
+v2: (as per, Jonathan Kim)
+ - Add early watch_id >= MAX_WATCH_ADDRESSES validation in the set path to
+ match the clear path.
+ - Drop the redundant bounds check in kfd_dbg_owns_dev_watch_id().
+
+Fixes: e0f85f4690d0 ("drm/amdkfd: add debug set and clear address watch points operation")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Cc: Jonathan Kim <jonathan.kim@amd.com>
+Cc: Felix Kuehling <felix.kuehling@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Jonathan Kim <jonathan.kim@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+index a8abc30918013..3a8df47aa5821 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+@@ -401,27 +401,25 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i
+ return -ENOMEM;
+ }
+
+-static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id)
++static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id)
+ {
+ spin_lock(&pdd->dev->watch_points_lock);
+
+ /* process owns device watch point so safe to clear */
+- if ((pdd->alloc_watch_ids >> watch_id) & 0x1) {
+- pdd->alloc_watch_ids &= ~(0x1 << watch_id);
+- pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id);
++ if (pdd->alloc_watch_ids & BIT(watch_id)) {
++ pdd->alloc_watch_ids &= ~BIT(watch_id);
++ pdd->dev->alloc_watch_ids &= ~BIT(watch_id);
+ }
+
+ spin_unlock(&pdd->dev->watch_points_lock);
+ }
+
+-static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id)
++static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id)
+ {
+ bool owns_watch_id = false;
+
+ spin_lock(&pdd->dev->watch_points_lock);
+- owns_watch_id = watch_id < MAX_WATCH_ADDRESSES &&
+- ((pdd->alloc_watch_ids >> watch_id) & 0x1);
+-
++ owns_watch_id = pdd->alloc_watch_ids & BIT(watch_id);
+ spin_unlock(&pdd->dev->watch_points_lock);
+
+ return owns_watch_id;
+@@ -432,6 +430,9 @@ int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd,
+ {
+ int r;
+
++ if (watch_id >= MAX_WATCH_ADDRESSES)
++ return -EINVAL;
++
+ if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id))
+ return -EINVAL;
+
+@@ -469,6 +470,9 @@ int kfd_dbg_trap_set_dev_address_watch(struct kfd_process_device *pdd,
+ if (r)
+ return r;
+
++ if (*watch_id >= MAX_WATCH_ADDRESSES)
++ return -EINVAL;
++
+ if (!pdd->dev->kfd->shared_resources.enable_mes) {
+ r = debug_lock_and_unmap(pdd->dev->dqm);
+ if (r) {
+--
+2.51.0
+
--- /dev/null
+From 0ee5dd8dccbabbe171e9a9badc8018c31ec2a252 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jan 2026 08:55:49 +0530
+Subject: drm/i915/acpi: free _DSM package when no connectors
+
+From: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+
+[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ]
+
+acpi_evaluate_dsm_typed() returns an ACPI package in pkg.
+When pkg->package.count == 0, we returned without freeing pkg,
+leaking memory. Free pkg before returning on the empty case.
+
+Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_acpi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c
+index c3b29a331d725..859fedb9d93ea 100644
+--- a/drivers/gpu/drm/i915/display/intel_acpi.c
++++ b/drivers/gpu/drm/i915/display/intel_acpi.c
+@@ -93,6 +93,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle)
+
+ if (!pkg->package.count) {
+ DRM_DEBUG_DRIVER("no connection in _DSM\n");
++ ACPI_FREE(pkg);
+ return;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From cc6ed325f74431c3804c32e79a79d1b0df1340c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 16:47:27 -0700
+Subject: drm/xe: Add xe_tile backpointer to xe_mmio
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit 1877c88fa9b9bdbce7a65d7cbd2aa4e29bb514af ]
+
+Once MMIO operations stop being (incorrectly) tied to a GT, we'll still
+need a backpointer for feature checks, message logging, and tracepoints.
+Use a tile backpointer since that may allow the most useful debugging
+output, while also providing access to the xe_device.
+
+v2:
+ - Make backpointer an xe_tile instead of xe_device. (Michal)
+
+Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> # v1
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-52-matthew.d.roper@intel.com
+Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_device_types.h | 3 +++
+ drivers/gpu/drm/xe/xe_mmio.c | 3 +++
+ drivers/gpu/drm/xe/xe_pci.c | 2 ++
+ 3 files changed, 8 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
+index 56630dabb85f7..ee3d0354c1539 100644
+--- a/drivers/gpu/drm/xe/xe_device_types.h
++++ b/drivers/gpu/drm/xe/xe_device_types.h
+@@ -115,6 +115,9 @@ struct xe_mem_region {
+ * subregions of the overall IO space).
+ */
+ struct xe_mmio {
++ /** @tile: Backpointer to tile, used for tracing */
++ struct xe_tile *tile;
++
+ /** @regs: Map used to access registers. */
+ void __iomem *regs;
+
+diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
+index 2f72516e01327..46924f4042418 100644
+--- a/drivers/gpu/drm/xe/xe_mmio.c
++++ b/drivers/gpu/drm/xe/xe_mmio.c
+@@ -98,6 +98,7 @@ static void mmio_multi_tile_setup(struct xe_device *xe, size_t tile_mmio_size)
+ for_each_tile(tile, xe, id) {
+ tile->mmio.regs_size = SZ_4M;
+ tile->mmio.regs = regs;
++ tile->mmio.tile = tile;
+ regs += tile_mmio_size;
+ }
+ }
+@@ -134,6 +135,7 @@ static void mmio_extension_setup(struct xe_device *xe, size_t tile_mmio_size,
+ for_each_tile(tile, xe, id) {
+ tile->mmio_ext.regs_size = tile_mmio_ext_size;
+ tile->mmio_ext.regs = regs;
++ tile->mmio_ext.tile = tile;
+ regs += tile_mmio_ext_size;
+ }
+ }
+@@ -180,6 +182,7 @@ int xe_mmio_init(struct xe_device *xe)
+ /* Setup first tile; other tiles (if present) will be setup later. */
+ root_tile->mmio.regs_size = SZ_4M;
+ root_tile->mmio.regs = xe->mmio.regs;
++ root_tile->mmio.tile = root_tile;
+
+ return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe);
+ }
+diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
+index f7b6ca281dec3..d0cc5d45a2e4b 100644
+--- a/drivers/gpu/drm/xe/xe_pci.c
++++ b/drivers/gpu/drm/xe/xe_pci.c
+@@ -710,6 +710,7 @@ static int xe_info_init(struct xe_device *xe,
+ gt->info.engine_mask = graphics_desc->hw_engine_mask;
+ gt->mmio.regs = tile->mmio.regs;
+ gt->mmio.regs_size = tile->mmio.regs_size;
++ gt->mmio.tile = tile;
+ if (MEDIA_VER(xe) < 13 && media_desc)
+ gt->info.engine_mask |= media_desc->hw_engine_mask;
+
+@@ -732,6 +733,7 @@ static int xe_info_init(struct xe_device *xe,
+ gt->mmio.regs_size = tile->mmio.regs_size;
+ gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET;
+ gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH;
++ gt->mmio.tile = tile;
+
+ /*
+ * FIXME: At the moment multi-tile and standalone media are
+--
+2.51.0
+
--- /dev/null
+From fe9092a84569df5233488f011de5b2a05f80bdbf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 16:47:28 -0700
+Subject: drm/xe: Adjust mmio code to pass VF substructure to SRIOV code
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit 6fb5d1a1d376910700d054d13cefbf0812b444a9 ]
+
+Although we want to break the GT-centric nature of the MMIO code in the
+general driver, the SRIOV handling still relies on data in a VF
+substructure of the GT. So add a GT backpointer, but name it
+sriov_vf_gt to make it clear that it's only for this one specific
+special case and will not be set or usable for anything else.
+
+v2:
+ - Store backpointer to the GT itself rather than the SRIOV-specific
+ substructure. (Michal)
+
+Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com> # v1
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-53-matthew.d.roper@intel.com
+Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_device_types.h | 8 ++++++++
+ drivers/gpu/drm/xe/xe_pci.c | 5 +++++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
+index ee3d0354c1539..78a1f8b78e269 100644
+--- a/drivers/gpu/drm/xe/xe_device_types.h
++++ b/drivers/gpu/drm/xe/xe_device_types.h
+@@ -121,6 +121,14 @@ struct xe_mmio {
+ /** @regs: Map used to access registers. */
+ void __iomem *regs;
+
++ /**
++ * @sriov_vf_gt: Backpointer to GT.
++ *
++ * This pointer is only set for GT MMIO regions and only when running
++ * as an SRIOV VF structure
++ */
++ struct xe_gt *sriov_vf_gt;
++
+ /**
+ * @regs_size: Length of the register region within the map.
+ *
+diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
+index d0cc5d45a2e4b..9d807d9a0807a 100644
+--- a/drivers/gpu/drm/xe/xe_pci.c
++++ b/drivers/gpu/drm/xe/xe_pci.c
+@@ -711,6 +711,9 @@ static int xe_info_init(struct xe_device *xe,
+ gt->mmio.regs = tile->mmio.regs;
+ gt->mmio.regs_size = tile->mmio.regs_size;
+ gt->mmio.tile = tile;
++ if (IS_SRIOV_VF(xe))
++ gt->mmio.sriov_vf_gt = gt;
++
+ if (MEDIA_VER(xe) < 13 && media_desc)
+ gt->info.engine_mask |= media_desc->hw_engine_mask;
+
+@@ -734,6 +737,8 @@ static int xe_info_init(struct xe_device *xe,
+ gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET;
+ gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH;
+ gt->mmio.tile = tile;
++ if (IS_SRIOV_VF(xe))
++ gt->mmio.sriov_vf_gt = gt;
+
+ /*
+ * FIXME: At the moment multi-tile and standalone media are
+--
+2.51.0
+
--- /dev/null
+From ba0a0a75c5684ad9ea99aa965674e1e0185b5d82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 16:47:23 -0700
+Subject: drm/xe: Clarify size of MMIO region
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit d4aff99aefa2a3c8999a98f0d52a977b284b9ec9 ]
+
+xe_mmio currently has a size parameter that is assigned but never used
+anywhere. The current values assigned appear to be the size of the BAR
+region assigned for the tile (both for registers and other purposes such
+as the GGTT). Since the current field isn't being used for anything,
+change the assignments to 4MB (the size of the register region on all
+current platform) and rename the field to 'regs_size' to more clearly
+describe what it represents. We can use this value in later patches to
+help ensure no register accesses accidentally go past the end of the
+desired register space (which might not be caught easily if they still
+fall within the iomap).
+
+v2:
+ - s/regs_length/regs_size/ (Lucas)
+ - Clarify kerneldoc description (Lucas)
+
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-48-matthew.d.roper@intel.com
+Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_device_types.h | 10 ++++++++--
+ drivers/gpu/drm/xe/xe_mmio.c | 10 ++++++++--
+ 2 files changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
+index f06ff5571ab1c..57d778655dcbd 100644
+--- a/drivers/gpu/drm/xe/xe_device_types.h
++++ b/drivers/gpu/drm/xe/xe_device_types.h
+@@ -119,8 +119,14 @@ struct xe_mmio {
+ /** @regs: Map used to access registers. */
+ void __iomem *regs;
+
+- /** @size: Size of the map. */
+- size_t size;
++ /**
++ * @regs_size: Length of the register region within the map.
++ *
++ * The size of the iomap set in *regs is generally larger than the
++ * register mmio space since it includes unused regions and/or
++ * non-register regions such as the GGTT PTEs.
++ */
++ size_t regs_size;
+ };
+
+ /**
+diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
+index 3fd462fda6255..f210e7470eae5 100644
+--- a/drivers/gpu/drm/xe/xe_mmio.c
++++ b/drivers/gpu/drm/xe/xe_mmio.c
+@@ -36,13 +36,19 @@ static void tiles_fini(void *arg)
+ /*
+ * On multi-tile devices, partition the BAR space for MMIO on each tile,
+ * possibly accounting for register override on the number of tiles available.
++ * tile_mmio_size contains both the tile's 4MB register space, as well as
++ * additional space for the GTT and other (possibly unused) regions).
+ * Resulting memory layout is like below:
+ *
+ * .----------------------. <- tile_count * tile_mmio_size
+ * | .... |
+ * |----------------------| <- 2 * tile_mmio_size
++ * | tile1 GTT + other |
++ * |----------------------| <- 1 * tile_mmio_size + 4MB
+ * | tile1->mmio.regs |
+ * |----------------------| <- 1 * tile_mmio_size
++ * | tile0 GTT + other |
++ * |----------------------| <- 4MB
+ * | tile0->mmio.regs |
+ * '----------------------' <- 0MB
+ */
+@@ -90,7 +96,7 @@ static void mmio_multi_tile_setup(struct xe_device *xe, size_t tile_mmio_size)
+
+ regs = xe->mmio.regs;
+ for_each_tile(tile, xe, id) {
+- tile->mmio.size = tile_mmio_size;
++ tile->mmio.regs_size = SZ_4M;
+ tile->mmio.regs = regs;
+ regs += tile_mmio_size;
+ }
+@@ -172,7 +178,7 @@ int xe_mmio_init(struct xe_device *xe)
+ }
+
+ /* Setup first tile; other tiles (if present) will be setup later. */
+- root_tile->mmio.size = SZ_16M;
++ root_tile->mmio.regs_size = SZ_4M;
+ root_tile->mmio.regs = xe->mmio.regs;
+
+ return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe);
+--
+2.51.0
+
--- /dev/null
+From aafc2fdb917dec4782099d9c5753badbd379d4ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 16:47:22 -0700
+Subject: drm/xe: Create dedicated xe_mmio structure
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit 34953ee349dde9d1733d4af75e929f7fd5fab539 ]
+
+Pull the 'mmio' substructure from xe_tile out into a dedicated type.
+Future patches will expand this structure and then eventually move MMIO
+read/write operations over to using this type.
+
+v2:
+ - Fix kerneldoc of 'size' field. The rename/refocusing of this field
+ got moved to the next patch of the series. (Lucas)
+ - Correct commit message; it's the tile, not the device, mmio that's
+ been pulled out to a separate type. (Michal)
+
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-47-matthew.d.roper@intel.com
+Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_device_types.h | 24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
+index 687f3a9039bb1..f06ff5571ab1c 100644
+--- a/drivers/gpu/drm/xe/xe_device_types.h
++++ b/drivers/gpu/drm/xe/xe_device_types.h
+@@ -107,6 +107,22 @@ struct xe_mem_region {
+ void __iomem *mapping;
+ };
+
++/**
++ * struct xe_mmio - register mmio structure
++ *
++ * Represents an MMIO region that the CPU may use to access registers. A
++ * region may share its IO map with other regions (e.g., all GTs within a
++ * tile share the same map with their parent tile, but represent different
++ * subregions of the overall IO space).
++ */
++struct xe_mmio {
++ /** @regs: Map used to access registers. */
++ void __iomem *regs;
++
++ /** @size: Size of the map. */
++ size_t size;
++};
++
+ /**
+ * struct xe_tile - hardware tile structure
+ *
+@@ -148,13 +164,7 @@ struct xe_tile {
+ * * 4MB-8MB: reserved
+ * * 8MB-16MB: global GTT
+ */
+- struct {
+- /** @mmio.size: size of tile's MMIO space */
+- size_t size;
+-
+- /** @mmio.regs: pointer to tile's MMIO space (starting with registers) */
+- void __iomem *regs;
+- } mmio;
++ struct xe_mmio mmio;
+
+ /**
+ * @mmio_ext: MMIO-extension info for a tile.
+--
+2.51.0
+
--- /dev/null
+From 5baf6a837a980fa4223241217bb9da5d9154e7bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jan 2026 16:56:22 +0000
+Subject: drm/xe/mmio: Avoid double-adjust in 64-bit reads
+
+From: Shuicheng Lin <shuicheng.lin@intel.com>
+
+[ Upstream commit 4a9b4e1fa52a6aaa1adbb7f759048df14afed54c ]
+
+xe_mmio_read64_2x32() was adjusting register addresses and then
+calling xe_mmio_read32(), which applies the adjustment again.
+This may shift accesses twice if adj_offset < adj_limit. There is
+no issue currently, as for media gt, adj_offset > adj_limit, so
+the 2nd adjust will be a no-op. But it may not work in future.
+
+To fix it, replace the adjusted-address comparison with a direct
+sanity check that ensures the MMIO address adjustment cutoff never
+falls within the 8-byte range of a 64-bit register. And let
+xe_mmio_read32() handle address translation.
+
+v2: rewrite the sanity check in a more natural way. (Matt)
+v3: Add Fixes tag. (Jani)
+
+Fixes: 07431945d8ae ("drm/xe: Avoid 64-bit register reads")
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Cc: Jani Nikula <jani.nikula@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260130165621.471408-2-shuicheng.lin@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit a30f999681126b128a43137793ac84b6a5b7443f)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_mmio.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
+index 9ea0973337eda..449e6c5636712 100644
+--- a/drivers/gpu/drm/xe/xe_mmio.c
++++ b/drivers/gpu/drm/xe/xe_mmio.c
+@@ -316,11 +316,11 @@ u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg)
+ struct xe_reg reg_udw = { .addr = reg.addr + 0x4 };
+ u32 ldw, udw, oldudw, retries;
+
+- reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr);
+- reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr);
+-
+- /* we shouldn't adjust just one register address */
+- xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4);
++ /*
++ * The two dwords of a 64-bit register can never straddle the offset
++ * adjustment cutoff.
++ */
++ xe_tile_assert(mmio->tile, !in_range(mmio->adj_limit, reg.addr + 1, 7));
+
+ oldudw = xe_mmio_read32(mmio, reg_udw);
+ for (retries = 5; retries; --retries) {
+--
+2.51.0
+
--- /dev/null
+From d8e37c95399d9cb29a359d4f9eabf62dbcd338da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 16:47:21 -0700
+Subject: drm/xe: Move forcewake to 'gt.pm' substructure
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit 998fde0647671c82f637e299026d951f9b155b37 ]
+
+Forcewake is a general GT power management concept that isn't specific
+to MMIO register access. Move the forcewake information for a GT out of
+the 'mmio' substruct and into a 'pm' substruct. Also use the gt_to_fw()
+helper in a few more places where it was being open-coded.
+
+v2:
+ - Kerneldoc tweaks. (Lucas)
+
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-46-matthew.d.roper@intel.com
+Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_device.h | 2 +-
+ drivers/gpu/drm/xe/xe_gt_types.h | 15 ++++++++++++---
+ drivers/gpu/drm/xe/xe_reg_sr.c | 9 +++++----
+ 3 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h
+index 34620ef855c0c..b662b7652431e 100644
+--- a/drivers/gpu/drm/xe/xe_device.h
++++ b/drivers/gpu/drm/xe/xe_device.h
+@@ -138,7 +138,7 @@ static inline bool xe_device_uc_enabled(struct xe_device *xe)
+
+ static inline struct xe_force_wake *gt_to_fw(struct xe_gt *gt)
+ {
+- return >->mmio.fw;
++ return >->pm.fw;
+ }
+
+ void xe_device_assert_mem_access(struct xe_device *xe);
+diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h
+index 3d1c51de02687..dd6bbef0bbcd8 100644
+--- a/drivers/gpu/drm/xe/xe_gt_types.h
++++ b/drivers/gpu/drm/xe/xe_gt_types.h
+@@ -145,11 +145,9 @@ struct xe_gt {
+ /**
+ * @mmio: mmio info for GT. All GTs within a tile share the same
+ * register space, but have their own copy of GSI registers at a
+- * specific offset, as well as their own forcewake handling.
++ * specific offset.
+ */
+ struct {
+- /** @mmio.fw: force wake for GT */
+- struct xe_force_wake fw;
+ /**
+ * @mmio.adj_limit: adjust MMIO address if address is below this
+ * value
+@@ -159,6 +157,17 @@ struct xe_gt {
+ u32 adj_offset;
+ } mmio;
+
++ /**
++ * @pm: power management info for GT. The driver uses the GT's
++ * "force wake" interface to wake up specific parts of the GT hardware
++ * from C6 sleep states and ensure the hardware remains awake while it
++ * is being actively used.
++ */
++ struct {
++ /** @pm.fw: force wake for GT */
++ struct xe_force_wake fw;
++ } pm;
++
+ /** @sriov: virtualization data related to GT */
+ union {
+ /** @sriov.pf: PF data. Valid only if driver is running as PF */
+diff --git a/drivers/gpu/drm/xe/xe_reg_sr.c b/drivers/gpu/drm/xe/xe_reg_sr.c
+index 52969c0909659..d3773a9853872 100644
+--- a/drivers/gpu/drm/xe/xe_reg_sr.c
++++ b/drivers/gpu/drm/xe/xe_reg_sr.c
+@@ -15,6 +15,7 @@
+
+ #include "regs/xe_engine_regs.h"
+ #include "regs/xe_gt_regs.h"
++#include "xe_device.h"
+ #include "xe_device_types.h"
+ #include "xe_force_wake.h"
+ #include "xe_gt.h"
+@@ -175,14 +176,14 @@ void xe_reg_sr_apply_mmio(struct xe_reg_sr *sr, struct xe_gt *gt)
+
+ xe_gt_dbg(gt, "Applying %s save-restore MMIOs\n", sr->name);
+
+- err = xe_force_wake_get(>->mmio.fw, XE_FORCEWAKE_ALL);
++ err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+ if (err)
+ goto err_force_wake;
+
+ xa_for_each(&sr->xa, reg, entry)
+ apply_one_mmio(gt, entry);
+
+- err = xe_force_wake_put(>->mmio.fw, XE_FORCEWAKE_ALL);
++ err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+ XE_WARN_ON(err);
+
+ return;
+@@ -208,7 +209,7 @@ void xe_reg_sr_apply_whitelist(struct xe_hw_engine *hwe)
+
+ drm_dbg(&xe->drm, "Whitelisting %s registers\n", sr->name);
+
+- err = xe_force_wake_get(>->mmio.fw, XE_FORCEWAKE_ALL);
++ err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+ if (err)
+ goto err_force_wake;
+
+@@ -234,7 +235,7 @@ void xe_reg_sr_apply_whitelist(struct xe_hw_engine *hwe)
+ xe_mmio_write32(gt, RING_FORCE_TO_NONPRIV(mmio_base, slot), addr);
+ }
+
+- err = xe_force_wake_put(>->mmio.fw, XE_FORCEWAKE_ALL);
++ err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+ XE_WARN_ON(err);
+
+ return;
+--
+2.51.0
+
--- /dev/null
+From 0789611e82a8445cd9a5d6b5c6367c2f65dd7f6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 16:47:24 -0700
+Subject: drm/xe: Move GSI offset adjustment fields into 'struct xe_mmio'
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit 9d383916a552784ec35e6d25469fc2da9bcd9948 ]
+
+By moving the GSI adjustment fields into 'struct xe_mmio' we can replace
+the GT's MMIO substructure with another instance of xe_mmio. At the
+moment this means MMIO operations wind up pulling information from two
+different places (the tile's xe_mmio for the iomap and the GT's xe_mmio
+for the adjustment), but we'll address that in future patches.
+
+The type headers change a bit with this change, meaning that various
+files should be including xe_device_types.h instead of (or in addition
+to) xe_gt_types.h.
+
+v2:
+ - Fix pre-existing kerneldoc typo while moving the fields (Lucas)
+v3:
+ - Add missing '@' in kerneldoc. (Rodrigo)
+
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-49-matthew.d.roper@intel.com
+Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_assert.h | 2 +-
+ drivers/gpu/drm/xe/xe_device.h | 1 +
+ drivers/gpu/drm/xe/xe_device_types.h | 7 ++++++-
+ drivers/gpu/drm/xe/xe_gt_freq.c | 2 +-
+ drivers/gpu/drm/xe/xe_gt_printk.h | 2 +-
+ drivers/gpu/drm/xe/xe_gt_types.h | 11 ++---------
+ 6 files changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_assert.h b/drivers/gpu/drm/xe/xe_assert.h
+index e22bbf57fca75..04d6b95c6d878 100644
+--- a/drivers/gpu/drm/xe/xe_assert.h
++++ b/drivers/gpu/drm/xe/xe_assert.h
+@@ -10,7 +10,7 @@
+
+ #include <drm/drm_print.h>
+
+-#include "xe_device_types.h"
++#include "xe_gt_types.h"
+ #include "xe_step.h"
+
+ /**
+diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h
+index b662b7652431e..5dad24fc487ca 100644
+--- a/drivers/gpu/drm/xe/xe_device.h
++++ b/drivers/gpu/drm/xe/xe_device.h
+@@ -9,6 +9,7 @@
+ #include <drm/drm_util.h>
+
+ #include "xe_device_types.h"
++#include "xe_gt_types.h"
+
+ static inline struct xe_device *to_xe_device(const struct drm_device *dev)
+ {
+diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
+index 57d778655dcbd..2291ac1fa96e1 100644
+--- a/drivers/gpu/drm/xe/xe_device_types.h
++++ b/drivers/gpu/drm/xe/xe_device_types.h
+@@ -14,7 +14,6 @@
+
+ #include "xe_devcoredump_types.h"
+ #include "xe_heci_gsc.h"
+-#include "xe_gt_types.h"
+ #include "xe_lmtt_types.h"
+ #include "xe_memirq_types.h"
+ #include "xe_oa.h"
+@@ -127,6 +126,12 @@ struct xe_mmio {
+ * non-register regions such as the GGTT PTEs.
+ */
+ size_t regs_size;
++
++ /** @adj_limit: adjust MMIO address if address is below this value */
++ u32 adj_limit;
++
++ /** @adj_offset: offset to add to MMIO address when adjusting */
++ u32 adj_offset;
+ };
+
+ /**
+diff --git a/drivers/gpu/drm/xe/xe_gt_freq.c b/drivers/gpu/drm/xe/xe_gt_freq.c
+index a05fde2c7b122..62a8aa2fdbb0d 100644
+--- a/drivers/gpu/drm/xe/xe_gt_freq.c
++++ b/drivers/gpu/drm/xe/xe_gt_freq.c
+@@ -11,9 +11,9 @@
+ #include <drm/drm_managed.h>
+ #include <drm/drm_print.h>
+
+-#include "xe_device_types.h"
+ #include "xe_gt_sysfs.h"
+ #include "xe_gt_throttle.h"
++#include "xe_gt_types.h"
+ #include "xe_guc_pc.h"
+ #include "xe_pm.h"
+
+diff --git a/drivers/gpu/drm/xe/xe_gt_printk.h b/drivers/gpu/drm/xe/xe_gt_printk.h
+index d6228baaff1ef..5dc71394372d6 100644
+--- a/drivers/gpu/drm/xe/xe_gt_printk.h
++++ b/drivers/gpu/drm/xe/xe_gt_printk.h
+@@ -8,7 +8,7 @@
+
+ #include <drm/drm_print.h>
+
+-#include "xe_device_types.h"
++#include "xe_gt_types.h"
+
+ #define xe_gt_printk(_gt, _level, _fmt, ...) \
+ drm_##_level(>_to_xe(_gt)->drm, "GT%u: " _fmt, (_gt)->info.id, ##__VA_ARGS__)
+diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h
+index dd6bbef0bbcd8..a287b98ee70b4 100644
+--- a/drivers/gpu/drm/xe/xe_gt_types.h
++++ b/drivers/gpu/drm/xe/xe_gt_types.h
+@@ -6,6 +6,7 @@
+ #ifndef _XE_GT_TYPES_H_
+ #define _XE_GT_TYPES_H_
+
++#include "xe_device_types.h"
+ #include "xe_force_wake_types.h"
+ #include "xe_gt_idle_types.h"
+ #include "xe_gt_sriov_pf_types.h"
+@@ -147,15 +148,7 @@ struct xe_gt {
+ * register space, but have their own copy of GSI registers at a
+ * specific offset.
+ */
+- struct {
+- /**
+- * @mmio.adj_limit: adjust MMIO address if address is below this
+- * value
+- */
+- u32 adj_limit;
+- /** @mmio.adj_offset: offect to add to MMIO address when adjusting */
+- u32 adj_offset;
+- } mmio;
++ struct xe_mmio mmio;
+
+ /**
+ * @pm: power management info for GT. The driver uses the GT's
+--
+2.51.0
+
--- /dev/null
+From 9e3477d518759a07742f5cfac9589e24ebe0a976 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 16:47:25 -0700
+Subject: drm/xe: Populate GT's mmio iomap from tile during init
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit fa599b8c95a7070430703f4908a50141f2c7088c ]
+
+Each GT should share the same register iomap as its parent tile. Future
+patches will switch to access the iomap through the GT's mmio substruct
+rather than through the tile.
+
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-50-matthew.d.roper@intel.com
+Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_pci.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
+index da09c26249f5f..f7b6ca281dec3 100644
+--- a/drivers/gpu/drm/xe/xe_pci.c
++++ b/drivers/gpu/drm/xe/xe_pci.c
+@@ -708,6 +708,8 @@ static int xe_info_init(struct xe_device *xe,
+ gt->info.type = XE_GT_TYPE_MAIN;
+ gt->info.has_indirect_ring_state = graphics_desc->has_indirect_ring_state;
+ gt->info.engine_mask = graphics_desc->hw_engine_mask;
++ gt->mmio.regs = tile->mmio.regs;
++ gt->mmio.regs_size = tile->mmio.regs_size;
+ if (MEDIA_VER(xe) < 13 && media_desc)
+ gt->info.engine_mask |= media_desc->hw_engine_mask;
+
+@@ -726,6 +728,8 @@ static int xe_info_init(struct xe_device *xe,
+ gt->info.type = XE_GT_TYPE_MEDIA;
+ gt->info.has_indirect_ring_state = media_desc->has_indirect_ring_state;
+ gt->info.engine_mask = media_desc->hw_engine_mask;
++ gt->mmio.regs = tile->mmio.regs;
++ gt->mmio.regs_size = tile->mmio.regs_size;
+ gt->mmio.adj_offset = MEDIA_GT_GSI_OFFSET;
+ gt->mmio.adj_limit = MEDIA_GT_GSI_LENGTH;
+
+--
+2.51.0
+
--- /dev/null
+From efcbe96c93bb1bd197bb7251e449ca330abff294 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Jan 2025 10:46:59 -0800
+Subject: drm/xe/ptl: Apply Wa_13011645652
+
+From: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
+
+[ Upstream commit dddc53806dd2a10e210d5ea08caec6d3f92440b2 ]
+
+Extend Wa_13011645652 to PTL.
+
+Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
+Reviewed-by: Stuart Summers <stuart.summers@intel.com>
+Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250116184659.384874-1-vinay.belgaumkar@intel.com
+Stable-dep-of: bc6387a2e0c1 ("drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_wa_oob.rules | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_wa_oob.rules b/drivers/gpu/drm/xe/xe_wa_oob.rules
+index 93fa2708ee378..e726fcb307905 100644
+--- a/drivers/gpu/drm/xe/xe_wa_oob.rules
++++ b/drivers/gpu/drm/xe/xe_wa_oob.rules
+@@ -27,6 +27,7 @@
+ 16022287689 GRAPHICS_VERSION(2001)
+ GRAPHICS_VERSION(2004)
+ 13011645652 GRAPHICS_VERSION(2004)
++ GRAPHICS_VERSION(3001)
+ 14022293748 GRAPHICS_VERSION(2001)
+ GRAPHICS_VERSION(2004)
+ GRAPHICS_VERSION_RANGE(3000, 3001)
+--
+2.51.0
+
--- /dev/null
+From c65929728ab60cbbf4c24061d8f7c3bcfdc7dc8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 16:47:29 -0700
+Subject: drm/xe: Switch MMIO interface to take xe_mmio instead of xe_gt
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit a84590c5ceb354d2e9f7f6812cfb3a9709e14afa ]
+
+Since much of the MMIO register access done by the driver is to non-GT
+registers, use of 'xe_gt' in these interfaces has been a long-standing
+design flaw that's been hard to disentangle.
+
+To avoid a flag day across the whole driver, munge the function names
+and add temporary compatibility macros with the original function names
+that can accept either the new xe_mmio or the old xe_gt structure as a
+parameter. This will allow us to slowly convert parts of the driver
+over to the new interface independently.
+
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-54-matthew.d.roper@intel.com
+Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_mmio.c | 131 ++++++++++++++++------------------
+ drivers/gpu/drm/xe/xe_mmio.h | 76 +++++++++++++++-----
+ drivers/gpu/drm/xe/xe_trace.h | 7 +-
+ 3 files changed, 126 insertions(+), 88 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
+index 46924f4042418..9ea0973337eda 100644
+--- a/drivers/gpu/drm/xe/xe_mmio.c
++++ b/drivers/gpu/drm/xe/xe_mmio.c
+@@ -67,16 +67,16 @@ static void mmio_multi_tile_setup(struct xe_device *xe, size_t tile_mmio_size)
+
+ /* Possibly override number of tile based on configuration register */
+ if (!xe->info.skip_mtcfg) {
+- struct xe_gt *gt = xe_root_mmio_gt(xe);
++ struct xe_mmio *mmio = xe_root_tile_mmio(xe);
+ u8 tile_count;
+ u32 mtcfg;
+
+ /*
+ * Although the per-tile mmio regs are not yet initialized, this
+- * is fine as it's going to the root gt, that's guaranteed to be
+- * initialized earlier in xe_mmio_init()
++ * is fine as it's going to the root tile's mmio, that's
++ * guaranteed to be initialized earlier in xe_mmio_init()
+ */
+- mtcfg = xe_mmio_read64_2x32(gt, XEHP_MTCFG_ADDR);
++ mtcfg = xe_mmio_read64_2x32(mmio, XEHP_MTCFG_ADDR);
+ tile_count = REG_FIELD_GET(TILE_COUNT, mtcfg) + 1;
+
+ if (tile_count < xe->info.tile_count) {
+@@ -187,116 +187,111 @@ int xe_mmio_init(struct xe_device *xe)
+ return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe);
+ }
+
+-static void mmio_flush_pending_writes(struct xe_gt *gt)
++static void mmio_flush_pending_writes(struct xe_mmio *mmio)
+ {
+ #define DUMMY_REG_OFFSET 0x130030
+- struct xe_tile *tile = gt_to_tile(gt);
+ int i;
+
+- if (tile->xe->info.platform != XE_LUNARLAKE)
++ if (mmio->tile->xe->info.platform != XE_LUNARLAKE)
+ return;
+
+ /* 4 dummy writes */
+ for (i = 0; i < 4; i++)
+- writel(0, tile->mmio.regs + DUMMY_REG_OFFSET);
++ writel(0, mmio->regs + DUMMY_REG_OFFSET);
+ }
+
+-u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg)
++u8 __xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg)
+ {
+- struct xe_tile *tile = gt_to_tile(gt);
+- u32 addr = xe_mmio_adjusted_addr(gt, reg.addr);
++ u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr);
+ u8 val;
+
+ /* Wa_15015404425 */
+- mmio_flush_pending_writes(gt);
++ mmio_flush_pending_writes(mmio);
+
+- val = readb((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr);
+- trace_xe_reg_rw(gt, false, addr, val, sizeof(val));
++ val = readb(mmio->regs + addr);
++ trace_xe_reg_rw(mmio, false, addr, val, sizeof(val));
+
+ return val;
+ }
+
+-u16 xe_mmio_read16(struct xe_gt *gt, struct xe_reg reg)
++u16 __xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg)
+ {
+- struct xe_tile *tile = gt_to_tile(gt);
+- u32 addr = xe_mmio_adjusted_addr(gt, reg.addr);
++ u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr);
+ u16 val;
+
+ /* Wa_15015404425 */
+- mmio_flush_pending_writes(gt);
++ mmio_flush_pending_writes(mmio);
+
+- val = readw((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr);
+- trace_xe_reg_rw(gt, false, addr, val, sizeof(val));
++ val = readw(mmio->regs + addr);
++ trace_xe_reg_rw(mmio, false, addr, val, sizeof(val));
+
+ return val;
+ }
+
+-void xe_mmio_write32(struct xe_gt *gt, struct xe_reg reg, u32 val)
++void __xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val)
+ {
+- struct xe_tile *tile = gt_to_tile(gt);
+- u32 addr = xe_mmio_adjusted_addr(gt, reg.addr);
++ u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr);
+
+- trace_xe_reg_rw(gt, true, addr, val, sizeof(val));
++ trace_xe_reg_rw(mmio, true, addr, val, sizeof(val));
+
+- if (!reg.vf && IS_SRIOV_VF(gt_to_xe(gt)))
+- xe_gt_sriov_vf_write32(gt, reg, val);
++ if (!reg.vf && mmio->sriov_vf_gt)
++ xe_gt_sriov_vf_write32(mmio->sriov_vf_gt, reg, val);
+ else
+- writel(val, (reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr);
++ writel(val, mmio->regs + addr);
+ }
+
+-u32 xe_mmio_read32(struct xe_gt *gt, struct xe_reg reg)
++u32 __xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg)
+ {
+- struct xe_tile *tile = gt_to_tile(gt);
+- u32 addr = xe_mmio_adjusted_addr(gt, reg.addr);
++ u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr);
+ u32 val;
+
+ /* Wa_15015404425 */
+- mmio_flush_pending_writes(gt);
++ mmio_flush_pending_writes(mmio);
+
+- if (!reg.vf && IS_SRIOV_VF(gt_to_xe(gt)))
+- val = xe_gt_sriov_vf_read32(gt, reg);
++ if (!reg.vf && mmio->sriov_vf_gt)
++ val = xe_gt_sriov_vf_read32(mmio->sriov_vf_gt, reg);
+ else
+- val = readl((reg.ext ? tile->mmio_ext.regs : tile->mmio.regs) + addr);
++ val = readl(mmio->regs + addr);
+
+- trace_xe_reg_rw(gt, false, addr, val, sizeof(val));
++ trace_xe_reg_rw(mmio, false, addr, val, sizeof(val));
+
+ return val;
+ }
+
+-u32 xe_mmio_rmw32(struct xe_gt *gt, struct xe_reg reg, u32 clr, u32 set)
++u32 __xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set)
+ {
+ u32 old, reg_val;
+
+- old = xe_mmio_read32(gt, reg);
++ old = xe_mmio_read32(mmio, reg);
+ reg_val = (old & ~clr) | set;
+- xe_mmio_write32(gt, reg, reg_val);
++ xe_mmio_write32(mmio, reg, reg_val);
+
+ return old;
+ }
+
+-int xe_mmio_write32_and_verify(struct xe_gt *gt,
+- struct xe_reg reg, u32 val, u32 mask, u32 eval)
++int __xe_mmio_write32_and_verify(struct xe_mmio *mmio,
++ struct xe_reg reg, u32 val, u32 mask, u32 eval)
+ {
+ u32 reg_val;
+
+- xe_mmio_write32(gt, reg, val);
+- reg_val = xe_mmio_read32(gt, reg);
++ xe_mmio_write32(mmio, reg, val);
++ reg_val = xe_mmio_read32(mmio, reg);
+
+ return (reg_val & mask) != eval ? -EINVAL : 0;
+ }
+
+-bool xe_mmio_in_range(const struct xe_gt *gt,
+- const struct xe_mmio_range *range,
+- struct xe_reg reg)
++bool __xe_mmio_in_range(const struct xe_mmio *mmio,
++ const struct xe_mmio_range *range,
++ struct xe_reg reg)
+ {
+- u32 addr = xe_mmio_adjusted_addr(gt, reg.addr);
++ u32 addr = xe_mmio_adjusted_addr(mmio, reg.addr);
+
+ return range && addr >= range->start && addr <= range->end;
+ }
+
+ /**
+ * xe_mmio_read64_2x32() - Read a 64-bit register as two 32-bit reads
+- * @gt: MMIO target GT
++ * @mmio: MMIO target
+ * @reg: register to read value from
+ *
+ * Although Intel GPUs have some 64-bit registers, the hardware officially
+@@ -316,21 +311,21 @@ bool xe_mmio_in_range(const struct xe_gt *gt,
+ *
+ * Returns the value of the 64-bit register.
+ */
+-u64 xe_mmio_read64_2x32(struct xe_gt *gt, struct xe_reg reg)
++u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg)
+ {
+ struct xe_reg reg_udw = { .addr = reg.addr + 0x4 };
+ u32 ldw, udw, oldudw, retries;
+
+- reg.addr = xe_mmio_adjusted_addr(gt, reg.addr);
+- reg_udw.addr = xe_mmio_adjusted_addr(gt, reg_udw.addr);
++ reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr);
++ reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr);
+
+ /* we shouldn't adjust just one register address */
+- xe_gt_assert(gt, reg_udw.addr == reg.addr + 0x4);
++ xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4);
+
+- oldudw = xe_mmio_read32(gt, reg_udw);
++ oldudw = xe_mmio_read32(mmio, reg_udw);
+ for (retries = 5; retries; --retries) {
+- ldw = xe_mmio_read32(gt, reg);
+- udw = xe_mmio_read32(gt, reg_udw);
++ ldw = xe_mmio_read32(mmio, reg);
++ udw = xe_mmio_read32(mmio, reg_udw);
+
+ if (udw == oldudw)
+ break;
+@@ -338,14 +333,14 @@ u64 xe_mmio_read64_2x32(struct xe_gt *gt, struct xe_reg reg)
+ oldudw = udw;
+ }
+
+- xe_gt_WARN(gt, retries == 0,
+- "64-bit read of %#x did not stabilize\n", reg.addr);
++ drm_WARN(&mmio->tile->xe->drm, retries == 0,
++ "64-bit read of %#x did not stabilize\n", reg.addr);
+
+ return (u64)udw << 32 | ldw;
+ }
+
+-static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us,
+- u32 *out_val, bool atomic, bool expect_match)
++static int ____xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us,
++ u32 *out_val, bool atomic, bool expect_match)
+ {
+ ktime_t cur = ktime_get_raw();
+ const ktime_t end = ktime_add_us(cur, timeout_us);
+@@ -355,7 +350,7 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v
+ bool check;
+
+ for (;;) {
+- read = xe_mmio_read32(gt, reg);
++ read = xe_mmio_read32(mmio, reg);
+
+ check = (read & mask) == val;
+ if (!expect_match)
+@@ -381,7 +376,7 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v
+ }
+
+ if (ret != 0) {
+- read = xe_mmio_read32(gt, reg);
++ read = xe_mmio_read32(mmio, reg);
+
+ check = (read & mask) == val;
+ if (!expect_match)
+@@ -399,7 +394,7 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v
+
+ /**
+ * xe_mmio_wait32() - Wait for a register to match the desired masked value
+- * @gt: MMIO target GT
++ * @mmio: MMIO target
+ * @reg: register to read value from
+ * @mask: mask to be applied to the value read from the register
+ * @val: desired value after applying the mask
+@@ -416,15 +411,15 @@ static int __xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 v
+ * @timeout_us for different reasons, specially in non-atomic contexts. Thus,
+ * it is possible that this function succeeds even after @timeout_us has passed.
+ */
+-int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us,
+- u32 *out_val, bool atomic)
++int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us,
++ u32 *out_val, bool atomic)
+ {
+- return __xe_mmio_wait32(gt, reg, mask, val, timeout_us, out_val, atomic, true);
++ return ____xe_mmio_wait32(mmio, reg, mask, val, timeout_us, out_val, atomic, true);
+ }
+
+ /**
+ * xe_mmio_wait32_not() - Wait for a register to return anything other than the given masked value
+- * @gt: MMIO target GT
++ * @mmio: MMIO target
+ * @reg: register to read value from
+ * @mask: mask to be applied to the value read from the register
+ * @val: value not to be matched after applying the mask
+@@ -435,8 +430,8 @@ int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 t
+ * This function works exactly like xe_mmio_wait32() with the exception that
+ * @val is expected not to be matched.
+ */
+-int xe_mmio_wait32_not(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us,
+- u32 *out_val, bool atomic)
++int __xe_mmio_wait32_not(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us,
++ u32 *out_val, bool atomic)
+ {
+- return __xe_mmio_wait32(gt, reg, mask, val, timeout_us, out_val, atomic, false);
++ return ____xe_mmio_wait32(mmio, reg, mask, val, timeout_us, out_val, atomic, false);
+ }
+diff --git a/drivers/gpu/drm/xe/xe_mmio.h b/drivers/gpu/drm/xe/xe_mmio.h
+index 26551410ecc87..ac6846447c52a 100644
+--- a/drivers/gpu/drm/xe/xe_mmio.h
++++ b/drivers/gpu/drm/xe/xe_mmio.h
+@@ -14,25 +14,67 @@ struct xe_reg;
+ int xe_mmio_init(struct xe_device *xe);
+ int xe_mmio_probe_tiles(struct xe_device *xe);
+
+-u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg);
+-u16 xe_mmio_read16(struct xe_gt *gt, struct xe_reg reg);
+-void xe_mmio_write32(struct xe_gt *gt, struct xe_reg reg, u32 val);
+-u32 xe_mmio_read32(struct xe_gt *gt, struct xe_reg reg);
+-u32 xe_mmio_rmw32(struct xe_gt *gt, struct xe_reg reg, u32 clr, u32 set);
+-int xe_mmio_write32_and_verify(struct xe_gt *gt, struct xe_reg reg, u32 val, u32 mask, u32 eval);
+-bool xe_mmio_in_range(const struct xe_gt *gt, const struct xe_mmio_range *range, struct xe_reg reg);
+-
+-u64 xe_mmio_read64_2x32(struct xe_gt *gt, struct xe_reg reg);
+-int xe_mmio_wait32(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us,
+- u32 *out_val, bool atomic);
+-int xe_mmio_wait32_not(struct xe_gt *gt, struct xe_reg reg, u32 mask, u32 val, u32 timeout_us,
+- u32 *out_val, bool atomic);
+-
+-static inline u32 xe_mmio_adjusted_addr(const struct xe_gt *gt, u32 addr)
++/*
++ * Temporary transition helper for xe_gt -> xe_mmio conversion. Allows
++ * continued usage of xe_gt as a parameter to MMIO operations which now
++ * take an xe_mmio structure instead. Will be removed once the driver-wide
++ * conversion is complete.
++ */
++#define __to_xe_mmio(ptr) \
++ _Generic(ptr, \
++ const struct xe_gt *: (&((const struct xe_gt *)(ptr))->mmio), \
++ struct xe_gt *: (&((struct xe_gt *)(ptr))->mmio), \
++ const struct xe_mmio *: (ptr), \
++ struct xe_mmio *: (ptr))
++
++u8 __xe_mmio_read8(struct xe_mmio *mmio, struct xe_reg reg);
++#define xe_mmio_read8(p, reg) __xe_mmio_read8(__to_xe_mmio(p), reg)
++
++u16 __xe_mmio_read16(struct xe_mmio *mmio, struct xe_reg reg);
++#define xe_mmio_read16(p, reg) __xe_mmio_read16(__to_xe_mmio(p), reg)
++
++void __xe_mmio_write32(struct xe_mmio *mmio, struct xe_reg reg, u32 val);
++#define xe_mmio_write32(p, reg, val) __xe_mmio_write32(__to_xe_mmio(p), reg, val)
++
++u32 __xe_mmio_read32(struct xe_mmio *mmio, struct xe_reg reg);
++#define xe_mmio_read32(p, reg) __xe_mmio_read32(__to_xe_mmio(p), reg)
++
++u32 __xe_mmio_rmw32(struct xe_mmio *mmio, struct xe_reg reg, u32 clr, u32 set);
++#define xe_mmio_rmw32(p, reg, clr, set) __xe_mmio_rmw32(__to_xe_mmio(p), reg, clr, set)
++
++int __xe_mmio_write32_and_verify(struct xe_mmio *mmio, struct xe_reg reg,
++ u32 val, u32 mask, u32 eval);
++#define xe_mmio_write32_and_verify(p, reg, val, mask, eval) \
++ __xe_mmio_write32_and_verify(__to_xe_mmio(p), reg, val, mask, eval)
++
++bool __xe_mmio_in_range(const struct xe_mmio *mmio,
++ const struct xe_mmio_range *range, struct xe_reg reg);
++#define xe_mmio_in_range(p, range, reg) __xe_mmio_in_range(__to_xe_mmio(p), range, reg)
++
++u64 __xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg);
++#define xe_mmio_read64_2x32(p, reg) __xe_mmio_read64_2x32(__to_xe_mmio(p), reg)
++
++int __xe_mmio_wait32(struct xe_mmio *mmio, struct xe_reg reg, u32 mask, u32 val,
++ u32 timeout_us, u32 *out_val, bool atomic);
++#define xe_mmio_wait32(p, reg, mask, val, timeout_us, out_val, atomic) \
++ __xe_mmio_wait32(__to_xe_mmio(p), reg, mask, val, timeout_us, out_val, atomic)
++
++int __xe_mmio_wait32_not(struct xe_mmio *mmio, struct xe_reg reg, u32 mask,
++ u32 val, u32 timeout_us, u32 *out_val, bool atomic);
++#define xe_mmio_wait32_not(p, reg, mask, val, timeout_us, out_val, atomic) \
++ __xe_mmio_wait32_not(__to_xe_mmio(p), reg, mask, val, timeout_us, out_val, atomic)
++
++static inline u32 __xe_mmio_adjusted_addr(const struct xe_mmio *mmio, u32 addr)
+ {
+- if (addr < gt->mmio.adj_limit)
+- addr += gt->mmio.adj_offset;
++ if (addr < mmio->adj_limit)
++ addr += mmio->adj_offset;
+ return addr;
+ }
++#define xe_mmio_adjusted_addr(p, addr) __xe_mmio_adjusted_addr(__to_xe_mmio(p), addr)
++
++static inline struct xe_mmio *xe_root_tile_mmio(struct xe_device *xe)
++{
++ return &xe->tiles[0].mmio;
++}
+
+ #endif
+diff --git a/drivers/gpu/drm/xe/xe_trace.h b/drivers/gpu/drm/xe/xe_trace.h
+index 8573d7a87d840..91130ad8999cd 100644
+--- a/drivers/gpu/drm/xe/xe_trace.h
++++ b/drivers/gpu/drm/xe/xe_trace.h
+@@ -21,6 +21,7 @@
+ #include "xe_vm.h"
+
+ #define __dev_name_xe(xe) dev_name((xe)->drm.dev)
++#define __dev_name_tile(tile) __dev_name_xe(tile_to_xe((tile)))
+ #define __dev_name_gt(gt) __dev_name_xe(gt_to_xe((gt)))
+ #define __dev_name_eq(q) __dev_name_gt((q)->gt)
+
+@@ -342,12 +343,12 @@ DEFINE_EVENT(xe_hw_fence, xe_hw_fence_try_signal,
+ );
+
+ TRACE_EVENT(xe_reg_rw,
+- TP_PROTO(struct xe_gt *gt, bool write, u32 reg, u64 val, int len),
++ TP_PROTO(struct xe_mmio *mmio, bool write, u32 reg, u64 val, int len),
+
+- TP_ARGS(gt, write, reg, val, len),
++ TP_ARGS(mmio, write, reg, val, len),
+
+ TP_STRUCT__entry(
+- __string(dev, __dev_name_gt(gt))
++ __string(dev, __dev_name_tile(mmio->tile))
+ __field(u64, val)
+ __field(u32, reg)
+ __field(u16, write)
+--
+2.51.0
+
--- /dev/null
+From ac1a34b188986528c1a427281dd36813bede4f05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Sep 2024 16:47:26 -0700
+Subject: drm/xe: Switch mmio_ext to use 'struct xe_mmio'
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit 960a83799f5bb8634755f0593c591c53ff4acee8 ]
+
+The mmio_ext stuff is completely unused right now, but it isn't
+providing any functionality that couldn't be treated as a regular mmio
+space.
+
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20240910234719.3335472-51-matthew.d.roper@intel.com
+Stable-dep-of: 4a9b4e1fa52a ("drm/xe/mmio: Avoid double-adjust in 64-bit reads")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_device_types.h | 8 +-------
+ drivers/gpu/drm/xe/xe_mmio.c | 2 +-
+ 2 files changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
+index 2291ac1fa96e1..56630dabb85f7 100644
+--- a/drivers/gpu/drm/xe/xe_device_types.h
++++ b/drivers/gpu/drm/xe/xe_device_types.h
+@@ -182,13 +182,7 @@ struct xe_tile {
+ *
+ * Each tile has its own additional 256MB (28-bit) MMIO-extension space.
+ */
+- struct {
+- /** @mmio_ext.size: size of tile's additional MMIO-extension space */
+- size_t size;
+-
+- /** @mmio_ext.regs: pointer to tile's additional MMIO-extension space */
+- void __iomem *regs;
+- } mmio_ext;
++ struct xe_mmio mmio_ext;
+
+ /** @mem: memory management info for tile */
+ struct {
+diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
+index f210e7470eae5..2f72516e01327 100644
+--- a/drivers/gpu/drm/xe/xe_mmio.c
++++ b/drivers/gpu/drm/xe/xe_mmio.c
+@@ -132,7 +132,7 @@ static void mmio_extension_setup(struct xe_device *xe, size_t tile_mmio_size,
+
+ regs = xe->mmio.regs + tile_mmio_size * xe->info.tile_count;
+ for_each_tile(tile, xe, id) {
+- tile->mmio_ext.size = tile_mmio_ext_size;
++ tile->mmio_ext.regs_size = tile_mmio_ext_size;
+ tile->mmio_ext.regs = regs;
+ regs += tile_mmio_ext_size;
+ }
+--
+2.51.0
+
--- /dev/null
+From 60a7c28547a24ee2b8901ac871103eafd1889669 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Jun 2025 00:38:03 +0530
+Subject: drm/xe/xe2_hpg: Add set of workarounds
+
+From: Shekhar Chauhan <shekhar.chauhan@intel.com>
+
+[ Upstream commit a5d221924e13a22c83b682410dcf72422d1c68db ]
+
+Add set of workarounds for xe2_hpg.
+
+-v2: Fix xe2_hpg GMD version for some workarounds.
+-v3: Removed extra Workaround (Matt Roper)
+
+Signed-off-by: Shekhar Chauhan <shekhar.chauhan@intel.com>
+Signed-off-by: Dnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com>
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+Link: https://lore.kernel.org/r/20250605190804.1287289-3-dnyaneshwar.bhadane@intel.com
+Stable-dep-of: bc6387a2e0c1 ("drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_wa.c | 46 ++++++++++++++++++------------
+ drivers/gpu/drm/xe/xe_wa_oob.rules | 4 +--
+ 2 files changed, 29 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
+index aea6034a81079..e8414a56332e7 100644
+--- a/drivers/gpu/drm/xe/xe_wa.c
++++ b/drivers/gpu/drm/xe/xe_wa.c
+@@ -492,10 +492,6 @@ static const struct xe_rtp_entry_sr engine_was[] = {
+ XE_RTP_RULES(GRAPHICS_VERSION(2004), FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0_UDW, ENABLE_SMP_LD_RENDER_SURFACE_CONTROL))
+ },
+- { XE_RTP_NAME("16018737384"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2004), FUNC(xe_rtp_match_first_render_or_compute)),
+- XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS))
+- },
+ /*
+ * These two workarounds are the same, just applying to different
+ * engines. Although Wa_18032095049 (for the RCS) isn't required on
+@@ -522,31 +518,38 @@ static const struct xe_rtp_entry_sr engine_was[] = {
+ /* Xe2_HPG */
+
+ { XE_RTP_NAME("16018712365"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
++ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0_UDW, XE2_ALLOC_DPA_STARVE_FIX_DIS))
+ },
+ { XE_RTP_NAME("16018737384"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, XE_RTP_END_VERSION_UNDEFINED),
++ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS))
+ },
+ { XE_RTP_NAME("14019988906"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
++ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD))
+ },
+ { XE_RTP_NAME("14019877138"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
++ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT))
+ },
+ { XE_RTP_NAME("14020338487"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
++ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(ROW_CHICKEN3, XE2_EUPEND_CHK_FLUSH_DIS))
+ },
+ { XE_RTP_NAME("18032247524"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
++ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0, SEQUENTIAL_ACCESS_UPGRADE_DISABLE))
+ },
+ { XE_RTP_NAME("14018471104"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
++ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0_UDW, ENABLE_SMP_LD_RENDER_SURFACE_CONTROL))
+ },
+ /*
+@@ -555,7 +558,7 @@ static const struct xe_rtp_entry_sr engine_was[] = {
+ * apply this to all engines for simplicity.
+ */
+ { XE_RTP_NAME("16021639441"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002)),
+ XE_RTP_ACTIONS(SET(CSFE_CHICKEN1(0),
+ GHWSP_CSB_REPORT_DIS |
+ PPHWSP_CSB_AND_TIMESTAMP_REPORT_DIS,
+@@ -567,11 +570,12 @@ static const struct xe_rtp_entry_sr engine_was[] = {
+ XE_RTP_ACTIONS(SET(LSC_CHICKEN_BIT_0, WR_REQ_CHAINING_DIS))
+ },
+ { XE_RTP_NAME("14021402888"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(HALF_SLICE_CHICKEN7, CLEAR_OPTIMIZATION_DISABLE))
+ },
+- { XE_RTP_NAME("14021821874"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_first_render_or_compute)),
++ { XE_RTP_NAME("14021821874, 14022954250"),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
++ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, STK_ID_RESTRICT))
+ },
+
+@@ -730,7 +734,7 @@ static const struct xe_rtp_entry_sr lrc_was[] = {
+ XE_RTP_ACTIONS(SET(INSTPM(RENDER_RING_BASE), ENABLE_SEMAPHORE_POLL_BIT))
+ },
+ { XE_RTP_NAME("18033852989"),
+- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2004), ENGINE_CLASS(RENDER)),
++ XE_RTP_RULES(GRAPHICS_VERSION(2004), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN1, DISABLE_BOTTOM_CLIP_RECTANGLE_TEST))
+ },
+ { XE_RTP_NAME("14021567978"),
+@@ -763,7 +767,7 @@ static const struct xe_rtp_entry_sr lrc_was[] = {
+ XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_SF_ROUND_NEAREST_EVEN))
+ },
+ { XE_RTP_NAME("14019386621"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(VF_SCRATCHPAD, XE2_VFG_TED_CREDIT_INTERFACE_DISABLE))
+ },
+ { XE_RTP_NAME("14020756599"),
+@@ -780,13 +784,17 @@ static const struct xe_rtp_entry_sr lrc_was[] = {
+ DIS_AUTOSTRIP))
+ },
+ { XE_RTP_NAME("15016589081"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(CHICKEN_RASTER_1, DIS_CLIP_NEGATIVE_BOUNDING_BOX))
+ },
+ { XE_RTP_NAME("22021007897"),
+- XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN4, SBE_PUSH_CONSTANT_BEHIND_FIX_ENABLE))
+ },
++ { XE_RTP_NAME("18033852989"),
++ XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
++ XE_RTP_ACTIONS(SET(COMMON_SLICE_CHICKEN1, DISABLE_BOTTOM_CLIP_RECTANGLE_TEST))
++ },
+
+ /* Xe3_LPG */
+ { XE_RTP_NAME("14021490052"),
+diff --git a/drivers/gpu/drm/xe/xe_wa_oob.rules b/drivers/gpu/drm/xe/xe_wa_oob.rules
+index e726fcb307905..97d14b2119ecf 100644
+--- a/drivers/gpu/drm/xe/xe_wa_oob.rules
++++ b/drivers/gpu/drm/xe/xe_wa_oob.rules
+@@ -28,10 +28,10 @@
+ GRAPHICS_VERSION(2004)
+ 13011645652 GRAPHICS_VERSION(2004)
+ GRAPHICS_VERSION(3001)
+-14022293748 GRAPHICS_VERSION(2001)
++14022293748 GRAPHICS_VERSION_RANGE(2001, 2002)
+ GRAPHICS_VERSION(2004)
+ GRAPHICS_VERSION_RANGE(3000, 3001)
+-22019794406 GRAPHICS_VERSION(2001)
++22019794406 GRAPHICS_VERSION_RANGE(2001, 2002)
+ GRAPHICS_VERSION(2004)
+ GRAPHICS_VERSION_RANGE(3000, 3001)
+ 22019338487 MEDIA_VERSION(2000)
+--
+2.51.0
+
--- /dev/null
+From 686f333a9d968b67e1ecd40354a69f02b722e3fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Feb 2026 14:05:09 -0800
+Subject: drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit bc6387a2e0c1562faa56ce2a98cef50cab809e08 ]
+
+The PSS_CHICKEN register has been part of the RCS engine's LRC since it
+was first introduced in Xe_LP. That means that any workarounds that
+adjust its value (such as Wa_14019988906 and Wa_14019877138) need to be
+implemented in the lrc_was[] table so that they become part of the
+default LRC from which all subsequent LRCs are copied. Although these
+workarounds were implemented correctly on most platforms, they were
+incorrectly placed on the engine_was[] table for Xe2_HPG.
+
+Move the workarounds to the proper lrc_was[] table and switch the
+'xe_rtp_match_first_render_or_compute' rule to specifically match the
+RCS since that's the engine whose LRC manages the register.
+
+Bspec: 65182
+Fixes: 7f3ee7d88058 ("drm/xe/xe2hpg: Add initial GT workarounds")
+Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com>
+Link: https://patch.msgid.link/20260205220508.51905-2-matthew.d.roper@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit e04c609eedf4d6748ac0bcada4de1275b034fed6)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_wa.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
+index e8414a56332e7..a2af1a44b0e08 100644
+--- a/drivers/gpu/drm/xe/xe_wa.c
++++ b/drivers/gpu/drm/xe/xe_wa.c
+@@ -527,16 +527,6 @@ static const struct xe_rtp_entry_sr engine_was[] = {
+ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS))
+ },
+- { XE_RTP_NAME("14019988906"),
+- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
+- FUNC(xe_rtp_match_first_render_or_compute)),
+- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD))
+- },
+- { XE_RTP_NAME("14019877138"),
+- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
+- FUNC(xe_rtp_match_first_render_or_compute)),
+- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT))
+- },
+ { XE_RTP_NAME("14020338487"),
+ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
+ FUNC(xe_rtp_match_first_render_or_compute)),
+@@ -774,6 +764,14 @@ static const struct xe_rtp_entry_sr lrc_was[] = {
+ XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(WM_CHICKEN3, HIZ_PLANE_COMPRESSION_DIS))
+ },
++ { XE_RTP_NAME("14019988906"),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)),
++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD))
++ },
++ { XE_RTP_NAME("14019877138"),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)),
++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT))
++ },
+ { XE_RTP_NAME("14021490052"),
+ XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(FF_MODE,
+--
+2.51.0
+
--- /dev/null
+From be91be9a5fe0fadfb98710636e5426ba45359686 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 10:49:56 +0000
+Subject: efi: Fix reservation of unaccepted memory table
+
+From: Kiryl Shutsemau (Meta) <kas@kernel.org>
+
+[ Upstream commit 0862438c90487e79822d5647f854977d50381505 ]
+
+The reserve_unaccepted() function incorrectly calculates the size of the
+memblock reservation for the unaccepted memory table. It aligns the
+size of the table, but fails to account for cases where the table's
+starting physical address (efi.unaccepted) is not page-aligned.
+
+If the table starts at an offset within a page and its end crosses into
+a subsequent page that the aligned size does not cover, the end of the
+table will not be reserved. This can lead to the table being overwritten
+or inaccessible, causing a kernel panic in accept_memory().
+
+This issue was observed when starting Intel TDX VMs with specific memory
+sizes (e.g., > 64GB).
+
+Fix this by calculating the end address first (including the unaligned
+start) and then aligning it up, ensuring the entire range is covered
+by the reservation.
+
+Fixes: 8dbe33956d96 ("efi/unaccepted: Make sure unaccepted table is mapped")
+Reported-by: Moritz Sanft <ms@edgeless.systems>
+Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/efi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index acabc856fe8a5..0d1a65879a358 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -667,13 +667,13 @@ static __init int match_config_table(const efi_guid_t *guid,
+
+ static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted)
+ {
+- phys_addr_t start, size;
++ phys_addr_t start, end;
+
+ start = PAGE_ALIGN_DOWN(efi.unaccepted);
+- size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size);
++ end = PAGE_ALIGN(efi.unaccepted + sizeof(*unaccepted) + unaccepted->size);
+
+- memblock_add(start, size);
+- memblock_reserve(start, size);
++ memblock_add(start, end - start);
++ memblock_reserve(start, end - start);
+ }
+
+ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+--
+2.51.0
+
--- /dev/null
+From 255bcfc211ce8fbedc9391729d82e053364a5266 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jan 2026 16:50:24 +0000
+Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot
+
+From: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+
+[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ]
+
+In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the
+entry size ('esize') is retrieved from the log record without adequate
+bounds checking.
+
+Specifically, the code calculates the end of the entry ('e2') using:
+ e2 = Add2Ptr(e1, esize);
+
+It then calculates the size for memmove using 'PtrOffset(e2, ...)',
+which subtracts the end pointer from the buffer limit. If 'esize' is
+maliciously large, 'e2' exceeds the used buffer size. This results in
+a negative offset which, when cast to size_t for memmove, interprets
+as a massive unsigned integer, leading to a heap buffer overflow.
+
+This commit adds a check to ensure that the entry size ('esize') strictly
+fits within the remaining used space of the index header before performing
+memory operations.
+
+Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
+Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/fslog.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
+index d0d530f4e2b95..5afe00972924c 100644
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -3431,6 +3431,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe,
+
+ e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off));
+ esize = le16_to_cpu(e1->size);
++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize)
++ goto dirty_vol;
++
+ e2 = Add2Ptr(e1, esize);
+
+ memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used)));
+--
+2.51.0
+
--- /dev/null
+From cbc98ac10b0277652fb472b50ed7f433327e30d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 23:02:51 +0100
+Subject: fs/ntfs3: Initialize new folios before use
+
+From: Bartlomiej Kubik <kubik.bartlomiej@gmail.com>
+
+[ Upstream commit f223ebffa185cc8da934333c5a31ff2d4f992dc9 ]
+
+KMSAN reports an uninitialized value in longest_match_std(), invoked
+from ntfs_compress_write(). When new folios are allocated without being
+marked uptodate and ni_read_frame() is skipped because the caller expects
+the frame to be completely overwritten, some reserved folios may remain
+only partially filled, leaving the rest memory uninitialized.
+
+Fixes: 584f60ba22f7 ("ntfs3: Convert ntfs_get_frame_pages() to use a folio")
+Tested-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com
+Reported-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=08d8956768c96a2c52cf
+
+Signed-off-by: Bartlomiej Kubik <kubik.bartlomiej@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index f1122ac5be622..23a637cdb0810 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -964,7 +964,7 @@ static int ntfs_get_frame_pages(struct address_space *mapping, pgoff_t index,
+
+ folio = __filemap_get_folio(mapping, index,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
+- gfp_mask);
++ gfp_mask | __GFP_ZERO);
+ if (IS_ERR(folio)) {
+ while (npages--) {
+ folio = page_folio(pages[npages]);
+--
+2.51.0
+
--- /dev/null
+From 4471670577adc7f907688e5f3316bce9575d7f07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Dec 2025 11:53:25 +0800
+Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the
+ same
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ]
+
+When processing valid within the range [valid : pos), if valid cannot
+be retrieved correctly, for example, if the retrieved valid value is
+always the same, this can trigger a potential infinite loop, similar
+to the hung problem reported by syzbot [1].
+
+Adding a check for the valid value within the loop body, and terminating
+the loop and returning -EINVAL if the value is the same as the current
+value, can prevent this.
+
+[1]
+INFO: task syz.4.21:6056 blocked for more than 143 seconds.
+Call Trace:
+ rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244
+ inode_lock include/linux/fs.h:1027 [inline]
+ ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284
+
+Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
+Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/file.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index 23a637cdb0810..3f144a049d710 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -1045,8 +1045,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from)
+ goto out;
+
+ if (lcn == SPARSE_LCN) {
+- ni->i_valid = valid =
+- frame_vbo + ((u64)clen << sbi->cluster_bits);
++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits);
++ if (ni->i_valid == valid) {
++ err = -EINVAL;
++ goto out;
++ }
++ ni->i_valid = valid;
+ continue;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From b90ca27cb0396eecd61d26411e0b8582d27ff4f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:28 +0000
+Subject: icmp: prevent possible overflow in icmp_global_allow()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 034bbd806298e9ba4197dd1587b0348ee30996ea ]
+
+Following expression can overflow
+if sysctl_icmp_msgs_per_sec is big enough.
+
+sysctl_icmp_msgs_per_sec * delta / HZ;
+
+Fixes: 4cdf507d5452 ("icmp: add a global rate limitation")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216142832.3834174-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/icmp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index ee24728fc60bf..8ab51b51cc9b2 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -247,7 +247,8 @@ bool icmp_global_allow(struct net *net)
+ if (delta < HZ / 50)
+ return false;
+
+- incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ;
++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec);
++ incr = div_u64((u64)incr * delta, HZ);
+ if (!incr)
+ return false;
+
+--
+2.51.0
+
--- /dev/null
+From 4b724a8256691d363dec1ebe2d2d5bfbf6d3b3f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:29 +0000
+Subject: inet: move icmp_global_{credit,stamp} to a separate cache line
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87b08913a9ae82082e276d237ece08fc8ee24380 ]
+
+icmp_global_credit was meant to be changed ~1000 times per second,
+but if an admin sets net.ipv4.icmp_msgs_per_sec to a very high value,
+icmp_global_credit changes can inflict false sharing to surrounding
+fields that are read mostly.
+
+Move icmp_global_credit and icmp_global_stamp to a separate
+cacheline aligned group.
+
+Fixes: b056b4cd9178 ("icmp: move icmp_global.credit and icmp_global.stamp to per netns storage")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216142832.3834174-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netns/ipv4.h | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 276f622f35168..a15e9366175ec 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -80,6 +80,12 @@ struct netns_ipv4 {
+ int sysctl_tcp_rmem[3];
+ __cacheline_group_end(netns_ipv4_read_rx);
+
++ /* ICMP rate limiter hot cache line. */
++ __cacheline_group_begin_aligned(icmp);
++ atomic_t icmp_global_credit;
++ u32 icmp_global_stamp;
++ __cacheline_group_end_aligned(icmp);
++
+ struct inet_timewait_death_row tcp_death_row;
+ struct udp_table *udp_table;
+
+@@ -124,8 +130,7 @@ struct netns_ipv4 {
+ int sysctl_icmp_ratemask;
+ int sysctl_icmp_msgs_per_sec;
+ int sysctl_icmp_msgs_burst;
+- atomic_t icmp_global_credit;
+- u32 icmp_global_stamp;
++
+ u32 ip_rt_min_pmtu;
+ int ip_rt_mtu_expires;
+ int ip_rt_min_advmss;
+--
+2.51.0
+
--- /dev/null
+From d86a349ae4f2bc297babe4e9ebea98f60c6f8e86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:22:02 +0000
+Subject: ipv6: fix a race in ip6_sock_set_v6only()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ]
+
+It is unlikely that this function will be ever called
+with isk->inet_num being not zero.
+
+Perform the check on isk->inet_num inside the locked section
+for complete safety.
+
+Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ipv6.h | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index 6d52b5584d2fb..2651bd76e5b75 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -1275,12 +1275,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
+
+ static inline int ip6_sock_set_v6only(struct sock *sk)
+ {
+- if (inet_sk(sk)->inet_num)
+- return -EINVAL;
++ int ret = 0;
++
+ lock_sock(sk);
+- sk->sk_ipv6only = true;
++ if (inet_sk(sk)->inet_num)
++ ret = -EINVAL;
++ else
++ sk->sk_ipv6only = true;
+ release_sock(sk);
+- return 0;
++ return ret;
+ }
+
+ static inline void ip6_sock_set_recverr(struct sock *sk)
+--
+2.51.0
+
--- /dev/null
+From 5d3b9b8035876d7c8864999ac54b972e51aeb4a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 17:50:21 +0000
+Subject: ipv6: Fix out-of-bound access in fib6_add_rt2node().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 8244f959e2c125c849e569f5b23ed49804cce695 ]
+
+syzbot reported out-of-bound read in fib6_add_rt2node(). [0]
+
+When IPv6 route is created with RTA_NH_ID, struct fib6_info
+does not have the trailing struct fib6_nh.
+
+The cited commit started to check !iter->fib6_nh->fib_nh_gw_family
+to ensure that rt6_qualify_for_ecmp() will return false for iter.
+
+If iter->nh is not NULL, rt6_qualify_for_ecmp() returns false anyway.
+
+Let's check iter->nh before reading iter->fib6_nh and avoid OOB read.
+
+[0]:
+BUG: KASAN: slab-out-of-bounds in fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142
+Read of size 1 at addr ffff8880384ba6de by task syz.0.18/5500
+
+CPU: 0 UID: 0 PID: 5500 Comm: syz.0.18 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xba/0x230 mm/kasan/report.c:482
+ kasan_report+0x117/0x150 mm/kasan/report.c:595
+ fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142
+ fib6_add_rt2node_nh net/ipv6/ip6_fib.c:1363 [inline]
+ fib6_add+0x910/0x18c0 net/ipv6/ip6_fib.c:1531
+ __ip6_ins_rt net/ipv6/route.c:1351 [inline]
+ ip6_route_add+0xde/0x1b0 net/ipv6/route.c:3957
+ inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660
+ rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f9316b9aeb9
+Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007ffd8809b678 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f9316e15fa0 RCX: 00007f9316b9aeb9
+RDX: 0000000000000000 RSI: 0000200000004380 RDI: 0000000000000003
+RBP: 00007f9316c08c1f R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 00007f9316e15fac R14: 00007f9316e15fa0 R15: 00007f9316e15fa0
+ </TASK>
+
+Allocated by task 5499:
+ kasan_save_stack mm/kasan/common.c:57 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263 [inline]
+ __do_kmalloc_node mm/slub.c:5657 [inline]
+ __kmalloc_noprof+0x40c/0x7e0 mm/slub.c:5669
+ kmalloc_noprof include/linux/slab.h:961 [inline]
+ kzalloc_noprof include/linux/slab.h:1094 [inline]
+ fib6_info_alloc+0x30/0xf0 net/ipv6/ip6_fib.c:155
+ ip6_route_info_create+0x142/0x860 net/ipv6/route.c:3820
+ ip6_route_add+0x49/0x1b0 net/ipv6/route.c:3949
+ inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660
+ rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: bbf4a17ad9ff ("ipv6: Fix ECMP sibling count mismatch when clearing RTF_ADDRCONF")
+Reported-by: syzbot+707d6a5da1ab9e0c6f9d@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/698cbfba.050a0220.2eeac1.009d.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Reviewed-by: Shigeru Yoshida <syoshida@redhat.com>
+Link: https://patch.msgid.link/20260211175133.3657034-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_fib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index d83430f4a0eff..01c953a39211a 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -1139,7 +1139,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
+ fib6_add_gc_list(iter);
+ }
+ if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) &&
+- !iter->fib6_nh->fib_nh_gw_family) {
++ (iter->nh || !iter->fib6_nh->fib_nh_gw_family)) {
+ iter->fib6_flags &= ~RTF_ADDRCONF;
+ iter->fib6_flags &= ~RTF_PREFIX_RT;
+ }
+--
+2.51.0
+
--- /dev/null
+From f4066fcb6ffb4acf2ae0c3d1b36fa8ce784eac35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Feb 2026 16:58:50 +0200
+Subject: ipvs: do not keep dest_dst if dev is going down
+
+From: Julian Anastasov <ja@ssi.bg>
+
+[ Upstream commit 8fde939b0206afc1d5846217a01a16b9bc8c7896 ]
+
+There is race between the netdev notifier ip_vs_dst_event()
+and the code that caches dst with dev that is going down.
+As the FIB can be notified for the closed device after our
+handler finishes, it is possible valid route to be returned
+and cached resuling in a leaked dev reference until the dest
+is not removed.
+
+To prevent new dest_dst to be attached to dest just after the
+handler dropped the old one, add a netif_running() check
+to make sure the notifier handler is not currently running
+for device that is closing.
+
+Fixes: 7a4f0761fce3 ("IPVS: init and cleanup restructuring")
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 46 ++++++++++++++++++++++++++-------
+ 1 file changed, 36 insertions(+), 10 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index fa2db17f6298b..8892f261451e9 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -295,6 +295,12 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs,
+ return true;
+ }
+
++/* rt has device that is down */
++static bool rt_dev_is_down(const struct net_device *dev)
++{
++ return dev && !netif_running(dev);
++}
++
+ /* Get route to destination or remote server */
+ static int
+ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+@@ -310,9 +316,11 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+
+ if (dest) {
+ dest_dst = __ip_vs_dst_check(dest);
+- if (likely(dest_dst))
++ if (likely(dest_dst)) {
+ rt = dst_rtable(dest_dst->dst_cache);
+- else {
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.ip;
++ } else {
+ dest_dst = ip_vs_dest_dst_alloc();
+ spin_lock_bh(&dest->dst_lock);
+ if (!dest_dst) {
+@@ -328,14 +336,22 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+ ip_vs_dest_dst_free(dest_dst);
+ goto err_unreach;
+ }
+- __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0);
++ /* It is forbidden to attach dest->dest_dst if
++ * device is going down.
++ */
++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst)))
++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0);
++ else
++ noref = 0;
+ spin_unlock_bh(&dest->dst_lock);
+ IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d\n",
+ &dest->addr.ip, &dest_dst->dst_saddr.ip,
+ rcuref_read(&rt->dst.__rcuref));
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.ip;
++ if (!noref)
++ ip_vs_dest_dst_free(dest_dst);
+ }
+- if (ret_saddr)
+- *ret_saddr = dest_dst->dst_saddr.ip;
+ } else {
+ noref = 0;
+
+@@ -472,9 +488,11 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+
+ if (dest) {
+ dest_dst = __ip_vs_dst_check(dest);
+- if (likely(dest_dst))
++ if (likely(dest_dst)) {
+ rt = dst_rt6_info(dest_dst->dst_cache);
+- else {
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.in6;
++ } else {
+ u32 cookie;
+
+ dest_dst = ip_vs_dest_dst_alloc();
+@@ -495,14 +513,22 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+ }
+ rt = dst_rt6_info(dst);
+ cookie = rt6_get_cookie(rt);
+- __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie);
++ /* It is forbidden to attach dest->dest_dst if
++ * device is going down.
++ */
++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst)))
++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie);
++ else
++ noref = 0;
+ spin_unlock_bh(&dest->dst_lock);
+ IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n",
+ &dest->addr.in6, &dest_dst->dst_saddr.in6,
+ rcuref_read(&rt->dst.__rcuref));
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.in6;
++ if (!noref)
++ ip_vs_dest_dst_free(dest_dst);
+ }
+- if (ret_saddr)
+- *ret_saddr = dest_dst->dst_saddr.in6;
+ } else {
+ noref = 0;
+ dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm,
+--
+2.51.0
+
--- /dev/null
+From b7a603cf51c5e4f6118e5f1e151febf2f98127a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 13:45:22 -0800
+Subject: kbuild: Add objtool to top-level clean target
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 68b4fe32d73789dea23e356f468de67c8367ef8f ]
+
+Objtool is an integral part of the build, make sure it gets cleaned by
+"make clean" and "make mrproper".
+
+Fixes: 442f04c34a1a ("objtool: Add tool to perform compile-time stack metadata validation")
+Reported-by: Jens Remus <jremus@linux.ibm.com>
+Closes: https://lore.kernel.org/15f2af3b-be33-46fc-b972-6b8e7e0aa52e@linux.ibm.com
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Tested-by: Jens Remus <jremus@linux.ibm.com>
+Link: https://patch.msgid.link/968faf2ed30fa8b3519f79f01a1ecfe7929553e5.1770759919.git.jpoimboe@kernel.org
+[nathan: use Closes: instead of Link: per checkpatch.pl]
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile | 11 ++++++++++-
+ tools/objtool/Makefile | 2 ++
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index 94c1c8c7f899f..4193928df50c8 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1370,6 +1370,15 @@ ifneq ($(wildcard $(resolve_btfids_O)),)
+ $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean
+ endif
+
++PHONY += objtool_clean
++
++objtool_O = $(abspath $(objtree))/tools/objtool
++
++objtool_clean:
++ifneq ($(wildcard $(objtool_O)),)
++ $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean
++endif
++
+ tools/: FORCE
+ $(Q)mkdir -p $(objtree)/tools
+ $(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/
+@@ -1527,7 +1536,7 @@ vmlinuxclean:
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean
+ $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean)
+
+-clean: archclean vmlinuxclean resolve_btfids_clean
++clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean
+
+ # mrproper - Delete all generated files, including .config
+ #
+diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
+index bf7f7f84ac625..02d1fccd495f4 100644
+--- a/tools/objtool/Makefile
++++ b/tools/objtool/Makefile
+@@ -7,6 +7,8 @@ srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+ srctree := $(patsubst %/,%,$(dir $(srctree)))
+ endif
+
++RM ?= rm -f
++
+ LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/
+ ifneq ($(OUTPUT),)
+ LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd
+--
+2.51.0
+
--- /dev/null
+From ed868f36e6c9d93623a543193eba2732a397e5d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:25:57 +0000
+Subject: macvlan: observe an RCU grace period in macvlan_common_newlink()
+ error path
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ]
+
+valis reported that a race condition still happens after my prior patch.
+
+macvlan_common_newlink() might have made @dev visible before
+detecting an error, and its caller will directly call free_netdev(dev).
+
+We must respect an RCU period, either in macvlan or the core networking
+stack.
+
+After adding a temporary mdelay(1000) in macvlan_forward_source_one()
+to open the race window, valis repro was:
+
+ip link add p1 type veth peer p2
+ip link set address 00:00:00:00:00:20 dev p1
+ip link set up dev p1
+ip link set up dev p2
+ip link add mv0 link p2 type macvlan mode source
+
+(ip link add invalid% link p2 type macvlan mode source macaddr add
+00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4
+PING 1.2.3.4 (1.2.3.4): 56 data bytes
+RTNETLINK answers: Invalid argument
+
+BUG: KASAN: slab-use-after-free in macvlan_forward_source
+(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+Read of size 8 at addr ffff888016bb89c0 by task e/175
+
+CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
+Call Trace:
+<IRQ>
+dump_stack_lvl (lib/dump_stack.c:123)
+print_report (mm/kasan/report.c:379 mm/kasan/report.c:482)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+kasan_report (mm/kasan/report.c:597)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+? tasklet_init (kernel/softirq.c:983)
+macvlan_handle_frame (drivers/net/macvlan.c:501)
+
+Allocated by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+__kasan_kmalloc (mm/kasan/common.c:419)
+__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657
+mm/slub.c:7140)
+alloc_netdev_mqs (net/core/dev.c:12012)
+rtnl_create_link (net/core/rtnetlink.c:3648)
+rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Freed by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+kasan_save_free_info (mm/kasan/generic.c:587)
+__kasan_slab_free (mm/kasan/common.c:287)
+kfree (mm/slub.c:6674 mm/slub.c:6882)
+rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: valis <sec@valis.email>
+Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macvlan.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index aaf7d755fc8a1..3770bc84a9445 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1568,6 +1568,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
+ if (create)
+ macvlan_port_destroy(port->dev);
+ }
++ /* @dev might have been made visible before an error was detected.
++ * Make sure to observe an RCU grace period before our caller
++ * (rtnl_newlink()) frees it.
++ */
++ synchronize_net();
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(macvlan_common_newlink);
+--
+2.51.0
+
--- /dev/null
+From aad79e3275af722bcaa51a4ef7bba63109432ee2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 09:00:30 +0200
+Subject: net: bridge: mcast: always update mdb_n_entries for vlan contexts
+
+From: Nikolay Aleksandrov <nikolay@nvidia.com>
+
+[ Upstream commit 8b769e311a86bb9d15c5658ad283b86fc8f080a2 ]
+
+syzbot triggered a warning[1] about the number of mdb entries in a context.
+It turned out that there are multiple ways to trigger that warning today
+(some got added during the years), the root cause of the problem is that
+the increase is done conditionally, and over the years these different
+conditions increased so there were new ways to trigger the warning, that is
+to do a decrease which wasn't paired with a previous increase.
+
+For example one way to trigger it is with flush:
+ $ ip l add br0 up type bridge vlan_filtering 1 mcast_snooping 1
+ $ ip l add dumdum up master br0 type dummy
+ $ bridge mdb add dev br0 port dumdum grp 239.0.0.1 permanent vid 1
+ $ ip link set dev br0 down
+ $ ip link set dev br0 type bridge mcast_vlan_snooping 1
+ ^^^^ this will enable snooping, but will not update mdb_n_entries
+ because in __br_multicast_enable_port_ctx() we check !netif_running
+ $ bridge mdb flush dev br0
+ ^^^ this will trigger the warning because it will delete the pg which
+ we added above, which will try to decrease mdb_n_entries
+
+Fix the problem by removing the conditional increase and always keep the
+count up-to-date while the vlan exists. In order to do that we have to
+first initialize it on port-vlan context creation, and then always increase
+or decrease the value regardless of mcast options. To keep the current
+behaviour we have to enforce the mdb limit only if the context is port's or
+if the port-vlan's mcast snooping is enabled.
+
+[1]
+ ------------[ cut here ]------------
+ n == 0
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline], CPU#0: syz.4.4607/22043
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline], CPU#0: syz.4.4607/22043
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825, CPU#0: syz.4.4607/22043
+ Modules linked in:
+ CPU: 0 UID: 0 PID: 22043 Comm: syz.4.4607 Not tainted syzkaller #0 PREEMPT(full)
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026
+ RIP: 0010:br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline]
+ RIP: 0010:br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline]
+ RIP: 0010:br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825
+ Code: 41 5f 5d e9 04 7a 48 f7 e8 3f 73 5c f7 90 0f 0b 90 e9 cf fd ff ff e8 31 73 5c f7 90 0f 0b 90 e9 16 fd ff ff e8 23 73 5c f7 90 <0f> 0b 90 e9 60 fd ff ff e8 15 73 5c f7 eb 05 e8 0e 73 5c f7 48 8b
+ RSP: 0018:ffffc9000c207220 EFLAGS: 00010293
+ RAX: ffffffff8a68042d RBX: ffff88807c6f1800 RCX: ffff888066e90000
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+ RBP: 0000000000000000 R08: ffff888066e90000 R09: 000000000000000c
+ R10: 000000000000000c R11: 0000000000000000 R12: ffff8880303ef800
+ R13: dffffc0000000000 R14: ffff888050eb11c4 R15: 1ffff1100a1d6238
+ FS: 00007fa45921b6c0(0000) GS:ffff8881256f5000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007fa4591f9ff8 CR3: 0000000081df2000 CR4: 00000000003526f0
+ Call Trace:
+ <TASK>
+ br_mdb_flush_pgs net/bridge/br_mdb.c:1525 [inline]
+ br_mdb_flush net/bridge/br_mdb.c:1544 [inline]
+ br_mdb_del_bulk+0x5e2/0xb20 net/bridge/br_mdb.c:1561
+ rtnl_mdb_del+0x48a/0x640 net/core/rtnetlink.c:-1
+ rtnetlink_rcv_msg+0x77e/0xbe0 net/core/rtnetlink.c:6967
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ RIP: 0033:0x7fa45839aeb9
+ Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48
+ RSP: 002b:00007fa45921b028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+ RAX: ffffffffffffffda RBX: 00007fa458615fa0 RCX: 00007fa45839aeb9
+ RDX: 0000000000000000 RSI: 00002000000000c0 RDI: 0000000000000004
+ RBP: 00007fa458408c1f R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+ R13: 00007fa458616038 R14: 00007fa458615fa0 R15: 00007fff0b59fae8
+ </TASK>
+
+Fixes: b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port")
+Reported-by: syzbot+d5d1b7343531d17bd3c5@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/aYrWbRp83MQR1ife@debil/T/#t
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Link: https://patch.msgid.link/20260213070031.1400003-2-nikolay@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_multicast.c | 45 ++++++++++++++++-----------------------
+ 1 file changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index 4227894e35792..9bd2914006df7 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -244,14 +244,11 @@ br_multicast_port_vid_to_port_ctx(struct net_bridge_port *port, u16 vid)
+
+ lockdep_assert_held_once(&port->br->multicast_lock);
+
+- if (!br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED))
+- return NULL;
+-
+ /* Take RCU to access the vlan. */
+ rcu_read_lock();
+
+ vlan = br_vlan_find(nbp_vlan_group_rcu(port), vid);
+- if (vlan && !br_multicast_port_ctx_vlan_disabled(&vlan->port_mcast_ctx))
++ if (vlan)
+ pmctx = &vlan->port_mcast_ctx;
+
+ rcu_read_unlock();
+@@ -701,7 +698,10 @@ br_multicast_port_ngroups_inc_one(struct net_bridge_mcast_port *pmctx,
+ u32 max = READ_ONCE(pmctx->mdb_max_entries);
+ u32 n = READ_ONCE(pmctx->mdb_n_entries);
+
+- if (max && n >= max) {
++ /* enforce the max limit when it's a port pmctx or a port-vlan pmctx
++ * with snooping enabled
++ */
++ if (!br_multicast_port_ctx_vlan_disabled(pmctx) && max && n >= max) {
+ NL_SET_ERR_MSG_FMT_MOD(extack, "%s is already in %u groups, and mcast_max_groups=%u",
+ what, n, max);
+ return -E2BIG;
+@@ -736,9 +736,7 @@ static int br_multicast_port_ngroups_inc(struct net_bridge_port *port,
+ return err;
+ }
+
+- /* Only count on the VLAN context if VID is given, and if snooping on
+- * that VLAN is enabled.
+- */
++ /* Only count on the VLAN context if VID is given */
+ if (!group->vid)
+ return 0;
+
+@@ -2010,6 +2008,18 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port,
+ timer_setup(&pmctx->ip6_own_query.timer,
+ br_ip6_multicast_port_query_expired, 0);
+ #endif
++ /* initialize mdb_n_entries if a new port vlan is being created */
++ if (vlan) {
++ struct net_bridge_port_group *pg;
++ u32 n = 0;
++
++ spin_lock_bh(&port->br->multicast_lock);
++ hlist_for_each_entry(pg, &port->mglist, mglist)
++ if (pg->key.addr.vid == vlan->vid)
++ n++;
++ WRITE_ONCE(pmctx->mdb_n_entries, n);
++ spin_unlock_bh(&port->br->multicast_lock);
++ }
+ }
+
+ void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx)
+@@ -2093,25 +2103,6 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
+ br_ip4_multicast_add_router(brmctx, pmctx);
+ br_ip6_multicast_add_router(brmctx, pmctx);
+ }
+-
+- if (br_multicast_port_ctx_is_vlan(pmctx)) {
+- struct net_bridge_port_group *pg;
+- u32 n = 0;
+-
+- /* The mcast_n_groups counter might be wrong. First,
+- * BR_VLFLAG_MCAST_ENABLED is toggled before temporary entries
+- * are flushed, thus mcast_n_groups after the toggle does not
+- * reflect the true values. And second, permanent entries added
+- * while BR_VLFLAG_MCAST_ENABLED was disabled, are not reflected
+- * either. Thus we have to refresh the counter.
+- */
+-
+- hlist_for_each_entry(pg, &pmctx->port->mglist, mglist) {
+- if (pg->key.addr.vid == pmctx->vlan->vid)
+- n++;
+- }
+- WRITE_ONCE(pmctx->mdb_n_entries, n);
+- }
+ }
+
+ static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
+--
+2.51.0
+
--- /dev/null
+From cf8c6198f53b6dc856bd4f7eeb49251a31abf202 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:28:59 +0200
+Subject: net/mlx5: Fix multiport device check over light SFs
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 47bf2e813817159f4d195be83a9b5a640ee6baec ]
+
+Driver is using num_vhca_ports capability to distinguish between
+multiport master device and multiport slave device. num_vhca_ports is a
+capability the driver sets according to the MAX num_vhca_ports
+capability reported by FW. On the other hand, light SFs doesn't set the
+above capbility.
+
+This leads to wrong results whenever light SFs is checking whether he is
+a multiport master or slave.
+
+Therefore, use the MAX capability to distinguish between master and
+slave devices.
+
+Fixes: e71383fb9cd1 ("net/mlx5: Light probe local SFs")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-2-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mlx5/driver.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index 9a8eb644f6707..2e3324578f2ea 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -1297,12 +1297,12 @@ static inline bool mlx5_rl_is_supported(struct mlx5_core_dev *dev)
+ static inline int mlx5_core_is_mp_slave(struct mlx5_core_dev *dev)
+ {
+ return MLX5_CAP_GEN(dev, affiliate_nic_vport_criteria) &&
+- MLX5_CAP_GEN(dev, num_vhca_ports) <= 1;
++ MLX5_CAP_GEN_MAX(dev, num_vhca_ports) <= 1;
+ }
+
+ static inline int mlx5_core_is_mp_master(struct mlx5_core_dev *dev)
+ {
+- return MLX5_CAP_GEN(dev, num_vhca_ports) > 1;
++ return MLX5_CAP_GEN_MAX(dev, num_vhca_ports) > 1;
+ }
+
+ static inline int mlx5_core_mp_enabled(struct mlx5_core_dev *dev)
+--
+2.51.0
+
--- /dev/null
+From c217aa17e2756286bf7d6f9841d90c3cf699d360 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:29:04 +0200
+Subject: net/mlx5e: Use unsigned for mlx5e_get_max_num_channels
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 57a94d4b22b0c6cc5d601e6b6238d78fb923d991 ]
+
+The max number of channels is always an unsigned int, use the correct
+type to fix compilation errors done with strict type checking, e.g.:
+
+error: call to ‘__compiletime_assert_1110’ declared with attribute
+ error: min(mlx5e_get_devlink_param_num_doorbells(mdev),
+ mlx5e_get_max_num_channels(mdev)) signedness error
+
+Fixes: 74a8dadac17e ("net/mlx5e: Preparations for supporting larger number of channels")
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-7-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index 8245a149cdf85..0e18906168313 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -176,7 +176,8 @@ static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size)
+ }
+
+ /* Use this function to get max num channels (rxqs/txqs) only to create netdev */
+-static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
++static inline unsigned int
++mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
+ {
+ return is_kdump_kernel() ?
+ MLX5E_MIN_NUM_CHANNELS :
+--
+2.51.0
+
--- /dev/null
+From e25102a478b882c2c45f9b86927f4b167d26232a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:02 +0000
+Subject: net: mscc: ocelot: add missing lock protection in
+ ocelot_port_xmit_inj()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 026f6513c5880c2c89e38ad66bbec2868f978605 ]
+
+ocelot_port_xmit_inj() calls ocelot_can_inject() and
+ocelot_port_inject_frame() without holding the injection group lock.
+Both functions contain lockdep_assert_held() for the injection lock,
+and the correct caller felix_port_deferred_xmit() properly acquires
+the lock using ocelot_lock_inj_grp() before calling these functions.
+
+Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register
+injection path to fix the missing lock protection. The FDMA path is not
+affected as it uses its own locking mechanism.
+
+Fixes: c5e12ac3beb0 ("net: mscc: ocelot: serialize access to the injection/extraction groups")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-4-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index df863657c87de..7df78004dba91 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb,
+ int port = priv->port.index;
+ u32 rew_op = 0;
+
+- if (!ocelot_can_inject(ocelot, 0))
++ ocelot_lock_inj_grp(ocelot, 0);
++
++ if (!ocelot_can_inject(ocelot, 0)) {
++ ocelot_unlock_inj_grp(ocelot, 0);
+ return NETDEV_TX_BUSY;
++ }
+
+- if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) {
++ ocelot_unlock_inj_grp(ocelot, 0);
+ return NETDEV_TX_OK;
++ }
+
+ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
++ ocelot_unlock_inj_grp(ocelot, 0);
++
+ consume_skb(skb);
+
+ return NETDEV_TX_OK;
+--
+2.51.0
+
--- /dev/null
+From 8995c18bcce02c86fc5f6b81d74a264e331a20d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:00 +0000
+Subject: net: mscc: ocelot: extract ocelot_xmit_timestamp() helper
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 29372f07f7969a2f0490793226ecf6c8c6bde0fa ]
+
+Extract the PTP timestamp handling logic from ocelot_port_xmit() into a
+separate ocelot_xmit_timestamp() helper function. This is a pure
+refactor with no behavioral change.
+
+The helper returns false if the skb was consumed (freed) due to a
+timestamp request failure, and true if the caller should continue with
+frame injection. The rew_op value is returned via pointer.
+
+This prepares for splitting ocelot_port_xmit() into separate FDMA and
+register injection paths in a subsequent patch.
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-2-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 36 ++++++++++++++++----------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index 7c9540a717251..5d2d40cb8333d 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -551,33 +551,41 @@ static int ocelot_port_stop(struct net_device *dev)
+ return 0;
+ }
+
+-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port,
++ struct sk_buff *skb, u32 *rew_op)
+ {
+- struct ocelot_port_private *priv = netdev_priv(dev);
+- struct ocelot_port *ocelot_port = &priv->port;
+- struct ocelot *ocelot = ocelot_port->ocelot;
+- int port = priv->port.index;
+- u32 rew_op = 0;
+-
+- if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
+- !ocelot_can_inject(ocelot, 0))
+- return NETDEV_TX_BUSY;
+-
+- /* Check if timestamping is needed */
+ if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ struct sk_buff *clone = NULL;
+
+ if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) {
+ kfree_skb(skb);
+- return NETDEV_TX_OK;
++ return false;
+ }
+
+ if (clone)
+ OCELOT_SKB_CB(skb)->clone = clone;
+
+- rew_op = ocelot_ptp_rew_op(skb);
++ *rew_op = ocelot_ptp_rew_op(skb);
+ }
+
++ return true;
++}
++
++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ struct ocelot_port_private *priv = netdev_priv(dev);
++ struct ocelot_port *ocelot_port = &priv->port;
++ struct ocelot *ocelot = ocelot_port->ocelot;
++ int port = priv->port.index;
++ u32 rew_op = 0;
++
++ if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
++ !ocelot_can_inject(ocelot, 0))
++ return NETDEV_TX_BUSY;
++
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ return NETDEV_TX_OK;
++
+ if (static_branch_unlikely(&ocelot_fdma_enabled)) {
+ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
+ } else {
+--
+2.51.0
+
--- /dev/null
+From f320f430a4448bc0ed9143aa5a19a73a17491c31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:01 +0000
+Subject: net: mscc: ocelot: split xmit into FDMA and register injection paths
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 47f79b20e7fb885aa1623b759a68e8e27401ec4d ]
+
+Split ocelot_port_xmit() into two separate functions:
+- ocelot_port_xmit_fdma(): handles the FDMA injection path
+- ocelot_port_xmit_inj(): handles the register-based injection path
+
+The top-level ocelot_port_xmit() now dispatches to the appropriate
+function based on the ocelot_fdma_enabled static key.
+
+This is a pure refactor with no behavioral change. Separating the two
+code paths makes each one simpler and prepares for adding proper locking
+to the register injection path without affecting the FDMA path.
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-3-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 39 ++++++++++++++++++++------
+ 1 file changed, 30 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index 5d2d40cb8333d..df863657c87de 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -571,7 +571,25 @@ static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port,
+ return true;
+ }
+
+-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb,
++ struct net_device *dev)
++{
++ struct ocelot_port_private *priv = netdev_priv(dev);
++ struct ocelot_port *ocelot_port = &priv->port;
++ struct ocelot *ocelot = ocelot_port->ocelot;
++ int port = priv->port.index;
++ u32 rew_op = 0;
++
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ return NETDEV_TX_OK;
++
++ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
++
++ return NETDEV_TX_OK;
++}
++
++static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb,
++ struct net_device *dev)
+ {
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+@@ -579,24 +597,27 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
+ int port = priv->port.index;
+ u32 rew_op = 0;
+
+- if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
+- !ocelot_can_inject(ocelot, 0))
++ if (!ocelot_can_inject(ocelot, 0))
+ return NETDEV_TX_BUSY;
+
+ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
+ return NETDEV_TX_OK;
+
+- if (static_branch_unlikely(&ocelot_fdma_enabled)) {
+- ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
+- } else {
+- ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
++ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
+- consume_skb(skb);
+- }
++ consume_skb(skb);
+
+ return NETDEV_TX_OK;
+ }
+
++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ if (static_branch_unlikely(&ocelot_fdma_enabled))
++ return ocelot_port_xmit_fdma(skb, dev);
++
++ return ocelot_port_xmit_inj(skb, dev);
++}
++
+ enum ocelot_action_type {
+ OCELOT_MACT_LEARN,
+ OCELOT_MACT_FORGET,
+--
+2.51.0
+
--- /dev/null
+From 7c4a15bc60c27c946ce80fbe4585b5484c42d0f5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:54:09 -0700
+Subject: net/rds: rds_sendmsg should not discard payload_len
+
+From: Allison Henderson <achender@kernel.org>
+
+[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ]
+
+Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with
+connection teardown") modifies rds_sendmsg to avoid enqueueing work
+while a tear down is in progress. However, it also changed the return
+value of rds_sendmsg to that of rds_send_xmit instead of the
+payload_len. This means the user may incorrectly receive errno values
+when it should have simply received a payload of 0 while the peer
+attempts a reconnections. So this patch corrects the teardown handling
+code to only use the out error path in that case, thus restoring the
+original payload_len return value.
+
+Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/send.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/rds/send.c b/net/rds/send.c
+index 09a2801106549..4a24ee9c22d7c 100644
+--- a/net/rds/send.c
++++ b/net/rds/send.c
+@@ -1382,9 +1382,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
+ else
+ queue_delayed_work(rds_wq, &cpath->cp_send_w, 1);
+ rcu_read_unlock();
++
++ if (ret)
++ goto out;
+ }
+- if (ret)
+- goto out;
++
+ rds_message_put(rm);
+
+ for (ind = 0; ind < vct.indx; ind++)
+--
+2.51.0
+
--- /dev/null
+From 40a940b54752c1bddc076a02f1f8e3f7e07e2550 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 12:56:39 +0100
+Subject: net: remove WARN_ON_ONCE when accessing forward path array
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ]
+
+Although unlikely, recent support for IPIP tunnels increases chances of
+reaching this WARN_ON_ONCE if userspace manages to build a sufficiently
+long forward path.
+
+Remove it.
+
+Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 1d276a26a360d..553317ad6f1b4 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -720,7 +720,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack)
+ {
+ int k = stack->num_paths++;
+
+- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX))
++ if (k >= NET_DEVICE_PATH_STACK_MAX)
+ return NULL;
+
+ return &stack->path[k];
+--
+2.51.0
+
--- /dev/null
+From 10f014ce0a4d9fef80ce4fcb2db8c04d8b8571b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 14:44:01 +0100
+Subject: net: sparx5/lan969x: fix DWRR cost max to match hardware register
+ width
+
+From: Daniel Machon <daniel.machon@microchip.com>
+
+[ Upstream commit 6c28aa8dfdf24f554d4c5d4ff7d723a95360d94a ]
+
+DWRR (Deficit Weighted Round Robin) scheduling distributes bandwidth
+across traffic classes based on per-queue cost values, where lower cost
+means higher bandwidth share.
+
+The SPX5_DWRR_COST_MAX constant is 63 (6 bits) but the hardware
+register field HSCH_DWRR_ENTRY_DWRR_COST is GENMASK(24, 20), only
+5 bits wide (max 31). This causes sparx5_weight_to_hw_cost() to
+compute cost values that silently overflow via FIELD_PREP, resulting
+in incorrect scheduling weights.
+
+Set SPX5_DWRR_COST_MAX to 31 to match the hardware register width.
+
+Fixes: 211225428d65 ("net: microchip: sparx5: add support for offloading ets qdisc")
+Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260210-sparx5-fix-dwrr-cost-max-v1-1-58fbdbc25652@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
+index ced35033a6c5d..b1c6c5c6f16ca 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
+@@ -35,7 +35,7 @@
+ #define SPX5_SE_BURST_UNIT 4096
+
+ /* Dwrr */
+-#define SPX5_DWRR_COST_MAX 63
++#define SPX5_DWRR_COST_MAX 31
+
+ struct sparx5_shaper {
+ u32 mode;
+--
+2.51.0
+
--- /dev/null
+From e8e8ae079c137b538272d8f452900d418895de65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 12:02:30 +0100
+Subject: net: sparx5/lan969x: fix PTP clock max_adj value
+
+From: Daniel Machon <daniel.machon@microchip.com>
+
+[ Upstream commit a49d2a2c37a6252c41cbdd505f9d1c58d5a3817a ]
+
+The max_adj field in ptp_clock_info tells userspace how much the PHC
+clock frequency can be adjusted. ptp4l reads this and will never request
+a correction larger than max_adj.
+
+On both sparx5 and lan969x the clock offset may never converge because
+the servo needs a frequency correction larger than the current max_adj
+of 200000 (200 ppm) allows. The servo rails at the max and the offset
+stays in the tens of microseconds.
+
+The hardware has no inherent max adjustment limit; frequency correction
+is done by writing a 64-bit clock period increment to CLK_PER_CFG, and
+the register has plenty of range. The 200000 value was just an overly
+conservative software limit. The max_adj is shared between sparx5 and
+lan969x, and the increased value is safe for both.
+
+Fix this by increasing max_adj to 10000000 (10000 ppm), giving the
+servo sufficient headroom.
+
+Fixes: 0933bd04047c ("net: sparx5: Add support for ptp clocks")
+Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260212-sparx5-ptp-max-adj-v2-v1-1-06b200e50ce3@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+index 5a932460db581..6b2dbfbeef377 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+@@ -562,7 +562,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+ static struct ptp_clock_info sparx5_ptp_clock_info = {
+ .owner = THIS_MODULE,
+ .name = "sparx5 ptp",
+- .max_adj = 200000,
++ .max_adj = 10000000,
+ .gettime64 = sparx5_ptp_gettime64,
+ .settime64 = sparx5_ptp_settime64,
+ .adjtime = sparx5_ptp_adjtime,
+--
+2.51.0
+
--- /dev/null
+From a13cfa690161a70bcb9587fe5a17072a4de0c5ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 21:41:54 +0000
+Subject: net: usb: catc: enable basic endpoint checking
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ]
+
+catc_probe() fills three URBs with hardcoded endpoint pipes without
+verifying the endpoint descriptors:
+
+ - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX
+ - usb_rcvintpipe(usbdev, 2) for interrupt status
+
+A malformed USB device can present these endpoints with transfer types
+that differ from what the driver assumes.
+
+Add a catc_usb_ep enum for endpoint numbers, replacing magic constants
+throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints()
+calls after usb_set_interface() to verify endpoint types before use,
+rejecting devices with mismatched descriptors at probe time.
+
+Similar to
+- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking")
+which fixed the issue in rtl8150.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Suggested-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------
+ 1 file changed, 31 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
+index ff439ef535ac9..98346cb4ece01 100644
+--- a/drivers/net/usb/catc.c
++++ b/drivers/net/usb/catc.c
+@@ -64,6 +64,16 @@ static const char driver_name[] = "catc";
+ #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */
+ #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */
+
++/*
++ * USB endpoints.
++ */
++
++enum catc_usb_ep {
++ CATC_USB_EP_CONTROL = 0,
++ CATC_USB_EP_BULK = 1,
++ CATC_USB_EP_INT_IN = 2,
++};
++
+ /*
+ * Control requests.
+ */
+@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ u8 broadcast[ETH_ALEN];
+ u8 *macbuf;
+ int pktsz, ret = -ENOMEM;
++ static const u8 bulk_ep_addr[] = {
++ CATC_USB_EP_BULK | USB_DIR_OUT,
++ CATC_USB_EP_BULK | USB_DIR_IN,
++ 0};
++ static const u8 int_ep_addr[] = {
++ CATC_USB_EP_INT_IN | USB_DIR_IN,
++ 0};
+
+ macbuf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if (!macbuf)
+@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ goto fail_mem;
+ }
+
++ /* Verify that all required endpoints are present */
++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
++ !usb_check_int_endpoints(intf, int_ep_addr)) {
++ dev_err(dev, "Missing or invalid endpoints\n");
++ ret = -ENODEV;
++ goto fail_mem;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct catc));
+ if (!netdev)
+ goto fail_mem;
+@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0),
+ NULL, NULL, 0, catc_ctrl_done, catc);
+
+- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1),
+- NULL, 0, catc_tx_done, catc);
++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK),
++ NULL, 0, catc_tx_done, catc);
+
+- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1),
+- catc->rx_buf, pktsz, catc_rx_done, catc);
++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK),
++ catc->rx_buf, pktsz, catc_rx_done, catc);
+
+- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2),
+- catc->irq_buf, 2, catc_irq_done, catc, 1);
++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN),
++ catc->irq_buf, 2, catc_irq_done, catc, 1);
+
+ if (!catc->is_f5u011) {
+ u32 *buf;
+--
+2.51.0
+
--- /dev/null
+From 3348a6871396d063e539781376af1d3d1c59f452 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 12:53:09 +0100
+Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ]
+
+Mihail Milev reports: Error: UNINIT (CWE-457):
+ net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl:
+ Declaring variable "tuple" without initializer.
+ net/netfilter/nf_conntrack_h323_main.c:1197:2:
+ uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find".
+ net/netfilter/nf_conntrack_expect.c:142:2:
+ read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash".
+
+ 1195| tuple.dst.protonum = IPPROTO_TCP;
+ 1196|
+ 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ 1198| if (exp && exp->master == ct)
+ 1199| return exp;
+
+Switch this to a C99 initialiser and set the l3num value.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_h323_main.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
+index 5a9bce24f3c3d..ed983421e2eb2 100644
+--- a/net/netfilter/nf_conntrack_h323_main.c
++++ b/net/netfilter/nf_conntrack_h323_main.c
+@@ -1186,13 +1186,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
+ {
+ struct net *net = nf_ct_net(ct);
+ struct nf_conntrack_expect *exp;
+- struct nf_conntrack_tuple tuple;
++ struct nf_conntrack_tuple tuple = {
++ .src.l3num = nf_ct_l3num(ct),
++ .dst.protonum = IPPROTO_TCP,
++ .dst.u.tcp.port = port,
++ };
+
+- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3));
+- tuple.src.u.tcp.port = 0;
+ memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3));
+- tuple.dst.u.tcp.port = port;
+- tuple.dst.protonum = IPPROTO_TCP;
+
+ exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ if (exp && exp->master == ct)
+--
+2.51.0
+
--- /dev/null
+From 615519bb31423c3c520737098c0bbc11e7a6026f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 21:14:40 +0900
+Subject: netfilter: nf_tables: fix use-after-free in nf_tables_addchain()
+
+From: Inseo An <y0un9sa@gmail.com>
+
+[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ]
+
+nf_tables_addchain() publishes the chain to table->chains via
+list_add_tail_rcu() (in nft_chain_add()) before registering hooks.
+If nf_tables_register_hook() then fails, the error path calls
+nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy()
+with no RCU grace period in between.
+
+This creates two use-after-free conditions:
+
+ 1) Control-plane: nf_tables_dump_chains() traverses table->chains
+ under rcu_read_lock(). A concurrent dump can still be walking
+ the chain when the error path frees it.
+
+ 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly
+ installs the IPv4 hook before IPv6 registration fails. Packets
+ entering nft_do_chain() via the transient IPv4 hook can still be
+ dereferencing chain->blob_gen_X when the error path frees the
+ chain.
+
+Add synchronize_rcu() between nft_chain_del() and the chain destroy
+so that all RCU readers -- both dump threads and in-flight packet
+evaluation -- have finished before the chain is freed.
+
+Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain")
+Signed-off-by: Inseo An <y0un9sa@gmail.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index f10be72021ddd..8dccd3598166b 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -2645,6 +2645,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
+
+ err_register_hook:
+ nft_chain_del(chain);
++ synchronize_rcu();
+ err_chain_add:
+ nft_trans_destroy(trans);
+ err_trans:
+--
+2.51.0
+
--- /dev/null
+From b5c36b36811c818cd73fc0bfb59341a13d330962 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 21:28:46 +0800
+Subject: objpool: fix the overestimation of object pooling metadata size
+
+From: zhouwenhao <zhouwenhao7600@gmail.com>
+
+[ Upstream commit 5ed4b6b37c647d168ae31035b3f61b705997e043 ]
+
+objpool uses struct objpool_head to store metadata information, and its
+cpu_slots member points to an array of pointers that store the addresses
+of the percpu ring arrays. However, the memory size allocated during the
+initialization of cpu_slots is nr_cpu_ids * sizeof(struct objpool_slot).
+On a 64-bit machine, the size of struct objpool_slot is 16 bytes, which is
+twice the size of the actual pointer required, and the extra memory is
+never be used, resulting in a waste of memory. Therefore, the memory size
+required for cpu_slots needs to be corrected.
+
+Link: https://lkml.kernel.org/r/20260202132846.68257-1-zhouwenhao7600@gmail.com
+Fixes: b4edb8d2d464 ("lib: objpool added: ring-array based lockless MPMC")
+Signed-off-by: zhouwenhao <zhouwenhao7600@gmail.com>
+Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
+Cc: Matt Wu <wuqiang.matt@bytedance.com>
+Cc: wuqiang.matt <wuqiang.matt@bytedance.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/objpool.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/objpool.c b/lib/objpool.c
+index b998b720c7329..d98fadf1de169 100644
+--- a/lib/objpool.c
++++ b/lib/objpool.c
+@@ -142,7 +142,7 @@ int objpool_init(struct objpool_head *pool, int nr_objs, int object_size,
+ pool->gfp = gfp & ~__GFP_ZERO;
+ pool->context = context;
+ pool->release = release;
+- slot_size = nr_cpu_ids * sizeof(struct objpool_slot);
++ slot_size = nr_cpu_ids * sizeof(struct objpool_slot *);
+ pool->cpu_slots = kzalloc(slot_size, pool->gfp);
+ if (!pool->cpu_slots)
+ return -ENOMEM;
+--
+2.51.0
+
--- /dev/null
+From 0a9a881cb8c1eff217c254ce773060d0e2438087 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:33:38 +0530
+Subject: octeontx2-af: Fix default entries mcam entry action
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ]
+
+As per design, AF should update the default MCAM action only when
+mcam_index is -1. A bug in the previous patch caused default entries
+to be changed even when the request was not for them.
+
+Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++---------
+ 1 file changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+index 97722ce8c4cb3..a78923d7811dc 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+@@ -1058,32 +1058,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
+ rvu_write64(rvu, blkaddr,
+ NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action);
+
+- /* update the VF flow rule action with the VF default entry action */
+- if (mcam_index < 0)
+- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
+- *(u64 *)&action);
+-
+ /* update the action change in default rule */
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+ if (pfvf->def_ucast_rule)
+ pfvf->def_ucast_rule->rx_action = action;
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_PROMISC_ENTRY);
++ if (mcam_index < 0) {
++ /* update the VF flow rule action with the VF default
++ * entry action
++ */
++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
++ *(u64 *)&action);
+
+- /* If PF's promiscuous entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_PROMISC_ENTRY);
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_ALLMULTI_ENTRY);
+- /* If PF's allmulti entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ /* If PF's promiscuous entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_ALLMULTI_ENTRY);
++ /* If PF's allmulti entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++ }
+ }
+
+ void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc,
+--
+2.51.0
+
--- /dev/null
+From cdabb11b55aa2ceec7f2b32474fe76500f68b516 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:01:49 +0000
+Subject: ping: annotate data-races in ping_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit ad5dfde2a5733aaf652ea3e40c8c5e071e935901 ]
+
+isk->inet_num, isk->inet_rcv_saddr and sk->sk_bound_dev_if
+are read locklessly in ping_lookup().
+
+Add READ_ONCE()/WRITE_ONCE() annotations.
+
+The race on isk->inet_rcv_saddr is probably coming from IPv6 support,
+but does not deserve a specific backport.
+
+Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216100149.3319315-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ping.c | 31 +++++++++++++++++++------------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index f62b17f59bb4a..0089c1605acfe 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -159,7 +159,7 @@ void ping_unhash(struct sock *sk)
+ pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+ spin_lock(&ping_table.lock);
+ if (sk_del_node_init_rcu(sk)) {
+- isk->inet_num = 0;
++ WRITE_ONCE(isk->inet_num, 0);
+ isk->inet_sport = 0;
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+ }
+@@ -192,31 +192,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ }
+
+ sk_for_each_rcu(sk, hslot) {
++ int bound_dev_if;
++
+ if (!net_eq(sock_net(sk), net))
+ continue;
+ isk = inet_sk(sk);
+
+ pr_debug("iterate\n");
+- if (isk->inet_num != ident)
++ if (READ_ONCE(isk->inet_num) != ident)
+ continue;
+
++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+ if (skb->protocol == htons(ETH_P_IP) &&
+ sk->sk_family == AF_INET) {
++ __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr);
++
+ pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk,
+- (int) isk->inet_num, &isk->inet_rcv_saddr,
+- sk->sk_bound_dev_if);
++ ident, &rcv_saddr,
++ bound_dev_if);
+
+- if (isk->inet_rcv_saddr &&
+- isk->inet_rcv_saddr != ip_hdr(skb)->daddr)
++ if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr)
+ continue;
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (skb->protocol == htons(ETH_P_IPV6) &&
+ sk->sk_family == AF_INET6) {
+
+ pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk,
+- (int) isk->inet_num,
++ ident,
+ &sk->sk_v6_rcv_saddr,
+- sk->sk_bound_dev_if);
++ bound_dev_if);
+
+ if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) &&
+ !ipv6_addr_equal(&sk->sk_v6_rcv_saddr,
+@@ -227,8 +231,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ continue;
+ }
+
+- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
+- sk->sk_bound_dev_if != sdif)
++ if (bound_dev_if && bound_dev_if != dif &&
++ bound_dev_if != sdif)
+ continue;
+
+ goto exit;
+@@ -403,7 +407,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr *saddr)
+ if (saddr->sa_family == AF_INET) {
+ struct inet_sock *isk = inet_sk(sk);
+ struct sockaddr_in *addr = (struct sockaddr_in *) saddr;
+- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
++
++ isk->inet_saddr = addr->sin_addr.s_addr;
++ WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr);
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (saddr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr;
+@@ -860,7 +866,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
+ struct sk_buff *skb;
+ int copied, err;
+
+- pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
++ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk,
++ READ_ONCE(isk->inet_num));
+
+ err = -EOPNOTSUPP;
+ if (flags & MSG_OOB)
+--
+2.51.0
+
--- /dev/null
+From 32e770989a4a7b777e075e6fe7fd28d104262826 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 14:34:01 -0800
+Subject: powercap: intel_rapl_tpmi: Remove FW_BUG from invalid version check
+
+From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+
+[ Upstream commit c7d54dafa042cf379859dba265fe5afef6fa8770 ]
+
+On partitioned systems, multiple TPMI instances may exist per package,
+but RAPL registers are only valid on one instance since RAPL has
+package-scope control. Other instances return invalid versions during
+domain parsing, which is expected behavior on such systems.
+
+Currently this generates a firmware bug warning:
+
+ intel_rapl_tpmi: [Firmware Bug]: Invalid version
+
+Remove the FW_BUG tag, downgrade to pr_debug(), and update the message
+to clarify that invalid versions are expected on partitioned systems
+where only one instance can be valid.
+
+Fixes: 9eef7f9da928 ("powercap: intel_rapl: Introduce RAPL TPMI interface driver")
+Reported-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Reviewed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Link: https://patch.msgid.link/20260211223401.1575776-1-sathyanarayanan.kuppuswamy@linux.intel.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/powercap/intel_rapl_tpmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/powercap/intel_rapl_tpmi.c b/drivers/powercap/intel_rapl_tpmi.c
+index 645fd1dc51a98..1618138c5cac1 100644
+--- a/drivers/powercap/intel_rapl_tpmi.c
++++ b/drivers/powercap/intel_rapl_tpmi.c
+@@ -156,7 +156,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
+ tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff;
+
+ if (tpmi_domain_version == TPMI_VERSION_INVALID) {
+- pr_warn(FW_BUG "Invalid version\n");
++ pr_debug("Invalid version, other instances may be valid\n");
+ return -ENODEV;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From b5f34b15bf28bbd6b40ea56bf5f7aaa24e63ca47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 07:29:16 +0100
+Subject: s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n
+
+From: Alexander Egorenkov <egorenar@linux.ibm.com>
+
+[ Upstream commit dd3411959b57df6e05a3ccbac67b0a836871c0c4 ]
+
+The commit c8424e776b09 ("MODSIGN: Export module signature definitions")
+replaced the dependency of KEXEC_SIG on SYSTEM_DATA_VERIFICATION with the
+dependency on MODULE_SIG_FORMAT. This change disables KEXEC_SIG in s390
+kernels built with MODULES=n if nothing else selects MODULE_SIG_FORMAT.
+
+Furthermore, the signature verification in s390 kexec does not require
+MODULE_SIG_FORMAT because it requires only the struct module_signature and,
+therefore, does not depend on code in kernel/module_signature.c.
+
+But making ARCH_SUPPORTS_KEXEC_SIG depend on SYSTEM_DATA_VERIFICATION is
+also incorrect because it makes KEXEC_SIG available on s390 only if some
+other arbitrary option (for instance a file system or device driver)
+selects it directly or indirectly.
+
+To properly make KEXEC_SIG available for s390 kernels built with MODULES=y
+as well as MODULES=n _and_ also not depend on arbitrary options selecting
+SYSTEM_DATA_VERIFICATION, set ARCH_SUPPORTS_KEXEC_SIG=y for s390 and select
+SYSTEM_DATA_VERIFICATION when KEXEC_SIG=y.
+
+Fixes: c8424e776b09 ("MODSIGN: Export module signature definitions")
+Suggested-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 1786b30307942..5e6aebf1b739a 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -239,6 +239,7 @@ config S390
+ select SPARSE_IRQ
+ select SWIOTLB
+ select SYSCTL_EXCEPTION_TRACE
++ select SYSTEM_DATA_VERIFICATION if KEXEC_SIG
+ select THREAD_INFO_IN_TASK
+ select TRACE_IRQFLAGS_SUPPORT
+ select TTY
+@@ -264,7 +265,7 @@ config ARCH_SUPPORTS_KEXEC_FILE
+ def_bool y
+
+ config ARCH_SUPPORTS_KEXEC_SIG
+- def_bool MODULE_SIG_FORMAT
++ def_bool y
+
+ config ARCH_SUPPORTS_KEXEC_PURGATORY
+ def_bool y
+--
+2.51.0
+
--- /dev/null
+From 26c6cfcf531af3145d76883f014d918349af931e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:05 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with
+ br_netfilter enabled
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv4 packet contains a zero IP header checksum. After VXLAN
+decapsulation, such packets do not pass sanity checks in br_netfilter
+and are dropped, which causes the test to fail.
+
+Fix this by calculating and setting a valid IPv4 header checksum for the
+encapsulated packet generated by mausezahn, so that the packet is accepted
+by br_netfilter. Fixed by using the payload_template_calc_checksum() /
+payload_template_expand_checksum() helpers that are only available
+in v6.3 and newer kernels.
+
+Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++-------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+index 3f9d50f1ef9ec..1952023c43ba4 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+@@ -559,6 +559,21 @@ vxlan_encapped_ping_do()
+ local inner_tos=$1; shift
+ local outer_tos=$1; shift
+
++ local ipv4hdr=$(:
++ )"45:"$( : IP version + IHL
++ )"$inner_tos:"$( : IP TOS
++ )"00:54:"$( : IP total length
++ )"99:83:"$( : IP identification
++ )"40:00:"$( : IP flags + frag off
++ )"40:"$( : IP TTL
++ )"01:"$( : IP proto
++ )"CHECKSUM:"$( : IP header csum
++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1
++ )
++ local checksum=$(payload_template_calc_checksum "$ipv4hdr")
++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum)
++
+ $MZ $dev -c $count -d 100msec -q \
+ -b $next_hop_mac -B $dest_ip \
+ -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(:
+@@ -569,16 +584,7 @@ vxlan_encapped_ping_do()
+ )"$dest_mac:"$( : ETH daddr
+ )"$(mac_get w2):"$( : ETH saddr
+ )"08:00:"$( : ETH type
+- )"45:"$( : IP version + IHL
+- )"$inner_tos:"$( : IP TOS
+- )"00:54:"$( : IP total length
+- )"99:83:"$( : IP identification
+- )"40:00:"$( : IP flags + frag off
+- )"40:"$( : IP TTL
+- )"01:"$( : IP proto
+- )"00:00:"$( : IP header csum
+- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
+- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1
++ )"$ipv4hdr:"$( : IPv4 header
+ )"08:"$( : ICMP type
+ )"00:"$( : ICMP code
+ )"8b:f2:"$( : ICMP csum
+--
+2.51.0
+
--- /dev/null
+From f7518edd06fd30c5bdc0e4247ca2cfdb457a2047 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:06 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with
+ br_netfilter enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit ce9f6aec0fb780dafc1dfc5f47c688422aff464a ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv6 packet has an incorrect payload length set in the IPv6 header.
+After VXLAN decapsulation, such packets do not pass sanity checks in
+br_netfilter and are dropped, which causes the test to fail.
+
+Fix this by setting the correct IPv6 payload length for the encapsulated
+packet generated by mausezahn, so that the packet is accepted
+by br_netfilter.
+
+tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+lines 698-706
+
+ )"00:03:"$( : Payload length
+ )"3a:"$( : Next header
+ )"04:"$( : Hop limit
+ )"$saddr:"$( : IP saddr
+ )"$daddr:"$( : IP daddr
+ )"80:"$( : ICMPv6.type
+ )"00:"$( : ICMPv6.code
+ )"00:"$( : ICMPv6.checksum
+ )
+
+Data after IPv6 header:
+• 80: — 1 byte (ICMPv6 type)
+• 00: — 1 byte (ICMPv6 code)
+• 00: — 1 byte (ICMPv6 checksum, truncated)
+
+Total: 3 bytes → 00:03 is correct. The old value 00:08 did not match
+the actual payload size.
+
+Fixes: b07e9957f220 ("selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for IPv6")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-3-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+index a603f7b0a08f0..e642feeada0e7 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+@@ -695,7 +695,7 @@ vxlan_encapped_ping_do()
+ )"6"$( : IP version
+ )"$inner_tos"$( : Traffic class
+ )"0:00:00:"$( : Flow label
+- )"00:08:"$( : Payload length
++ )"00:03:"$( : Payload length
+ )"3a:"$( : Next header
+ )"04:"$( : Hop limit
+ )"$saddr:"$( : IP saddr
+--
+2.51.0
+
--- /dev/null
+From ead92bcb10ad8c0b3653acd376d1d647896233f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 09:38:05 -0500
+Subject: selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT
+
+From: Aristeu Rozanski <aris@redhat.com>
+
+[ Upstream commit b24335521de92fd2ee22460072b75367ca8860b0 ]
+
+selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT
+
+In order to synchronize new processes to test inheritance of memfd_noexec
+sysctl, memfd_test sets up the sysctl with a value before creating the new
+process. The new process then sends itself a SIGSTOP in order to wait for
+the parent to flip the sysctl value and send a SIGCONT signal.
+
+This would work as intended if it wasn't the fact that the new process is
+being created with CLONE_NEWPID, which creates a new PID namespace and the
+new process has PID 1 in this namespace. There're restrictions on sending
+signals to PID 1 and, although it's relaxed for other than root PID
+namespace, it's biting us here. In this specific case the SIGSTOP sent by
+the new process is ignored (no error to kill() is returned) and it never
+stops its execution. This is usually not noticiable as the parent usually
+manages to set the new sysctl value before the child has a chance to run
+and the test succeeds. But if you run the test in a loop, it eventually
+reproduces:
+
+ while [ 1 ]; do ./memfd_test >log 2>&1 || break; done; cat log
+
+So this patch replaces the SIGSTOP/SIGCONT synchronization with IPC
+semaphore.
+
+Link: https://lkml.kernel.org/r/a7776389-b3d6-4b18-b438-0b0e3ed1fd3b@work
+Fixes: 6469b66e3f5a ("selftests: improve vm.memfd_noexec sysctl tests")
+Signed-off-by: Aristeu Rozanski <aris@redhat.com>
+Cc: Aleksa Sarai <cyphar@cyphar.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: liuye <liuye@kylinos.cn>
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/memfd/memfd_test.c | 113 +++++++++++++++++++--
+ 1 file changed, 105 insertions(+), 8 deletions(-)
+
+diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c
+index 0a0b555160280..b518699a71038 100644
+--- a/tools/testing/selftests/memfd/memfd_test.c
++++ b/tools/testing/selftests/memfd/memfd_test.c
+@@ -18,6 +18,9 @@
+ #include <sys/stat.h>
+ #include <sys/syscall.h>
+ #include <sys/wait.h>
++#include <sys/types.h>
++#include <sys/ipc.h>
++#include <sys/sem.h>
+ #include <unistd.h>
+ #include <ctype.h>
+
+@@ -39,6 +42,20 @@
+ F_SEAL_EXEC)
+
+ #define MFD_NOEXEC_SEAL 0x0008U
++union semun {
++ int val;
++ struct semid_ds *buf;
++ unsigned short int *array;
++ struct seminfo *__buf;
++};
++
++/*
++ * we use semaphores on nested wait tasks due the use of CLONE_NEWPID: the
++ * child will be PID 1 and can't send SIGSTOP to themselves due special
++ * treatment of the init task, so the SIGSTOP/SIGCONT synchronization
++ * approach can't be used here.
++ */
++#define SEM_KEY 0xdeadbeef
+
+ /*
+ * Default is not to test hugetlbfs
+@@ -1291,8 +1308,22 @@ static int sysctl_nested(void *arg)
+
+ static int sysctl_nested_wait(void *arg)
+ {
+- /* Wait for a SIGCONT. */
+- kill(getpid(), SIGSTOP);
++ int sem = semget(SEM_KEY, 1, 0600);
++ struct sembuf sembuf;
++
++ if (sem < 0) {
++ perror("semget:");
++ abort();
++ }
++ sembuf.sem_num = 0;
++ sembuf.sem_flg = 0;
++ sembuf.sem_op = 0;
++
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ abort();
++ }
++
+ return sysctl_nested(arg);
+ }
+
+@@ -1313,7 +1344,9 @@ static void test_sysctl_sysctl2_failset(void)
+
+ static int sysctl_nested_child(void *arg)
+ {
+- int pid;
++ int pid, sem;
++ union semun semun;
++ struct sembuf sembuf;
+
+ printf("%s nested sysctl 0\n", memfd_str);
+ sysctl_assert_write("0");
+@@ -1347,23 +1380,53 @@ static int sysctl_nested_child(void *arg)
+ test_sysctl_sysctl2_failset);
+ join_thread(pid);
+
++ sem = semget(SEM_KEY, 1, IPC_CREAT | 0600);
++ if (sem < 0) {
++ perror("semget:");
++ return 1;
++ }
++ semun.val = 1;
++ sembuf.sem_op = -1;
++ sembuf.sem_flg = 0;
++ sembuf.sem_num = 0;
++
+ /* Verify that the rules are actually inherited after fork. */
+ printf("%s nested sysctl 0 -> 1 after fork\n", memfd_str);
+ sysctl_assert_write("0");
+
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl1_failset);
+ sysctl_assert_write("1");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 0 -> 2 after fork\n", memfd_str);
+ sysctl_assert_write("0");
+
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2_failset);
+ sysctl_assert_write("2");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ /*
+@@ -1373,28 +1436,62 @@ static int sysctl_nested_child(void *arg)
+ */
+ printf("%s nested sysctl 2 -> 1 after fork\n", memfd_str);
+ sysctl_assert_write("2");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2);
+ sysctl_assert_write("1");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 2 -> 0 after fork\n", memfd_str);
+ sysctl_assert_write("2");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2);
+ sysctl_assert_write("0");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 1 -> 0 after fork\n", memfd_str);
+ sysctl_assert_write("1");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl1);
+ sysctl_assert_write("0");
+- kill(pid, SIGCONT);
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
++ semctl(sem, 0, IPC_RMID);
++
+ return 0;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From b9a61defd3b4cc5b777e72b82023e04c0801d846 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 14:53:53 +0100
+Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ]
+
+As explained in [1], iproute2 started rejecting tc-police burst sizes
+that result in an overflow. This can happen when the burst size is high
+enough and the rate is low enough.
+
+A couple of test cases specify such configurations, resulting in
+iproute2 errors and test failure.
+
+Fix by reducing the burst size so that the test will pass with both new
+and old iproute2 versions.
+
+[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/
+
+Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+index 0441a18f098b1..aac8ef490feb8 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+@@ -317,7 +317,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 0.5kbit burst 1m conform-exceed drop/ok
++ action police rate 0.5kbit burst 2k conform-exceed drop/ok
+ check_fail $? "Incorrect success to add police action with too low rate"
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+@@ -327,7 +327,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 1.5kbit burst 1m conform-exceed drop/ok
++ action police rate 1.5kbit burst 2k conform-exceed drop/ok
+ check_err $? "Failed to add police action with low rate"
+
+ tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
+--
+2.51.0
+
--- /dev/null
+From c323066db198394bebc818f8af36b4f75fbe43b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 19:51:59 -0800
+Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ]
+
+Since we started running selftests in NIPA we have been seeing
+tc_actions.sh generate a soft lockup warning on ~20% of the runs.
+On the pre-netdev foundation setup it was actually a missed irq
+splat from the console. Now it's either that or a lockup.
+
+I initially suspected a socket locking issue since the test
+is exercising local loopback with act_mirred.
+After hours of staring at this I noticed in strace that ncat
+when -o $file is specified _both_ saves the output to the file
+and still prints it to stdout. Because the file being sent
+is constructed with:
+
+ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred
+ ^^^^^^^^^
+
+the data printed is all \0. Most terminals don't display nul
+characters (and neither does vng output capture save them).
+But QEMU's serial console still has to poke them thru which
+is very slow and causes the lockup (if the file is >600kB).
+
+Replace the '-o $file' with '> $file'. This speeds the test up
+from 2m20s to 18s on debug kernels, and prevents the warnings.
+
+Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index ea89e558672db..86edbc7e2489b 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -223,7 +223,7 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 &
+ local rpid=$!
+ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+--
+2.51.0
+
dmaengine-fsl-edma-don-t-explicitly-disable-clocks-i.patch
drbd-always-set-blk_feat_stable_writes.patch
io_uring-cancel-de-unionize-file-and-user_data-in-st.patch
+fs-ntfs3-initialize-new-folios-before-use.patch
+fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch
+fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch
+acpi-button-install-notifier-for-system-events-as-we.patch
+acpi-button-only-send-key_power-for-acpi_button_noti.patch
+acpi-button-adjust-event-notification-routines.patch
+acpi-button-convert-the-driver-to-a-platform-one.patch
+acpi-button-call-device_init_wakeup-earlier-during-p.patch
+acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch
+powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch
+kbuild-add-objtool-to-top-level-clean-target.patch
+selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch
+objpool-fix-the-overestimation-of-object-pooling-met.patch
+acpi-pm-add-unused-power-resource-quirk-for-thundero.patch
+cpuidle-skip-governor-when-only-one-idle-state-is-av.patch
+selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch
+net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch
+net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch
+net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch
+net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch
+ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch
+net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch
+net-usb-catc-enable-basic-endpoint-checking.patch
+xen-netback-reject-zero-queue-configuration-from-gue.patch
+net-rds-rds_sendmsg-should-not-discard-payload_len.patch
+net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch
+selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch
+selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch
+netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch
+ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch
+net-remove-warn_on_once-when-accessing-forward-path-.patch
+netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch
+ipv6-fix-a-race-in-ip6_sock_set_v6only.patch
+bpftool-fix-truncated-netlink-dumps.patch
+ping-annotate-data-races-in-ping_lookup.patch
+selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch
+macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch
+icmp-prevent-possible-overflow-in-icmp_global_allow.patch
+inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch
+octeontx2-af-fix-default-entries-mcam-entry-action.patch
+bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch
+net-mlx5-fix-multiport-device-check-over-light-sfs.patch
+net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch
+apparmor-fix-null-sock-in-aa_sock_file_perm.patch
+apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch
+apparmor-fix-optimize-table-creation-from-possibly-u.patch
+apparmor-return-enomem-in-unpack_perms_table-upon-al.patch
+apparmor-fix-rlimit-for-posix-cpu-timers.patch
+apparmor-remove-apply_modes_to_perms-from-label_matc.patch
+apparmor-make-label_match-return-a-consistent-value.patch
+apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch
+apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch
+apparmor-fix-aa_label-to-return-state-from-compount-.patch
+drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch
+drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch
+drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch
+asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch
+drm-i915-acpi-free-_dsm-package-when-no-connectors.patch
+asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch
+drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch
+drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch
+drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch
+spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch
+s390-kexec-make-kexec_sig-available-when-config_modu.patch
+drm-xe-move-forcewake-to-gt.pm-substructure.patch
+drm-xe-create-dedicated-xe_mmio-structure.patch
+drm-xe-clarify-size-of-mmio-region.patch
+drm-xe-move-gsi-offset-adjustment-fields-into-struct.patch
+drm-xe-populate-gt-s-mmio-iomap-from-tile-during-ini.patch
+drm-xe-switch-mmio_ext-to-use-struct-xe_mmio.patch
+drm-xe-add-xe_tile-backpointer-to-xe_mmio.patch
+drm-xe-adjust-mmio-code-to-pass-vf-substructure-to-s.patch
+drm-xe-switch-mmio-interface-to-take-xe_mmio-instead.patch
+drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch
+drm-xe-ptl-apply-wa_13011645652.patch
+drm-xe-xe2_hpg-add-set-of-workarounds.patch
+drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch
+efi-fix-reservation-of-unaccepted-memory-table.patch
+btrfs-use-the-correct-type-to-initialize-block-reser.patch
+btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch
+x86-hyperv-fix-error-pointer-dereference.patch
+asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch
+drm-amd-display-use-same-max-plane-scaling-limits-fo.patch
--- /dev/null
+From cba7b5fc3d93f6b5c198fee5b6da28fe9344f306 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:41:40 +0800
+Subject: spi: wpcm-fiu: Fix potential NULL pointer dereference in
+ wpcm_fiu_probe()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Felix Gu <ustc.gu@gmail.com>
+
+[ Upstream commit 888a0a802c467bbe34a42167bdf9d7331333440a ]
+
+platform_get_resource_byname() can return NULL, which would cause a crash
+when passed the pointer to resource_size().
+
+Move the fiu->memory_size assignment after the error check for
+devm_ioremap_resource() to prevent the potential NULL pointer dereference.
+
+Fixes: 9838c182471e ("spi: wpcm-fiu: Add direct map support")
+Signed-off-by: Felix Gu <ustc.gu@gmail.com>
+Reviewed-by: J. Neuschäfer <j.ne@posteo.net>
+Link: https://patch.msgid.link/20260212-wpcm-v1-1-5b7c4f526aac@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-wpcm-fiu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c
+index a9aee2a6c7dcb..c47b56f0933f1 100644
+--- a/drivers/spi/spi-wpcm-fiu.c
++++ b/drivers/spi/spi-wpcm-fiu.c
+@@ -459,11 +459,11 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
+ fiu->memory = devm_ioremap_resource(dev, res);
+- fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+ if (IS_ERR(fiu->memory))
+ return dev_err_probe(dev, PTR_ERR(fiu->memory),
+ "Failed to map flash memory window\n");
+
++ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+ fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm");
+
+ wpcm_fiu_hw_init(fiu);
+--
+2.51.0
+
--- /dev/null
+From 9e49b394a10d793a248231ea18705e0b9e527bf6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 13:09:03 -0600
+Subject: x86/hyperv: Fix error pointer dereference
+
+From: Ethan Tidmore <ethantidmore06@gmail.com>
+
+[ Upstream commit 705d01c8d78121ee1634bfc602ac4b0ad1438fab ]
+
+The function idle_thread_get() can return an error pointer and is not
+checked for it. Add check for error pointer.
+
+Detected by Smatch:
+arch/x86/hyperv/hv_vtl.c:126 hv_vtl_bringup_vcpu() error:
+'idle' dereferencing possible ERR_PTR()
+
+Fixes: 2b4b90e053a29 ("x86/hyperv: Use per cpu initial stack for vtl context")
+Signed-off-by: Ethan Tidmore <ethantidmore06@gmail.com>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/hyperv/hv_vtl.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c
+index 2510e91b29b08..b135ba5c18710 100644
+--- a/arch/x86/hyperv/hv_vtl.c
++++ b/arch/x86/hyperv/hv_vtl.c
+@@ -68,7 +68,7 @@ static void hv_vtl_ap_entry(void)
+
+ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
+ {
+- u64 status;
++ u64 status, rsp, rip;
+ int ret = 0;
+ struct hv_enable_vp_vtl *input;
+ unsigned long irq_flags;
+@@ -81,9 +81,11 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
+ struct desc_struct *gdt;
+
+ struct task_struct *idle = idle_thread_get(cpu);
+- u64 rsp = (unsigned long)idle->thread.sp;
++ if (IS_ERR(idle))
++ return PTR_ERR(idle);
+
+- u64 rip = (u64)&hv_vtl_ap_entry;
++ rsp = (unsigned long)idle->thread.sp;
++ rip = (u64)&hv_vtl_ap_entry;
+
+ native_store_gdt(&gdt_ptr);
+ store_idt(&idt_ptr);
+--
+2.51.0
+
--- /dev/null
+From 3fd1466f7772791b3b619a35e8f1b4126a63682d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 22:40:40 +0000
+Subject: xen-netback: reject zero-queue configuration from guest
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ]
+
+A malicious or buggy Xen guest can write "0" to the xenbus key
+"multi-queue-num-queues". The connect() function in the backend only
+validates the upper bound (requested_num_queues > xenvif_max_queues)
+but not zero, allowing requested_num_queues=0 to reach
+vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers
+WARN_ON_ONCE(!size) in __vmalloc_node_range().
+
+On systems with panic_on_warn=1, this allows a guest-to-host denial
+of service.
+
+The Xen network interface specification requires
+the queue count to be "greater than zero".
+
+Add a zero check to match the validation already present
+in xen-blkback, which has included this
+guard since its multi-queue support was added.
+
+Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/xen-netback/xenbus.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
+index a78a25b872409..61b547aab286a 100644
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -735,10 +735,11 @@ static void connect(struct backend_info *be)
+ */
+ requested_num_queues = xenbus_read_unsigned(dev->otherend,
+ "multi-queue-num-queues", 1);
+- if (requested_num_queues > xenvif_max_queues) {
++ if (requested_num_queues > xenvif_max_queues ||
++ requested_num_queues == 0) {
+ /* buggy or malicious guest */
+ xenbus_dev_fatal(dev, -EINVAL,
+- "guest requested %u queues, exceeding the maximum of %u.",
++ "guest requested %u queues, but valid range is 1 - %u.",
+ requested_num_queues, xenvif_max_queues);
+ return;
+ }
+--
+2.51.0
+
--- /dev/null
+From 7ef894ebf106c74baec5924e515a2802ed21d287 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Dec 2025 14:55:09 +0100
+Subject: ACPI: button: Adjust event notification routines
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 93dc5db6d47aaa3b4b458ddfddfa3369c24e22f4 ]
+
+Adjust the event notification routines in the ACPI button driver to
+take a struct acpi_button pointer as an argument istead of a struct
+acpi_device one where applicable, which allows the use of
+acpi_driver_data() to be limited and will facilitate subsequent
+changes.
+
+No intentional functional impact.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://patch.msgid.link/2260995.Icojqenx9y@rafael.j.wysocki
+Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 67 +++++++++++++++++++++----------------------
+ 1 file changed, 33 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 3c6dd9b4ba0ad..09a6e4ffe9f20 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -169,6 +169,7 @@ static struct acpi_driver acpi_button_driver = {
+ };
+
+ struct acpi_button {
++ struct acpi_device *adev;
+ unsigned int type;
+ struct input_dev *input;
+ char phys[32]; /* for input device */
+@@ -202,9 +203,9 @@ static int acpi_lid_evaluate_state(struct acpi_device *device)
+ return lid_state ? 1 : 0;
+ }
+
+-static int acpi_lid_notify_state(struct acpi_device *device, int state)
++static int acpi_lid_notify_state(struct acpi_button *button, int state)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = button->adev;
+ ktime_t next_report;
+ bool do_update;
+
+@@ -287,18 +288,18 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state)
+ static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq,
+ void *offset)
+ {
+- struct acpi_device *device = seq->private;
++ struct acpi_button *button = seq->private;
+ int state;
+
+- state = acpi_lid_evaluate_state(device);
++ state = acpi_lid_evaluate_state(button->adev);
+ seq_printf(seq, "state: %s\n",
+ state < 0 ? "unsupported" : (state ? "open" : "closed"));
+ return 0;
+ }
+
+-static int acpi_button_add_fs(struct acpi_device *device)
++static int acpi_button_add_fs(struct acpi_button *button)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = button->adev;
+ struct proc_dir_entry *entry = NULL;
+ int ret = 0;
+
+@@ -333,7 +334,7 @@ static int acpi_button_add_fs(struct acpi_device *device)
+ /* create /proc/acpi/button/lid/LID/state */
+ entry = proc_create_single_data(ACPI_BUTTON_FILE_STATE, S_IRUGO,
+ acpi_device_dir(device), acpi_button_state_seq_show,
+- device);
++ button);
+ if (!entry) {
+ ret = -ENODEV;
+ goto remove_dev_dir;
+@@ -355,9 +356,9 @@ static int acpi_button_add_fs(struct acpi_device *device)
+ goto done;
+ }
+
+-static int acpi_button_remove_fs(struct acpi_device *device)
++static int acpi_button_remove_fs(struct acpi_button *button)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = button->adev;
+
+ if (button->type != ACPI_BUTTON_TYPE_LID)
+ return 0;
+@@ -385,9 +386,10 @@ int acpi_lid_open(void)
+ }
+ EXPORT_SYMBOL(acpi_lid_open);
+
+-static int acpi_lid_update_state(struct acpi_device *device,
++static int acpi_lid_update_state(struct acpi_button *button,
+ bool signal_wakeup)
+ {
++ struct acpi_device *device = button->adev;
+ int state;
+
+ state = acpi_lid_evaluate_state(device);
+@@ -397,19 +399,17 @@ static int acpi_lid_update_state(struct acpi_device *device,
+ if (state && signal_wakeup)
+ acpi_pm_wakeup_event(&device->dev);
+
+- return acpi_lid_notify_state(device, state);
++ return acpi_lid_notify_state(button, state);
+ }
+
+-static void acpi_lid_initialize_state(struct acpi_device *device)
++static void acpi_lid_initialize_state(struct acpi_button *button)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
+-
+ switch (lid_init_state) {
+ case ACPI_BUTTON_LID_INIT_OPEN:
+- (void)acpi_lid_notify_state(device, 1);
++ (void)acpi_lid_notify_state(button, 1);
+ break;
+ case ACPI_BUTTON_LID_INIT_METHOD:
+- (void)acpi_lid_update_state(device, false);
++ (void)acpi_lid_update_state(button, false);
+ break;
+ case ACPI_BUTTON_LID_INIT_IGNORE:
+ default:
+@@ -421,8 +421,8 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
+
+ static void acpi_lid_notify(acpi_handle handle, u32 event, void *data)
+ {
+- struct acpi_device *device = data;
+- struct acpi_button *button;
++ struct acpi_button *button = data;
++ struct acpi_device *device = button->adev;
+
+ if (event != ACPI_BUTTON_NOTIFY_STATUS) {
+ acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
+@@ -430,17 +430,16 @@ static void acpi_lid_notify(acpi_handle handle, u32 event, void *data)
+ return;
+ }
+
+- button = acpi_driver_data(device);
+ if (!button->lid_state_initialized)
+ return;
+
+- acpi_lid_update_state(device, true);
++ acpi_lid_update_state(button, true);
+ }
+
+ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+ {
+- struct acpi_device *device = data;
+- struct acpi_button *button;
++ struct acpi_button *button = data;
++ struct acpi_device *device = button->adev;
+ struct input_dev *input;
+ int keycode;
+
+@@ -457,7 +456,6 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+
+ acpi_pm_wakeup_event(&device->dev);
+
+- button = acpi_driver_data(device);
+ if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE)
+ return;
+
+@@ -505,7 +503,7 @@ static int acpi_button_resume(struct device *dev)
+ if (button->type == ACPI_BUTTON_TYPE_LID) {
+ button->last_state = !!acpi_lid_evaluate_state(device);
+ button->last_time = ktime_get();
+- acpi_lid_initialize_state(device);
++ acpi_lid_initialize_state(button);
+ }
+
+ if (button->type == ACPI_BUTTON_TYPE_POWER) {
+@@ -521,12 +519,12 @@ static int acpi_button_resume(struct device *dev)
+
+ static int acpi_lid_input_open(struct input_dev *input)
+ {
+- struct acpi_device *device = input_get_drvdata(input);
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_button *button = input_get_drvdata(input);
++ struct acpi_device *device = button->adev;
+
+ button->last_state = !!acpi_lid_evaluate_state(device);
+ button->last_time = ktime_get();
+- acpi_lid_initialize_state(device);
++ acpi_lid_initialize_state(button);
+
+ return 0;
+ }
+@@ -551,6 +549,7 @@ static int acpi_button_add(struct acpi_device *device)
+
+ device->driver_data = button;
+
++ button->adev = device;
+ button->input = input = input_allocate_device();
+ if (!input) {
+ error = -ENOMEM;
+@@ -587,7 +586,7 @@ static int acpi_button_add(struct acpi_device *device)
+ }
+
+ if (!error)
+- error = acpi_button_add_fs(device);
++ error = acpi_button_add_fs(button);
+
+ if (error) {
+ input_free_device(input);
+@@ -617,7 +616,7 @@ static int acpi_button_add(struct acpi_device *device)
+ break;
+ }
+
+- input_set_drvdata(input, device);
++ input_set_drvdata(input, button);
+ error = input_register_device(input);
+ if (error) {
+ input_free_device(input);
+@@ -628,17 +627,17 @@ static int acpi_button_add(struct acpi_device *device)
+ case ACPI_BUS_TYPE_POWER_BUTTON:
+ status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_button_event,
+- device);
++ button);
+ break;
+ case ACPI_BUS_TYPE_SLEEP_BUTTON:
+ status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_button_event,
+- device);
++ button);
+ break;
+ default:
+ status = acpi_install_notify_handler(device->handle,
+ ACPI_ALL_NOTIFY, handler,
+- device);
++ button);
+ break;
+ }
+ if (ACPI_FAILURE(status)) {
+@@ -661,7 +660,7 @@ static int acpi_button_add(struct acpi_device *device)
+ err_input_unregister:
+ input_unregister_device(input);
+ err_remove_fs:
+- acpi_button_remove_fs(device);
++ acpi_button_remove_fs(button);
+ err_free_button:
+ kfree(button);
+ return error;
+@@ -689,7 +688,7 @@ static void acpi_button_remove(struct acpi_device *device)
+ }
+ acpi_os_wait_events_complete();
+
+- acpi_button_remove_fs(device);
++ acpi_button_remove_fs(button);
+ input_unregister_device(button->input);
+ kfree(button);
+ }
+--
+2.51.0
+
--- /dev/null
+From 0cbd41fee306283a48dcba36cc7ac48a508c060e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 15:13:26 +0100
+Subject: ACPI: button: Call device_init_wakeup() earlier during probe
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit e91f8c5305b92b63c8bac315f95c535d5c1e8fec ]
+
+Calling device_init_wakeup() after installing a notify handler in which
+wakeup events are signaled may cause a wakeup event to be missed if the
+device is probed right before a system suspend.
+
+To avoid this, move the device_init_wakeup() call in acpi_button_probe()
+before the notify handler installation and add a corresponding cleanup
+to the error path.
+
+Also carry out wakeup cleanup for the button in acpi_button_remove()
+because after that point the notify handler will not run for it and
+wakeup events coming from it will not be signaled.
+
+Fixes: 0d51157dfaac ("ACPI: button: Eliminate the driver notify callback")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://patch.msgid.link/12854922.O9o76ZdvQC@rafael.j.wysocki
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index b899b8745fedd..38bc64d6bdaf3 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -625,6 +625,8 @@ static int acpi_button_probe(struct platform_device *pdev)
+ goto err_remove_fs;
+ }
+
++ device_init_wakeup(&pdev->dev, true);
++
+ switch (device->device_type) {
+ case ACPI_BUS_TYPE_POWER_BUTTON:
+ status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+@@ -655,11 +657,11 @@ static int acpi_button_probe(struct platform_device *pdev)
+ lid_device = device;
+ }
+
+- device_init_wakeup(&pdev->dev, true);
+ pr_info("%s [%s]\n", name, acpi_device_bid(device));
+ return 0;
+
+ err_input_unregister:
++ device_init_wakeup(&pdev->dev, false);
+ input_unregister_device(input);
+ err_remove_fs:
+ acpi_button_remove_fs(button);
+@@ -691,6 +693,8 @@ static void acpi_button_remove(struct platform_device *pdev)
+ }
+ acpi_os_wait_events_complete();
+
++ device_init_wakeup(&pdev->dev, false);
++
+ acpi_button_remove_fs(button);
+ input_unregister_device(button->input);
+ kfree(button);
+--
+2.51.0
+
--- /dev/null
+From 04681d258c4a7119c6f042f3e3ff1eb4ed356615 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Dec 2025 14:57:57 +0100
+Subject: ACPI: button: Convert the driver to a platform one
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 52d86401963666423cb9a56d117136c846093db0 ]
+
+While binding drivers directly to struct acpi_device objects allows
+basic functionality to be provided, at least in the majority of cases,
+there are some problems with it, related to general consistency, sysfs
+layout, power management operation ordering, and code cleanliness.
+
+Overall, it is better to bind drivers to platform devices than to their
+ACPI companions, so convert the ACPI button driver to a platform one.
+
+While this is not expected to alter functionality, it changes sysfs
+layout and so it will be visible to user space.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://patch.msgid.link/2461734.NG923GbCHz@rafael.j.wysocki
+Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 61 +++++++++++++++++++++++--------------------
+ 1 file changed, 32 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 09a6e4ffe9f20..b899b8745fedd 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -19,6 +19,7 @@
+ #include <linux/slab.h>
+ #include <linux/acpi.h>
+ #include <linux/dmi.h>
++#include <linux/platform_device.h>
+ #include <acpi/button.h>
+
+ #define ACPI_BUTTON_CLASS "button"
+@@ -145,8 +146,8 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
+ {}
+ };
+
+-static int acpi_button_add(struct acpi_device *device);
+-static void acpi_button_remove(struct acpi_device *device);
++static int acpi_button_probe(struct platform_device *pdev);
++static void acpi_button_remove(struct platform_device *pdev);
+
+ #ifdef CONFIG_PM_SLEEP
+ static int acpi_button_suspend(struct device *dev);
+@@ -157,19 +158,19 @@ static int acpi_button_resume(struct device *dev);
+ #endif
+ static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
+
+-static struct acpi_driver acpi_button_driver = {
+- .name = "button",
+- .class = ACPI_BUTTON_CLASS,
+- .ids = button_device_ids,
+- .ops = {
+- .add = acpi_button_add,
+- .remove = acpi_button_remove,
++static struct platform_driver acpi_button_driver = {
++ .probe = acpi_button_probe,
++ .remove = acpi_button_remove,
++ .driver = {
++ .name = "acpi-button",
++ .acpi_match_table = button_device_ids,
++ .pm = &acpi_button_pm,
+ },
+- .drv.pm = &acpi_button_pm,
+ };
+
+ struct acpi_button {
+ struct acpi_device *adev;
++ struct platform_device *pdev;
+ unsigned int type;
+ struct input_dev *input;
+ char phys[32]; /* for input device */
+@@ -397,7 +398,7 @@ static int acpi_lid_update_state(struct acpi_button *button,
+ return state;
+
+ if (state && signal_wakeup)
+- acpi_pm_wakeup_event(&device->dev);
++ acpi_pm_wakeup_event(&button->pdev->dev);
+
+ return acpi_lid_notify_state(button, state);
+ }
+@@ -454,7 +455,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+ return;
+ }
+
+- acpi_pm_wakeup_event(&device->dev);
++ acpi_pm_wakeup_event(&button->pdev->dev);
+
+ if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE)
+ return;
+@@ -486,8 +487,7 @@ static u32 acpi_button_event(void *data)
+ #ifdef CONFIG_PM_SLEEP
+ static int acpi_button_suspend(struct device *dev)
+ {
+- struct acpi_device *device = to_acpi_device(dev);
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_button *button = dev_get_drvdata(dev);
+
+ button->suspended = true;
+ return 0;
+@@ -495,9 +495,9 @@ static int acpi_button_suspend(struct device *dev)
+
+ static int acpi_button_resume(struct device *dev)
+ {
++ struct acpi_button *button = dev_get_drvdata(dev);
++ struct acpi_device *device = ACPI_COMPANION(dev);
+ struct input_dev *input;
+- struct acpi_device *device = to_acpi_device(dev);
+- struct acpi_button *button = acpi_driver_data(device);
+
+ button->suspended = false;
+ if (button->type == ACPI_BUTTON_TYPE_LID) {
+@@ -529,8 +529,9 @@ static int acpi_lid_input_open(struct input_dev *input)
+ return 0;
+ }
+
+-static int acpi_button_add(struct acpi_device *device)
++static int acpi_button_probe(struct platform_device *pdev)
+ {
++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+ acpi_notify_handler handler;
+ struct acpi_button *button;
+ struct input_dev *input;
+@@ -547,8 +548,9 @@ static int acpi_button_add(struct acpi_device *device)
+ if (!button)
+ return -ENOMEM;
+
+- device->driver_data = button;
++ platform_set_drvdata(pdev, button);
+
++ button->pdev = pdev;
+ button->adev = device;
+ button->input = input = input_allocate_device();
+ if (!input) {
+@@ -599,7 +601,7 @@ static int acpi_button_add(struct acpi_device *device)
+ input->phys = button->phys;
+ input->id.bustype = BUS_HOST;
+ input->id.product = button->type;
+- input->dev.parent = &device->dev;
++ input->dev.parent = &pdev->dev;
+
+ switch (button->type) {
+ case ACPI_BUTTON_TYPE_POWER:
+@@ -653,7 +655,7 @@ static int acpi_button_add(struct acpi_device *device)
+ lid_device = device;
+ }
+
+- device_init_wakeup(&device->dev, true);
++ device_init_wakeup(&pdev->dev, true);
+ pr_info("%s [%s]\n", name, acpi_device_bid(device));
+ return 0;
+
+@@ -666,9 +668,10 @@ static int acpi_button_add(struct acpi_device *device)
+ return error;
+ }
+
+-static void acpi_button_remove(struct acpi_device *device)
++static void acpi_button_remove(struct platform_device *pdev)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
++ struct acpi_button *button = platform_get_drvdata(pdev);
+
+ switch (device->device_type) {
+ case ACPI_BUS_TYPE_POWER_BUTTON:
+@@ -727,7 +730,7 @@ module_param_call(lid_init_state,
+ NULL, 0644);
+ MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state");
+
+-static int acpi_button_register_driver(struct acpi_driver *driver)
++static int __init acpi_button_init(void)
+ {
+ const struct dmi_system_id *dmi_id;
+
+@@ -743,20 +746,20 @@ static int acpi_button_register_driver(struct acpi_driver *driver)
+ * Modules such as nouveau.ko and i915.ko have a link time dependency
+ * on acpi_lid_open(), and would therefore not be loadable on ACPI
+ * capable kernels booted in non-ACPI mode if the return value of
+- * acpi_bus_register_driver() is returned from here with ACPI disabled
++ * platform_driver_register() is returned from here with ACPI disabled
+ * when this driver is built as a module.
+ */
+ if (acpi_disabled)
+ return 0;
+
+- return acpi_bus_register_driver(driver);
++ return platform_driver_register(&acpi_button_driver);
+ }
+
+-static void acpi_button_unregister_driver(struct acpi_driver *driver)
++static void __exit acpi_button_exit(void)
+ {
+ if (!acpi_disabled)
+- acpi_bus_unregister_driver(driver);
++ platform_driver_unregister(&acpi_button_driver);
+ }
+
+-module_driver(acpi_button_driver, acpi_button_register_driver,
+- acpi_button_unregister_driver);
++module_init(acpi_button_init);
++module_exit(acpi_button_exit);
+--
+2.51.0
+
--- /dev/null
+From 697f2a878193ad5ac05f53dbbfa35d3a0bab0cd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 21:22:54 +0000
+Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs
+
+From: Sean V Kelley <skelley@nvidia.com>
+
+[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all
+possible CPUs. In acpi_get_psd_map(), encountering an offline CPU
+returns -EFAULT, causing cppc_cpufreq initialization to fail.
+
+This breaks systems booted with "nosmt" or "nosmt=force".
+
+Fix by using for_each_online_cpu() in both functions.
+
+Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests")
+Signed-off-by: Sean V Kelley <skelley@nvidia.com>
+Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index e66e20d1f31b7..b59b0100d03c5 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -362,7 +362,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
+ end:
+ if (cmd == CMD_WRITE) {
+ if (unlikely(ret)) {
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i);
+
+ if (!desc)
+@@ -524,7 +524,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data)
+ else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
+ cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ if (i == cpu)
+ continue;
+
+--
+2.51.0
+
--- /dev/null
+From 16e6728e45c0f7450486d6cb54ad7f7750f9efaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Feb 2026 00:14:52 +0800
+Subject: ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO
+
+From: Zhai Can <bczhc0@126.com>
+
+[ Upstream commit cd7ef20ba8c6e936dba133b4136537a8ada22976 ]
+
+On the THUNDEROBOT ZERO laptop, the second NVMe slot and the discrete
+NVIDIA GPU are both controlled by power-resource PXP. Due to the SSDT table
+bug (lack of reference), PXP will be shut dow as an "unused" power resource
+during initialization, making the NVMe slot #2 + NVIDIA both inaccessible.
+
+This issue was introduced by commit a1224f34d72a ("ACPI: PM: Check
+states of power resources during initialization"). Here are test
+results on the three consecutive commits:
+
+(bad again!) a1224f34d72a ACPI: PM: Check states of power resources during initialization
+(good) bc2836859643 ACPI: PM: Do not turn off power resources in unknown state
+(bad) 519d81956ee2 Linux 5.15-rc6
+
+On commit bc2836859643 ("ACPI: PM: Do not turn off power resources in
+unknown state") this was not an issue because the power resource state
+left UNKNOWN thus being ignored.
+
+See also commit 9b04d99788cf ("ACPI: PM: Do not turn of unused power
+resources on the Toshiba Click Mini") which is another almost identical
+case to this one.
+
+Fixes: a1224f34d72a ("ACPI: PM: Check states of power resources during initialization")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221087
+Signed-off-by: Zhai Can <bczhc0@126.com>
+Link: https://patch.msgid.link/20260214161452.2849346-1-bczhc0@126.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/power.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
+index 361a7721a6a87..7da5ae5594a72 100644
+--- a/drivers/acpi/power.c
++++ b/drivers/acpi/power.c
+@@ -1113,6 +1113,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
+ },
+ },
++ {
++ /*
++ * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power
++ * resource 'PXP' will be shut down on initialization, making
++ * the NVMe #2 and the NVIDIA dGPU both unavailable (they're
++ * both controlled by 'PXP').
++ */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"),
++ }
++
++ },
+ {}
+ };
+
+--
+2.51.0
+
--- /dev/null
+From b7dc5b1ba28ccb80d5a25de4bbdf12eabcee7922 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jan 2026 11:47:02 -0800
+Subject: apparmor: account for in_atomic removal in common_file_perm
+
+From: Ryan Lee <ryan.lee@canonical.com>
+
+[ Upstream commit 9b829c0aa96e9385b1e9a308d3eb054b95fbeda2 ]
+
+If we are not in an atomic context in common_file_perm, then we don't have
+to use the atomic versions, resulting in improved performance outside of
+atomic contexts.
+
+Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index 4e44bd5bf1d91..5fc99fe8d38a4 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -523,15 +523,14 @@ static int common_file_perm(const char *op, struct file *file, u32 mask)
+ {
+ struct aa_label *label;
+ int error = 0;
+- bool needput;
+
+ /* don't reaudit files closed during inheritance */
+ if (unlikely(file->f_path.dentry == aa_null.dentry))
+ return -EACCES;
+
+- label = __begin_current_label_crit_section(&needput);
++ label = begin_current_label_crit_section();
+ error = aa_file_perm(op, current_cred(), label, file, mask, false);
+- __end_current_label_crit_section(label, needput);
++ end_current_label_crit_section(label);
+
+ return error;
+ }
+--
+2.51.0
+
--- /dev/null
+From 81990ddea20e9ae7031e67c9154b243ca9044a1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:11:07 +0100
+Subject: AppArmor: Allow apparmor to handle unaligned dfa tables
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Helge Deller <deller@kernel.org>
+
+[ Upstream commit 64802f731214a51dfe3c6c27636b3ddafd003eb0 ]
+
+The dfa tables can originate from kernel or userspace and 8-byte alignment
+isn't always guaranteed and as such may trigger unaligned memory accesses
+on various architectures. Resulting in the following
+
+[Â Â 73.901376] WARNING: CPU: 0 PID: 341 at security/apparmor/match.c:316 aa_dfa_unpack+0x6cc/0x720
+[Â Â 74.015867] Modules linked in: binfmt_misc evdev flash sg drm drm_panel_orientation_quirks backlight i2c_core configfs nfnetlink autofs4 ext4 crc16 mbcache jbd2 hid_generic usbhid sr_mod hid cdrom
+sd_mod ata_generic ohci_pci ehci_pci ehci_hcd ohci_hcd pata_ali libata sym53c8xx scsi_transport_spi tg3 scsi_mod usbcore libphy scsi_common mdio_bus usb_common
+[Â Â 74.428977] CPU: 0 UID: 0 PID: 341 Comm: apparmor_parser Not tainted 6.18.0-rc6+ #9 NONE
+[Â Â 74.536543] Call Trace:
+[Â Â 74.568561] [<0000000000434c24>] dump_stack+0x8/0x18
+[Â Â 74.633757] [<0000000000476438>] __warn+0xd8/0x100
+[Â Â 74.696664] [<00000000004296d4>] warn_slowpath_fmt+0x34/0x74
+[Â Â 74.771006] [<00000000008db28c>] aa_dfa_unpack+0x6cc/0x720
+[Â Â 74.843062] [<00000000008e643c>] unpack_pdb+0xbc/0x7e0
+[Â Â 74.910545] [<00000000008e7740>] unpack_profile+0xbe0/0x1300
+[Â Â 74.984888] [<00000000008e82e0>] aa_unpack+0xe0/0x6a0
+[Â Â 75.051226] [<00000000008e3ec4>] aa_replace_profiles+0x64/0x1160
+[Â Â 75.130144] [<00000000008d4d90>] policy_update+0xf0/0x280
+[Â Â 75.201057] [<00000000008d4fc8>] profile_replace+0xa8/0x100
+[Â Â 75.274258] [<0000000000766bd0>] vfs_write+0x90/0x420
+[Â Â 75.340594] [<00000000007670cc>] ksys_write+0x4c/0xe0
+[Â Â 75.406932] [<0000000000767174>] sys_write+0x14/0x40
+[Â Â 75.472126] [<0000000000406174>] linux_sparc_syscall+0x34/0x44
+[Â Â 75.548802] ---[ end trace 0000000000000000 ]---
+[Â Â 75.609503] dfa blob stream 0xfff0000008926b96 not aligned.
+[Â Â 75.682695] Kernel unaligned access at TPC[8db2a8] aa_dfa_unpack+0x6e8/0x720
+
+Work around it by using the get_unaligned_xx() helpers.
+
+Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack")
+Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+Closes: https://github.com/sparclinux/issues/issues/30
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/match.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/security/apparmor/match.c b/security/apparmor/match.c
+index c5a91600842a1..26e82ba879d44 100644
+--- a/security/apparmor/match.c
++++ b/security/apparmor/match.c
+@@ -15,6 +15,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/err.h>
+ #include <linux/kref.h>
++#include <linux/unaligned.h>
+
+ #include "include/lib.h"
+ #include "include/match.h"
+@@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
+ /* loaded td_id's start at 1, subtract 1 now to avoid doing
+ * it every time we use td_id as an index
+ */
+- th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
++ th.td_id = get_unaligned_be16(blob) - 1;
+ if (th.td_id > YYTD_ID_MAX)
+ goto out;
+- th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
+- th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
++ th.td_flags = get_unaligned_be16(blob + 2);
++ th.td_lolen = get_unaligned_be32(blob + 8);
+ blob += sizeof(struct table_header);
+
+ if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
+@@ -313,14 +314,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
+ if (size < sizeof(struct table_set_header))
+ goto fail;
+
+- if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
++ if (get_unaligned_be32(data) != YYTH_MAGIC)
+ goto fail;
+
+- hsize = ntohl(*(__be32 *) (data + 4));
++ hsize = get_unaligned_be32(data + 4);
+ if (size < hsize)
+ goto fail;
+
+- dfa->flags = ntohs(*(__be16 *) (data + 12));
++ dfa->flags = get_unaligned_be16(data + 12);
+ if (dfa->flags & ~(YYTH_FLAGS))
+ goto fail;
+
+@@ -329,7 +330,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
+ * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
+ * if (hsize < 16 + 4)
+ * goto fail;
+- * dfa->max_oob = ntol(*(__be32 *) (data + 16));
++ * dfa->max_oob = get_unaligned_be32(data + 16);
+ * if (dfa->max <= MAX_OOB_SUPPORTED) {
+ * pr_err("AppArmor DFA OOB greater than supported\n");
+ * goto fail;
+--
+2.51.0
+
--- /dev/null
+From 93e3eb98d7b22d429f53aac02dd90de32fd32663 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jan 2026 19:03:07 -0500
+Subject: apparmor: avoid per-cpu hold underflow in aa_get_buffer
+
+From: Zhengmian Hu <huzhengmian@gmail.com>
+
+[ Upstream commit 640cf2f09575c9dc344b3f7be2498d31e3923ead ]
+
+When aa_get_buffer() pulls from the per-cpu list it unconditionally
+decrements cache->hold. If hold reaches 0 while count is still non-zero,
+the unsigned decrement wraps to UINT_MAX. This keeps hold non-zero for a
+very long time, so aa_put_buffer() never returns buffers to the global
+list, which can starve other CPUs and force repeated kmalloc(aa_g_path_max)
+allocations.
+
+Guard the decrement so hold never underflows.
+Fixes: ea9bae12d028 ("apparmor: cache buffers on percpu list if there is lock contention")
+
+Signed-off-by: Zhengmian Hu <huzhengmian@gmail.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index be3678d08ed23..13c9bfdf65ff5 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -2136,7 +2136,8 @@ char *aa_get_buffer(bool in_atomic)
+ if (!list_empty(&cache->head)) {
+ aa_buf = list_first_entry(&cache->head, union aa_buffer, list);
+ list_del(&aa_buf->list);
+- cache->hold--;
++ if (cache->hold)
++ cache->hold--;
+ cache->count--;
+ put_cpu_ptr(&aa_local_buffers);
+ return &aa_buf->buffer[0];
+--
+2.51.0
+
--- /dev/null
+From a17e93d7177534497989d09964775ce3a8810144 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jan 2026 23:40:03 -0800
+Subject: apparmor: drop in_atomic flag in common_mmap, and common_file_perm
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit c3f27ccdb2dce3f0f2814574d06017f46c11fa29 ]
+
+with the previous changes to mmap the in_atomic flag is now always
+false, so drop it.
+
+Suggested-by: Tyler Hicks <code@tyhicks.com>
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 21 +++++++++------------
+ 1 file changed, 9 insertions(+), 12 deletions(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index b02c6c8951cd6..4e44bd5bf1d91 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -519,8 +519,7 @@ static void apparmor_file_free_security(struct file *file)
+ aa_put_label(rcu_access_pointer(ctx->label));
+ }
+
+-static int common_file_perm(const char *op, struct file *file, u32 mask,
+- bool in_atomic)
++static int common_file_perm(const char *op, struct file *file, u32 mask)
+ {
+ struct aa_label *label;
+ int error = 0;
+@@ -531,7 +530,7 @@ static int common_file_perm(const char *op, struct file *file, u32 mask,
+ return -EACCES;
+
+ label = __begin_current_label_crit_section(&needput);
+- error = aa_file_perm(op, current_cred(), label, file, mask, in_atomic);
++ error = aa_file_perm(op, current_cred(), label, file, mask, false);
+ __end_current_label_crit_section(label, needput);
+
+ return error;
+@@ -539,13 +538,12 @@ static int common_file_perm(const char *op, struct file *file, u32 mask,
+
+ static int apparmor_file_receive(struct file *file)
+ {
+- return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file),
+- false);
++ return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file));
+ }
+
+ static int apparmor_file_permission(struct file *file, int mask)
+ {
+- return common_file_perm(OP_FPERM, file, mask, false);
++ return common_file_perm(OP_FPERM, file, mask);
+ }
+
+ static int apparmor_file_lock(struct file *file, unsigned int cmd)
+@@ -555,11 +553,11 @@ static int apparmor_file_lock(struct file *file, unsigned int cmd)
+ if (cmd == F_WRLCK)
+ mask |= MAY_WRITE;
+
+- return common_file_perm(OP_FLOCK, file, mask, false);
++ return common_file_perm(OP_FLOCK, file, mask);
+ }
+
+ static int common_mmap(const char *op, struct file *file, unsigned long prot,
+- unsigned long flags, bool in_atomic)
++ unsigned long flags)
+ {
+ int mask = 0;
+
+@@ -577,21 +575,20 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot,
+ if (prot & PROT_EXEC)
+ mask |= AA_EXEC_MMAP;
+
+- return common_file_perm(op, file, mask, in_atomic);
++ return common_file_perm(op, file, mask);
+ }
+
+ static int apparmor_mmap_file(struct file *file, unsigned long reqprot,
+ unsigned long prot, unsigned long flags)
+ {
+- return common_mmap(OP_FMMAP, file, prot, flags, false);
++ return common_mmap(OP_FMMAP, file, prot, flags);
+ }
+
+ static int apparmor_file_mprotect(struct vm_area_struct *vma,
+ unsigned long reqprot, unsigned long prot)
+ {
+ return common_mmap(OP_FMPROT, vma->vm_file, prot,
+- !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0,
+- false);
++ !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
+ }
+
+ #ifdef CONFIG_IO_URING
+--
+2.51.0
+
--- /dev/null
+From f980f740bc58df84fb3aba8bd8c7d97d407dc0aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 04:12:02 -0800
+Subject: apparmor: fix aa_label to return state from compount and component
+ match
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 9058798652c8bc0584ed1fb0766a1015046c06e8 ]
+
+aa-label_match is not correctly returning the state in all cases.
+The only reason this didn't cause a error is that all callers currently
+ignore the return value.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202602020631.wXgZosyU-lkp@intel.com/
+Fixes: a4c9efa4dbad6 ("apparmor: make label_match return a consistent value")
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 1d3fa5c28d97f..dd6c58f595ba8 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1334,7 +1334,7 @@ static int label_compound_match(struct aa_profile *profile,
+ * @request: permissions to request
+ * @perms: an initialized perms struct to add accumulation to
+ *
+- * Returns: 0 on success else ERROR
++ * Returns: the state the match finished in, may be the none matching state
+ *
+ * For the label A//&B//&C this does the perm match for each of A and B and C
+ * @perms should be preinitialized with allperms OR a previous permission
+@@ -1362,7 +1362,7 @@ static int label_components_match(struct aa_profile *profile,
+ }
+
+ /* no subcomponents visible - no change in perms */
+- return 0;
++ return state;
+
+ next:
+ tmp = *aa_lookup_perms(rules->policy, state);
+@@ -1378,13 +1378,13 @@ static int label_components_match(struct aa_profile *profile,
+ }
+
+ if ((perms->allow & request) != request)
+- return -EACCES;
++ return DFA_NOMATCH;
+
+- return 0;
++ return state;
+
+ fail:
+ *perms = nullperms;
+- return -EACCES;
++ return DFA_NOMATCH;
+ }
+
+ /**
+@@ -1406,7 +1406,7 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns,
+ request, perms);
+ if ((perms->allow & request) == request)
+- return 0;
++ return tmp;
+
+ /* failed compound_match try component matches */
+ *perms = allperms;
+--
+2.51.0
+
--- /dev/null
+From 28d7f2b9241cd7084ce1a1294a59c6366b152c68 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jan 2026 11:48:54 -0800
+Subject: apparmor: fix boolean argument in apparmor_mmap_file
+
+From: Ryan Lee <ryan.lee@canonical.com>
+
+[ Upstream commit 48d5268e911abcf7674ec33c9b0b3e952be1175e ]
+
+The previous value of GFP_ATOMIC is an int and not a bool, potentially
+resulting in UB when being assigned to a bool. In addition, the mmap hook
+is called outside of locks (i.e. in a non-atomic context), so we can pass
+a fixed constant value of false instead to common_mmap.
+
+Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index b3f7a3258a2cf..b02c6c8951cd6 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -583,7 +583,7 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot,
+ static int apparmor_mmap_file(struct file *file, unsigned long reqprot,
+ unsigned long prot, unsigned long flags)
+ {
+- return common_mmap(OP_FMMAP, file, prot, flags, GFP_ATOMIC);
++ return common_mmap(OP_FMMAP, file, prot, flags, false);
+ }
+
+ static int apparmor_file_mprotect(struct vm_area_struct *vma,
+--
+2.51.0
+
--- /dev/null
+From 39754f2e1d194ddaef2934efa36e1af28ab6363b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 15:58:45 -0300
+Subject: apparmor: fix invalid deref of rawdata when export_binary is unset
+
+From: Georgia Garcia <georgia.garcia@canonical.com>
+
+[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ]
+
+If the export_binary parameter is disabled on runtime, profiles that
+were loaded before that will still have their rawdata stored in
+apparmorfs, with a symbolic link to the rawdata on the policy
+directory. When one of those profiles are replaced, the rawdata is set
+to NULL, but when trying to resolve the symbolic links to rawdata for
+that profile, it will try to dereference profile->rawdata->name when
+profile->rawdata is now NULL causing an oops. Fix it by checking if
+rawdata is set.
+
+[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088
+[ 168.657420] #PF: supervisor read access in kernel mode
+[ 168.660619] #PF: error_code(0x0000) - not-present page
+[ 168.663613] PGD 0 P4D 0
+[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI
+[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary)
+[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330
+[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8
+[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282
+[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158
+[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80
+[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000
+[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80
+[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0
+[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000
+[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0
+[ 168.701696] Call Trace:
+[ 168.702325] <TASK>
+[ 168.702995] rawdata_get_link_data+0x1c/0x30
+[ 168.704145] vfs_readlink+0xd4/0x160
+[ 168.705152] do_readlinkat+0x114/0x180
+[ 168.706214] __x64_sys_readlink+0x1e/0x30
+[ 168.708653] x64_sys_call+0x1d77/0x26b0
+[ 168.709525] do_syscall_64+0x81/0x500
+[ 168.710348] ? do_statx+0x72/0xb0
+[ 168.711109] ? putname+0x3e/0x80
+[ 168.711845] ? __x64_sys_statx+0xb7/0x100
+[ 168.712711] ? x64_sys_call+0x10fc/0x26b0
+[ 168.713577] ? do_syscall_64+0xbf/0x500
+[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0
+[ 168.715404] ? irqentry_exit+0xb2/0x740
+[ 168.716359] ? exc_page_fault+0x90/0x1b0
+[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement")
+Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/apparmorfs.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index 391a586d0557f..7803b973b4c42 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -1639,6 +1639,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry,
+
+ label = aa_get_label_rcu(&proxy->label);
+ profile = labels_profile(label);
++
++ /* rawdata can be null when aa_g_export_binary is unset during
++ * runtime and a profile is replaced
++ */
++ if (!profile->rawdata) {
++ aa_put_label(label);
++ return ERR_PTR(-ENOENT);
++ }
++
+ depth = profile_depth(profile);
+ target = gen_symlink_name(depth, profile->rawdata->name, name);
+ aa_put_label(label);
+--
+2.51.0
+
--- /dev/null
+From 6ca8f1cd024a58c1855efb33d12332dc121bf30e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Oct 2025 16:35:00 +0000
+Subject: apparmor: fix NULL pointer dereference in __unix_needs_revalidation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: System Administrator <root@localhost>
+
+[ Upstream commit e2938ad00b21340c0362562dfedd7cfec0554d67 ]
+
+When receiving file descriptors via SCM_RIGHTS, both the socket pointer
+and the socket's sk pointer can be NULL during socket setup or teardown,
+causing NULL pointer dereferences in __unix_needs_revalidation().
+
+This is a regression in AppArmor 5.0.0 (kernel 6.17+) where the new
+__unix_needs_revalidation() function was added without proper NULL checks.
+
+The crash manifests as:
+ BUG: kernel NULL pointer dereference, address: 0x0000000000000018
+ RIP: aa_file_perm+0xb7/0x3b0 (or +0xbe/0x3b0, +0xc0/0x3e0)
+ Call Trace:
+ apparmor_file_receive+0x42/0x80
+ security_file_receive+0x2e/0x50
+ receive_fd+0x1d/0xf0
+ scm_detach_fds+0xad/0x1c0
+
+The function dereferences sock->sk->sk_family without checking if either
+sock or sock->sk is NULL first.
+
+Add NULL checks for both sock and sock->sk before accessing sk_family.
+
+Fixes: 88fec3526e841 ("apparmor: make sure unix socket labeling is correctly updated.")
+Reported-by: Jamin Mc <jaminmc@gmail.com>
+Closes: https://bugzilla.proxmox.com/show_bug.cgi?id=7083
+Closes: https://gitlab.com/apparmor/apparmor/-/issues/568
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+Signed-off-by: System Administrator <root@localhost>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/file.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
+index c758204028780..919dbbbc87ab6 100644
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -578,6 +578,9 @@ static bool __unix_needs_revalidation(struct file *file, struct aa_label *label,
+ return false;
+ if (request & NET_PEER_MASK)
+ return false;
++ /* sock and sock->sk can be NULL for sockets being set up or torn down */
++ if (!sock || !sock->sk)
++ return false;
+ if (sock->sk->sk_family == PF_UNIX) {
+ struct aa_sk_ctx *ctx = aa_sock(sock->sk);
+
+--
+2.51.0
+
--- /dev/null
+From bc58740ab87fc6aedfae2f5119cff0a5ecac37ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 15:07:42 -0800
+Subject: apparmor: fix NULL sock in aa_sock_file_perm
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ]
+
+Deal with the potential that sock and sock-sk can be NULL during
+socket setup or teardown. This could lead to an oops. The fix for NULL
+pointer dereference in __unix_needs_revalidation shows this is at
+least possible for af_unix sockets. While the fix for af_unix sockets
+applies for newer mediation this is still the fall back path for older
+af_unix mediation and other sockets, so ensure it is covered.
+
+Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/net.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index 45cf25605c345..44c04102062f3 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -326,8 +326,10 @@ int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label,
+ struct socket *sock = (struct socket *) file->private_data;
+
+ AA_BUG(!label);
+- AA_BUG(!sock);
+- AA_BUG(!sock->sk);
++
++ /* sock && sock->sk can be NULL for sockets being set up or torn down */
++ if (!sock || !sock->sk)
++ return 0;
+
+ if (sock->sk->sk_family == PF_UNIX)
+ return aa_unix_file_perm(subj_cred, label, op, request, file);
+--
+2.51.0
+
--- /dev/null
+From bf90f4a6c7be30d9e17de847a880b88144fd4cc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 21:15:04 +0100
+Subject: apparmor: Fix & Optimize table creation from possibly unaligned
+ memory
+
+From: Helge Deller <deller@kernel.org>
+
+[ Upstream commit 6fc367bfd4c8886e6b1742aabbd1c0bdc310db3a ]
+
+Source blob may come from userspace and might be unaligned.
+Try to optize the copying process by avoiding unaligned memory accesses.
+
+- Added Fixes tag
+- Added "Fix &" to description as this doesn't just optimize but fixes
+ a potential unaligned memory access
+Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack")
+Signed-off-by: Helge Deller <deller@gmx.de>
+[jj: remove duplicate word "convert" in comment trigger checkpatch warning]
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/include/match.h | 12 +++++++-----
+ security/apparmor/match.c | 7 +++----
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
+index 1fbe82f5021b1..0dde8eda3d1a5 100644
+--- a/security/apparmor/include/match.h
++++ b/security/apparmor/include/match.h
+@@ -104,16 +104,18 @@ struct aa_dfa {
+ struct table_header *tables[YYTD_ID_TSIZE];
+ };
+
+-#define byte_to_byte(X) (X)
+-
+ #define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX) \
+ do { \
+ typeof(LEN) __i; \
+ TTYPE *__t = (TTYPE *) TABLE; \
+ BTYPE *__b = (BTYPE *) BLOB; \
+- for (__i = 0; __i < LEN; __i++) { \
+- __t[__i] = NTOHX(__b[__i]); \
+- } \
++ BUILD_BUG_ON(sizeof(TTYPE) != sizeof(BTYPE)); \
++ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) \
++ memcpy(__t, __b, (LEN) * sizeof(BTYPE)); \
++ else /* copy & convert from big-endian */ \
++ for (__i = 0; __i < LEN; __i++) { \
++ __t[__i] = NTOHX(&__b[__i]); \
++ } \
+ } while (0)
+
+ static inline size_t table_size(size_t len, size_t el_size)
+diff --git a/security/apparmor/match.c b/security/apparmor/match.c
+index 26e82ba879d44..bbeb3be68572f 100644
+--- a/security/apparmor/match.c
++++ b/security/apparmor/match.c
+@@ -67,14 +67,13 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
+ table->td_flags = th.td_flags;
+ table->td_lolen = th.td_lolen;
+ if (th.td_flags == YYTD_DATA8)
+- UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+- u8, u8, byte_to_byte);
++ memcpy(table->td_data, blob, th.td_lolen);
+ else if (th.td_flags == YYTD_DATA16)
+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+- u16, __be16, be16_to_cpu);
++ u16, __be16, get_unaligned_be16);
+ else if (th.td_flags == YYTD_DATA32)
+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+- u32, __be32, be32_to_cpu);
++ u32, __be32, get_unaligned_be32);
+ else
+ goto fail;
+ /* if table was vmalloced make sure the page tables are synced
+--
+2.51.0
+
--- /dev/null
+From a92faeff75b9b95efb19f934a2d8a04b7e8fb45f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:16:54 -0800
+Subject: apparmor: fix rlimit for posix cpu timers
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ]
+
+Posix cpu timers requires an additional step beyond setting the rlimit.
+Refactor the code so its clear when what code is setting the
+limit and conditionally update the posix cpu timers when appropriate.
+
+Fixes: baa73d9e478ff ("posix-timers: Make them configurable")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/resource.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index 8e80db3ae21c0..64212b39ba4bb 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -196,6 +196,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
+ rules->rlimits.limits[j].rlim_max);
+ /* soft limit should not exceed hard limit */
+ rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
++ if (j == RLIMIT_CPU &&
++ rlim->rlim_cur != RLIM_INFINITY &&
++ IS_ENABLED(CONFIG_POSIX_TIMERS))
++ (void) update_rlimit_cpu(current->group_leader,
++ rlim->rlim_cur);
+ }
+ }
+ }
+--
+2.51.0
+
--- /dev/null
+From 1b50e53d14a5564ef310d834b10eb8a68e13c47a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Nov 2025 23:59:38 -0800
+Subject: apparmor: make label_match return a consistent value
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit a4c9efa4dbad6dacad6e8b274e30e814c8353097 ]
+
+compound match is inconsistent in returning a state or an integer error
+this is problemati if the error is ever used as a state in the state
+machine
+
+Fixes: f1bd904175e81 ("apparmor: add the base fns() for domain labels")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 02ee128f53d13..1d3fa5c28d97f 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1278,7 +1278,7 @@ static inline aa_state_t match_component(struct aa_profile *profile,
+ * @request: permissions to request
+ * @perms: perms struct to set
+ *
+- * Returns: 0 on success else ERROR
++ * Returns: state match stopped at or DFA_NOMATCH if aborted early
+ *
+ * For the label A//&B//&C this does the perm match for A//&B//&C
+ * @perms should be preinitialized with allperms OR a previous permission
+@@ -1305,7 +1305,7 @@ static int label_compound_match(struct aa_profile *profile,
+
+ /* no component visible */
+ *perms = allperms;
+- return 0;
++ return state;
+
+ next:
+ label_for_each_cont(i, label, tp) {
+@@ -1317,14 +1317,11 @@ static int label_compound_match(struct aa_profile *profile,
+ goto fail;
+ }
+ *perms = *aa_lookup_perms(rules->policy, state);
+- if ((perms->allow & request) != request)
+- return -EACCES;
+-
+- return 0;
++ return state;
+
+ fail:
+ *perms = nullperms;
+- return state;
++ return DFA_NOMATCH;
+ }
+
+ /**
+@@ -1406,11 +1403,12 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+ struct aa_label *label, aa_state_t state, bool subns,
+ u32 request, struct aa_perms *perms)
+ {
+- int error = label_compound_match(profile, rules, label, state, subns,
+- request, perms);
+- if (!error)
+- return error;
++ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns,
++ request, perms);
++ if ((perms->allow & request) == request)
++ return 0;
+
++ /* failed compound_match try component matches */
+ *perms = allperms;
+ return label_components_match(profile, rules, label, state, subns,
+ request, perms);
+--
+2.51.0
+
--- /dev/null
+From 20e659bd6f569bdd9cd1d48e83db5fd650ebb624 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Sep 2025 02:22:21 -0700
+Subject: apparmor: move check for aa_null file to cover all cases
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 4a134723f9f1ad2f3621566259db673350d19cb1 ]
+
+files with a dentry pointing aa_null.dentry where already rejected as
+part of file_inheritance. Unfortunately the check in
+common_file_perm() is insufficient to cover all cases causing
+unnecessary audit messages without the original files context.
+
+Eg.
+[ 442.886474] audit: type=1400 audit(1704822661.616:329): apparmor="DENIED" operation="file_inherit" class="file" namespace="root//lxd-juju-98527a-0_<var-snap-lxd-common-lxd>" profile="snap.lxd.activate" name="/apparmor/.null" pid=9525 comm="snap-exec"
+
+Further examples of this are in the logs of
+https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2120439
+https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1952084
+https://bugs.launchpad.net/snapd/+bug/2049099
+
+These messages have no value and should not be sent to the logs.
+AppArmor was already filtering the out in some cases but the original
+patch did not catch all cases. Fix this by push the existing check
+down into two functions that should cover all cases.
+
+Link: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2122743
+Fixes: 192ca6b55a86 ("apparmor: revalidate files during exec")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/file.c | 12 ++++++++++--
+ security/apparmor/lsm.c | 4 ----
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
+index 919dbbbc87ab6..7de23e85cd5d0 100644
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -154,8 +154,12 @@ static int path_name(const char *op, const struct cred *subj_cred,
+ const char *info = NULL;
+ int error;
+
+- error = aa_path_name(path, flags, buffer, name, &info,
+- labels_profile(label)->disconnected);
++ /* don't reaudit files closed during inheritance */
++ if (unlikely(path->dentry == aa_null.dentry))
++ error = -EACCES;
++ else
++ error = aa_path_name(path, flags, buffer, name, &info,
++ labels_profile(label)->disconnected);
+ if (error) {
+ fn_for_each_confined(label, profile,
+ aa_audit_file(subj_cred,
+@@ -616,6 +620,10 @@ int aa_file_perm(const char *op, const struct cred *subj_cred,
+ AA_BUG(!label);
+ AA_BUG(!file);
+
++ /* don't reaudit files closed during inheritance */
++ if (unlikely(file->f_path.dentry == aa_null.dentry))
++ return -EACCES;
++
+ fctx = file_ctx(file);
+
+ rcu_read_lock();
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index 5fc99fe8d38a4..be3678d08ed23 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -524,10 +524,6 @@ static int common_file_perm(const char *op, struct file *file, u32 mask)
+ struct aa_label *label;
+ int error = 0;
+
+- /* don't reaudit files closed during inheritance */
+- if (unlikely(file->f_path.dentry == aa_null.dentry))
+- return -EACCES;
+-
+ label = begin_current_label_crit_section();
+ error = aa_file_perm(op, current_cred(), label, file, mask, false);
+ end_current_label_crit_section(label);
+--
+2.51.0
+
--- /dev/null
+From ed9f1c4d636efa6eaa38a7b2ae2f39777467312a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Nov 2025 00:14:36 -0800
+Subject: apparmor: remove apply_modes_to_perms from label_match
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit b2e27be2948f2f8c38421cd554b5fc9383215648 ]
+
+The modes shouldn't be applied at the point of label match, it just
+results in them being applied multiple times. Instead they should be
+applied after which is already being done by all callers so it can
+just be dropped from label_match.
+
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 913678f199c35..02ee128f53d13 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1317,7 +1317,6 @@ static int label_compound_match(struct aa_profile *profile,
+ goto fail;
+ }
+ *perms = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, perms);
+ if ((perms->allow & request) != request)
+ return -EACCES;
+
+@@ -1370,7 +1369,6 @@ static int label_components_match(struct aa_profile *profile,
+
+ next:
+ tmp = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ label_for_each_cont(i, label, tp) {
+ if (!aa_ns_visible(profile->ns, tp->ns, subns))
+@@ -1379,7 +1377,6 @@ static int label_components_match(struct aa_profile *profile,
+ if (!state)
+ goto fail;
+ tmp = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From b16b1469afccd64d710e1b2b75d34ad0d3d9e3c0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jan 2026 09:35:57 -0800
+Subject: apparmor: return -ENOMEM in unpack_perms_table upon alloc failure
+
+From: Ryan Lee <ryan.lee@canonical.com>
+
+[ Upstream commit 74b7105e53e80a4072bd3e1a50be7aa15e3f0a01 ]
+
+In policy_unpack.c:unpack_perms_table, the perms struct is allocated via
+kcalloc, with the position being reset if the allocation fails. However,
+the error path results in -EPROTO being retured instead of -ENOMEM. Fix
+this to return the correct error code.
+
+Reported-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
+Fixes: fd1b2b95a2117 ("apparmor: add the ability for policy to specify a permission table")
+Reviewed-by: Tyler Hicks <code@tyhicks.com>
+Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy_unpack.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index 7523971e37d9c..dd602bd5fca99 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -687,8 +687,10 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms)
+ if (!aa_unpack_array(e, NULL, &size))
+ goto fail_reset;
+ *perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL);
+- if (!*perms)
+- goto fail_reset;
++ if (!*perms) {
++ e->pos = pos;
++ return -ENOMEM;
++ }
+ for (i = 0; i < size; i++) {
+ if (!unpack_perm(e, version, &(*perms)[i]))
+ goto fail;
+--
+2.51.0
+
--- /dev/null
+From f254d058b5b26383e30693f57ee5dba2a6484043 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 11:27:32 +0100
+Subject: ASoC: codecs: aw88261: Fix erroneous bitmask logic in Awinic init
+
+From: Alexandre Ferrieux <alexandre.ferrieux@orange.com>
+
+[ Upstream commit b82fa9b0c26eeb2fde6017f7de2c3c544484efef ]
+
+The aw88261_dev_reg_update() function sets the Awinic registers in a
+rather nonuniform way:
+ - most registers get directly overwritten from the firmware blob
+ - but a handful of them need more delicate logic to preserve
+ some bits from their current value, according to a register-
+ specific mask
+For the latter, the logic is basically
+ NEW = (OLD & MASK) | (VAL & ~MASK)
+However, the ~MASK value is hand-computed, and in the specific case
+of the SYSCTRL register, in a buggy way.
+This patch restores the proper ~MASK value.
+
+Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver")
+Signed-off-by: Alexandre Ferrieux <alexandre.ferrieux@orange.com>
+Link: https://patch.msgid.link/20260211-aw88261-fwname-v1-1-e24e833a019d@fairphone.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/aw88261.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c
+index de11ae8dd9d9f..124c0a58d08bd 100644
+--- a/sound/soc/codecs/aw88261.c
++++ b/sound/soc/codecs/aw88261.c
+@@ -423,9 +423,10 @@ static int aw88261_dev_reg_update(struct aw88261 *aw88261,
+ if (ret)
+ break;
+
++ /* keep all three bits from current hw status */
+ read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) |
+ (~AW88261_HMUTE_MASK);
+- reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK);
++ reg_val &= (AW88261_AMPPD_MASK & AW88261_PWDN_MASK & AW88261_HMUTE_MASK);
+ reg_val |= read_val;
+
+ /* enable uls hmute */
+--
+2.51.0
+
--- /dev/null
+From cb05e8172a788cbde295e6db7b66615c1704d8d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 18:57:14 +0000
+Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ]
+
+This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()").
+
+The original patch attempted to acquire the card->controls_rwsem lock in
+fsl_xcvr_mode_put(). However, this function is called from the upper ALSA
+core function snd_ctl_elem_write(), which already holds the write lock on
+controls_rwsem for the whole put operation. So there is no need to simply
+hold the lock for fsl_xcvr_activate_ctl() again.
+
+Acquiring the read lock while holding the write lock in the same thread
+results in a deadlock and a hung task, as reported by Alexander Stein.
+
+Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()")
+Reported-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_xcvr.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
+index 51669e5fe8888..58db4906a01d5 100644
+--- a/sound/soc/fsl/fsl_xcvr.c
++++ b/sound/soc/fsl/fsl_xcvr.c
+@@ -223,13 +223,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,
+
+ xcvr->mode = snd_soc_enum_item_to_val(e, item[0]);
+
+- down_read(&card->snd_card->controls_rwsem);
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_ARC));
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_EARC));
+- up_read(&card->snd_card->controls_rwsem);
+-
+ /* Allow playback for SPDIF only */
+ rtd = snd_soc_get_pcm_runtime(card, card->dai_link);
+ rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
+--
+2.51.0
+
--- /dev/null
+From 4ee1d79222c9696a8af0f94abe85db94e905be2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 15:18:34 -0500
+Subject: ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk
+
+From: Detlev Casanova <detlev.casanova@collabora.com>
+
+[ Upstream commit 0783052534f547f8f201dd4554b1df9f1f8615b5 ]
+
+Drivers will not always call set_sysclk() for all clocks, especially when
+default mclk-fs can be used.
+When that is the case, use the clock rate set in the params multiplied by the
+default mclk-fs.
+
+Fixes: 5323186e2e8d ("ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback")
+Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
+Reported-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Link: https://patch.msgid.link/20260218201834.924358-1-detlev.casanova@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/rockchip/rockchip_i2s_tdm.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
+index d9a1fab7f4031..e4697ee0addc8 100644
+--- a/sound/soc/rockchip/rockchip_i2s_tdm.c
++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
+@@ -22,6 +22,7 @@
+
+ #define DRV_NAME "rockchip-i2s-tdm"
+
++#define DEFAULT_MCLK_FS 256
+ #define CH_GRP_MAX 4 /* The max channel 8 / 2 */
+ #define MULTIPLEX_CH_MAX 10
+
+@@ -665,6 +666,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
+ mclk_rate = i2s_tdm->mclk_rx_freq;
+ }
+
++ /*
++ * When the dai/component driver doesn't need to set mclk-fs for a specific
++ * clock, it can skip the call to set_sysclk() for that clock.
++ * In that case, simply use the clock rate from the params and multiply it by
++ * the default mclk-fs value.
++ */
++ if (!mclk_rate)
++ mclk_rate = DEFAULT_MCLK_FS * params_rate(params);
++
+ err = clk_set_rate(mclk, mclk_rate);
+ if (err)
+ return err;
+--
+2.51.0
+
--- /dev/null
+From 9af36c5903f6075496fadfeac7bbd8a0077bee88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 10:57:55 +0530
+Subject: bnge: fix reserving resources from FW
+
+From: Vikas Gupta <vikas.gupta@broadcom.com>
+
+[ Upstream commit 604530085b2ef484843c723a105b6fd3218b4710 ]
+
+HWRM_FUNC_CFG is used to reserve resources, whereas HWRM_FUNC_QCFG is
+intended for querying resource information from the firmware.
+Since __bnge_hwrm_reserve_pf_rings() reserves resources for a specific
+PF, the command type should be HWRM_FUNC_CFG.
+
+Fixes: 627c67f038d2 ("bng_en: Add resource management support")
+Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
+Reviewed-by: Bhargava Chenna Marreddy <bhargava.marreddy@broadcom.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260218052755.4097468-1-vikas.gupta@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
+index 198f49b40dbf0..2994f10446a63 100644
+--- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
++++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
+@@ -442,7 +442,7 @@ __bnge_hwrm_reserve_pf_rings(struct bnge_dev *bd, struct bnge_hw_rings *hwr)
+ struct hwrm_func_cfg_input *req;
+ u32 enables = 0;
+
+- if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_QCFG))
++ if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_CFG))
+ return NULL;
+
+ req->fid = cpu_to_le16(0xffff);
+--
+2.51.0
+
--- /dev/null
+From 13e72c57b9ae043426daa0a565601ef99ab42b8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 06:09:19 +0000
+Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ]
+
+The ALB RX path may access rx_hashtbl concurrently with bond
+teardown. During rapid bond up/down cycles, rlb_deinitialize()
+frees rx_hashtbl while RX handlers are still running, leading
+to a null pointer dereference detected by KASAN.
+
+However, the root cause is that rlb_arp_recv() can still be accessed
+after setting recv_probe to NULL, which is actually a use-after-free
+(UAF) issue. That is the reason for using the referenced commit in the
+Fixes tag.
+
+[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI
+[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef]
+[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary)
+[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022
+[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding]
+[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6
+ 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00
+[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206
+[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e
+[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8
+[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8
+[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119
+[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810
+[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000
+[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0
+[ 214.310347] Call Trace:
+[ 214.313070] <IRQ>
+[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding]
+[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding]
+[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding]
+[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710
+[ 214.339199] ? __pfx_arp_process+0x10/0x10
+[ 214.343775] ? sched_balance_find_src_group+0x98/0x630
+[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10
+[ 214.356513] ? arp_rcv+0x307/0x690
+[ 214.360311] ? __pfx_arp_rcv+0x10/0x10
+[ 214.364499] ? __lock_acquire+0x58c/0xbd0
+[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0
+[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10
+[ 214.380743] ? lock_acquire+0x10b/0x140
+[ 214.385026] process_backlog+0x3f1/0x13a0
+[ 214.389502] ? process_backlog+0x3aa/0x13a0
+[ 214.394174] __napi_poll.constprop.0+0x9f/0x370
+[ 214.399233] net_rx_action+0x8c1/0xe60
+[ 214.403423] ? __pfx_net_rx_action+0x10/0x10
+[ 214.408193] ? lock_acquire.part.0+0xbd/0x260
+[ 214.413058] ? sched_clock_cpu+0x6c/0x540
+[ 214.417540] ? mark_held_locks+0x40/0x70
+[ 214.421920] handle_softirqs+0x1fd/0x860
+[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10
+[ 214.431264] ? __neigh_event_send+0x2d6/0xf50
+[ 214.436131] do_softirq+0xb1/0xf0
+[ 214.439830] </IRQ>
+
+The issue is reproducible by repeatedly running
+ip link set bond0 up/down while receiving ARP messages, where
+rlb_arp_recv() can race with rlb_deinitialize() and dereference
+a freed rx_hashtbl entry.
+
+Fix this by setting recv_probe to NULL and then calling
+synchronize_net() to wait for any concurrent RX processing to finish.
+This ensures that no RX handler can access rx_hashtbl after it is freed
+in bond_alb_deinitialize().
+
+Reported-by: Liang Li <liali@redhat.com>
+Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 166dff47a029f..dba8f68690947 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4405,9 +4405,13 @@ static int bond_close(struct net_device *bond_dev)
+
+ bond_work_cancel_all(bond);
+ bond->send_peer_notif = 0;
++ WRITE_ONCE(bond->recv_probe, NULL);
++
++ /* Wait for any in-flight RX handlers */
++ synchronize_net();
++
+ if (bond_is_lb(bond))
+ bond_alb_deinitialize(bond);
+- bond->recv_probe = NULL;
+
+ if (BOND_MODE(bond) == BOND_MODE_8023AD &&
+ bond->params.broadcast_neighbor)
+--
+2.51.0
+
--- /dev/null
+From b3866b06ee71c5a977553cbeccbb6559c569feac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 21:29:49 +0000
+Subject: bpf: Add a map/btf from a fd array more consistently
+
+From: Anton Protopopov <a.s.protopopov@gmail.com>
+
+[ Upstream commit b0b1a8583d8e797114e613139e3e3318a1704690 ]
+
+The add_fd_from_fd_array() function takes a file descriptor as a
+parameter and tries to add either map or btf to the corresponding
+list of used objects. As was reported by Dan Carpenter, since the
+commit c81e4322acf0 ("bpf: Fix a potential use-after-free of BTF
+object"), the fdget() is called twice on the file descriptor, and
+thus userspace, potentially, can replace the file pointed to by the
+file descriptor in between the two calls. On practice, this shouldn't
+break anything on the kernel side, but for consistency fix the code
+such that only one fdget() is executed.
+
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/r/aY689z7gHNv8rgVO@stanley.mountain/
+Fixes: ccd2d799ed44 ("bpf: Fix a potential use-after-free of BTF object")
+Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
+Link: https://lore.kernel.org/r/20260213212949.759321-1-a.s.protopopov@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index dade674ffe071..c4fa2268dbbc5 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -24098,9 +24098,11 @@ static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd)
+ return 0;
+ }
+
+- btf = btf_get_by_fd(fd);
+- if (!IS_ERR(btf))
++ btf = __btf_get_by_fd(f);
++ if (!IS_ERR(btf)) {
++ btf_get(btf);
+ return __add_used_btf(env, btf);
++ }
+
+ verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd);
+ return PTR_ERR(map);
+--
+2.51.0
+
--- /dev/null
+From d0c77135f8ab1167897cdaca3131cfb0c04d35a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 13:29:04 +0000
+Subject: bpf: Fix a potential use-after-free of BTF object
+
+From: Anton Protopopov <a.s.protopopov@gmail.com>
+
+[ Upstream commit ccd2d799ed4467c07f5ee18c2f5c59bcc990822c ]
+
+Refcounting in the check_pseudo_btf_id() function is incorrect:
+the __check_pseudo_btf_id() function might get called with a zero
+refcounted btf. Fix this, and patch related code accordingly.
+
+v3: rephrase a comment (AI)
+v2: fix a refcount leak introduced in v1 (AI)
+
+Reported-by: syzbot+5a0f1995634f7c1dadbf@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=5a0f1995634f7c1dadbf
+Fixes: 76145f725532 ("bpf: Refactor check_pseudo_btf_id")
+Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
+Link: https://lore.kernel.org/r/20260209132904.63908-1-a.s.protopopov@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 52 +++++++++++++++++++++----------------------
+ 1 file changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 4338d233beecf..dade674ffe071 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -20219,29 +20219,29 @@ static int find_btf_percpu_datasec(struct btf *btf)
+ }
+
+ /*
+- * Add btf to the used_btfs array and return the index. (If the btf was
+- * already added, then just return the index.) Upon successful insertion
+- * increase btf refcnt, and, if present, also refcount the corresponding
+- * kernel module.
++ * Add btf to the env->used_btfs array. If needed, refcount the
++ * corresponding kernel module. To simplify caller's logic
++ * in case of error or if btf was added before the function
++ * decreases the btf refcount.
+ */
+ static int __add_used_btf(struct bpf_verifier_env *env, struct btf *btf)
+ {
+ struct btf_mod_pair *btf_mod;
++ int ret = 0;
+ int i;
+
+ /* check whether we recorded this BTF (and maybe module) already */
+ for (i = 0; i < env->used_btf_cnt; i++)
+ if (env->used_btfs[i].btf == btf)
+- return i;
++ goto ret_put;
+
+ if (env->used_btf_cnt >= MAX_USED_BTFS) {
+ verbose(env, "The total number of btfs per program has reached the limit of %u\n",
+ MAX_USED_BTFS);
+- return -E2BIG;
++ ret = -E2BIG;
++ goto ret_put;
+ }
+
+- btf_get(btf);
+-
+ btf_mod = &env->used_btfs[env->used_btf_cnt];
+ btf_mod->btf = btf;
+ btf_mod->module = NULL;
+@@ -20250,12 +20250,18 @@ static int __add_used_btf(struct bpf_verifier_env *env, struct btf *btf)
+ if (btf_is_module(btf)) {
+ btf_mod->module = btf_try_get_module(btf);
+ if (!btf_mod->module) {
+- btf_put(btf);
+- return -ENXIO;
++ ret = -ENXIO;
++ goto ret_put;
+ }
+ }
+
+- return env->used_btf_cnt++;
++ env->used_btf_cnt++;
++ return 0;
++
++ret_put:
++ /* Either error or this BTF was already added */
++ btf_put(btf);
++ return ret;
+ }
+
+ /* replace pseudo btf_id with kernel symbol address */
+@@ -20352,9 +20358,7 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env,
+
+ btf_fd = insn[1].imm;
+ if (btf_fd) {
+- CLASS(fd, f)(btf_fd);
+-
+- btf = __btf_get_by_fd(f);
++ btf = btf_get_by_fd(btf_fd);
+ if (IS_ERR(btf)) {
+ verbose(env, "invalid module BTF object FD specified.\n");
+ return -EINVAL;
+@@ -20364,17 +20368,17 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env,
+ verbose(env, "kernel is missing BTF, make sure CONFIG_DEBUG_INFO_BTF=y is specified in Kconfig.\n");
+ return -EINVAL;
+ }
++ btf_get(btf_vmlinux);
+ btf = btf_vmlinux;
+ }
+
+ err = __check_pseudo_btf_id(env, insn, aux, btf);
+- if (err)
++ if (err) {
++ btf_put(btf);
+ return err;
++ }
+
+- err = __add_used_btf(env, btf);
+- if (err < 0)
+- return err;
+- return 0;
++ return __add_used_btf(env, btf);
+ }
+
+ static bool is_tracing_prog_type(enum bpf_prog_type type)
+@@ -24094,13 +24098,9 @@ static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd)
+ return 0;
+ }
+
+- btf = __btf_get_by_fd(f);
+- if (!IS_ERR(btf)) {
+- err = __add_used_btf(env, btf);
+- if (err < 0)
+- return err;
+- return 0;
+- }
++ btf = btf_get_by_fd(fd);
++ if (!IS_ERR(btf))
++ return __add_used_btf(env, btf);
+
+ verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd);
+ return PTR_ERR(map);
+--
+2.51.0
+
--- /dev/null
+From 278f42068573532ff42bf144a7a4bc43e14df680 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 11:41:50 -0800
+Subject: bpftool: Fix truncated netlink dumps
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ]
+
+Netlink requires that the recv buffer used during dumps is at least
+min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will
+get truncated. Make sure bpftool follows this requirement, avoid
+missing information on systems with large pages.
+
+Acked-by: Quentin Monnet <qmo@kernel.org>
+Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/net.c | 5 ++++-
+ tools/lib/bpf/netlink.c | 4 +++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c
+index cfc6f944f7c33..1a06b0b5eef35 100644
+--- a/tools/bpf/bpftool/net.c
++++ b/tools/bpf/bpftool/net.c
+@@ -156,7 +156,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ bool multipart = true;
+ struct nlmsgerr *err;
+ struct nlmsghdr *nh;
+- char buf[4096];
++ char buf[8192];
+ int len, ret;
+
+ while (multipart) {
+@@ -201,6 +201,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ return ret;
+ }
+ }
++
++ if (len)
++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len);
+ }
+ ret = 0;
+ done:
+diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
+index c997e69d507fe..c9a78fb16f115 100644
+--- a/tools/lib/bpf/netlink.c
++++ b/tools/lib/bpf/netlink.c
+@@ -143,7 +143,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ struct nlmsghdr *nh;
+ int len, ret;
+
+- ret = alloc_iov(&iov, 4096);
++ ret = alloc_iov(&iov, 8192);
+ if (ret)
+ goto done;
+
+@@ -212,6 +212,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ }
+ }
+ }
++ if (len)
++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len);
+ }
+ ret = 0;
+ done:
+--
+2.51.0
+
--- /dev/null
+From cfcb0e598ad8a283cef8cac60b5a5f2b2608b859 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 17:15:53 +0000
+Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not
+ found
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ]
+
+If btrfs_search_slot_for_read() returns 1, it means we did not find any
+key greater than or equals to the key we asked for, meaning we have
+reached the end of the tree and therefore the path is not valid. If
+this happens we need to break out of the loop and stop, instead of
+continuing and accessing an invalid path.
+
+Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/qgroup.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index 7a1dd250e92c0..302bb3ecf39a3 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1157,11 +1157,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info,
+ }
+ if (ret > 0) {
+ /*
+- * Shouldn't happen, but in case it does we
+- * don't need to do the btrfs_next_item, just
+- * continue.
++ * Shouldn't happen because the key should still
++ * be there (return 0), but in case it does it
++ * means we have reached the end of the tree -
++ * there are no more leaves with items that have
++ * a key greater than or equals to @found_key,
++ * so just stop the search loop.
+ */
+- continue;
++ break;
+ }
+ }
+ ret = btrfs_next_item(tree_root, path);
+--
+2.51.0
+
--- /dev/null
+From 9bab32c05aec361994be65021f40fbd57b907e65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Oct 2025 12:47:26 +0100
+Subject: btrfs: reduce block group critical section in
+ btrfs_free_reserved_bytes()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 8b6fa164ab59f9e3f24e627fe09a0234783e7a8b ]
+
+There's no need to update the space_info fields (bytes_reserved,
+max_extent_size, bytes_readonly, bytes_zone_unusable) while holding the
+block group's spinlock. So move those updates to happen after we unlock
+the block group (and while holding the space_info locked of course), so
+that all we do under the block group's critical section is to update the
+block group itself.
+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 5870ec7c8fe5 ("btrfs: reset block group size class when it becomes empty")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 035b04e7658d1..144868f02e2aa 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -3859,21 +3859,24 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache, u64 num_bytes,
+ bool is_delalloc)
+ {
+ struct btrfs_space_info *space_info = cache->space_info;
++ bool bg_ro;
+
+ spin_lock(&space_info->lock);
+ spin_lock(&cache->lock);
+- if (cache->ro)
++ bg_ro = cache->ro;
++ cache->reserved -= num_bytes;
++ if (is_delalloc)
++ cache->delalloc_bytes -= num_bytes;
++ spin_unlock(&cache->lock);
++
++ if (bg_ro)
+ space_info->bytes_readonly += num_bytes;
+ else if (btrfs_is_zoned(cache->fs_info))
+ space_info->bytes_zone_unusable += num_bytes;
+- cache->reserved -= num_bytes;
++
+ space_info->bytes_reserved -= num_bytes;
+ space_info->max_extent_size = 0;
+
+- if (is_delalloc)
+- cache->delalloc_bytes -= num_bytes;
+- spin_unlock(&cache->lock);
+-
+ btrfs_try_granting_tickets(space_info);
+ spin_unlock(&space_info->lock);
+ }
+--
+2.51.0
+
--- /dev/null
+From efa8f81ee52a4da3dd3b11063fc8ebb73b69c0e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Oct 2025 13:57:09 +0100
+Subject: btrfs: remove fs_info argument from btrfs_try_granting_tickets()
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit e3df6408b13a75cf73e543e53453f28261874c6f ]
+
+We don't need it since we can grab fs_info from the given space_info.
+So remove the fs_info argument.
+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Anand Jain <asj@kernel.org>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: 5870ec7c8fe5 ("btrfs: reset block group size class when it becomes empty")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.c | 4 ++--
+ fs/btrfs/block-rsv.c | 2 +-
+ fs/btrfs/space-info.c | 14 +++++++-------
+ fs/btrfs/space-info.h | 5 ++---
+ 4 files changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 8bf501fbcc0be..035b04e7658d1 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -3836,7 +3836,7 @@ int btrfs_add_reserved_bytes(struct btrfs_block_group *cache,
+ * that happens.
+ */
+ if (num_bytes < ram_bytes)
+- btrfs_try_granting_tickets(cache->fs_info, space_info);
++ btrfs_try_granting_tickets(space_info);
+ out:
+ spin_unlock(&cache->lock);
+ spin_unlock(&space_info->lock);
+@@ -3874,7 +3874,7 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache, u64 num_bytes,
+ cache->delalloc_bytes -= num_bytes;
+ spin_unlock(&cache->lock);
+
+- btrfs_try_granting_tickets(cache->fs_info, space_info);
++ btrfs_try_granting_tickets(space_info);
+ spin_unlock(&space_info->lock);
+ }
+
+diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c
+index 5ad6de738aee0..75cd35570a287 100644
+--- a/fs/btrfs/block-rsv.c
++++ b/fs/btrfs/block-rsv.c
+@@ -387,7 +387,7 @@ void btrfs_update_global_block_rsv(struct btrfs_fs_info *fs_info)
+ num_bytes = block_rsv->reserved - block_rsv->size;
+ btrfs_space_info_update_bytes_may_use(sinfo, -num_bytes);
+ block_rsv->reserved = block_rsv->size;
+- btrfs_try_granting_tickets(fs_info, sinfo);
++ btrfs_try_granting_tickets(sinfo);
+ }
+
+ block_rsv->full = (block_rsv->reserved == block_rsv->size);
+diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c
+index e5c18a29eb7e6..474ed47095ba7 100644
+--- a/fs/btrfs/space-info.c
++++ b/fs/btrfs/space-info.c
+@@ -378,7 +378,7 @@ void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info,
+ btrfs_space_info_update_bytes_zone_unusable(space_info, block_group->zone_unusable);
+ if (block_group->length > 0)
+ space_info->full = false;
+- btrfs_try_granting_tickets(info, space_info);
++ btrfs_try_granting_tickets(space_info);
+ spin_unlock(&space_info->lock);
+
+ block_group->space_info = space_info;
+@@ -528,9 +528,9 @@ static void remove_ticket(struct btrfs_space_info *space_info,
+ * This is for space we already have accounted in space_info->bytes_may_use, so
+ * basically when we're returning space from block_rsv's.
+ */
+-void btrfs_try_granting_tickets(struct btrfs_fs_info *fs_info,
+- struct btrfs_space_info *space_info)
++void btrfs_try_granting_tickets(struct btrfs_space_info *space_info)
+ {
++ struct btrfs_fs_info *fs_info = space_info->fs_info;
+ struct list_head *head;
+ enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_NO_FLUSH;
+
+@@ -1129,7 +1129,7 @@ static bool maybe_fail_all_tickets(struct btrfs_fs_info *fs_info,
+ * the list.
+ */
+ if (!aborted)
+- btrfs_try_granting_tickets(fs_info, space_info);
++ btrfs_try_granting_tickets(space_info);
+ }
+ return (tickets_id != space_info->tickets_id);
+ }
+@@ -1549,7 +1549,7 @@ static void priority_reclaim_metadata_space(struct btrfs_fs_info *fs_info,
+ * ticket in front of a smaller ticket that can now be satisfied with
+ * the available space.
+ */
+- btrfs_try_granting_tickets(fs_info, space_info);
++ btrfs_try_granting_tickets(space_info);
+ spin_unlock(&space_info->lock);
+ }
+
+@@ -1577,7 +1577,7 @@ static void priority_reclaim_data_space(struct btrfs_fs_info *fs_info,
+
+ ticket->error = -ENOSPC;
+ remove_ticket(space_info, ticket);
+- btrfs_try_granting_tickets(fs_info, space_info);
++ btrfs_try_granting_tickets(space_info);
+ spin_unlock(&space_info->lock);
+ }
+
+@@ -2200,5 +2200,5 @@ void btrfs_return_free_space(struct btrfs_space_info *space_info, u64 len)
+ grant:
+ /* Add to any tickets we may have. */
+ if (len)
+- btrfs_try_granting_tickets(fs_info, space_info);
++ btrfs_try_granting_tickets(space_info);
+ }
+diff --git a/fs/btrfs/space-info.h b/fs/btrfs/space-info.h
+index a846f63585c95..596a1e923ddfe 100644
+--- a/fs/btrfs/space-info.h
++++ b/fs/btrfs/space-info.h
+@@ -283,8 +283,7 @@ int btrfs_reserve_metadata_bytes(struct btrfs_fs_info *fs_info,
+ struct btrfs_space_info *space_info,
+ u64 orig_bytes,
+ enum btrfs_reserve_flush_enum flush);
+-void btrfs_try_granting_tickets(struct btrfs_fs_info *fs_info,
+- struct btrfs_space_info *space_info);
++void btrfs_try_granting_tickets(struct btrfs_space_info *space_info);
+ int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
+ const struct btrfs_space_info *space_info, u64 bytes,
+ enum btrfs_reserve_flush_enum flush);
+@@ -295,7 +294,7 @@ static inline void btrfs_space_info_free_bytes_may_use(
+ {
+ spin_lock(&space_info->lock);
+ btrfs_space_info_update_bytes_may_use(space_info, -num_bytes);
+- btrfs_try_granting_tickets(space_info->fs_info, space_info);
++ btrfs_try_granting_tickets(space_info);
+ spin_unlock(&space_info->lock);
+ }
+ int btrfs_reserve_data_bytes(struct btrfs_space_info *space_info, u64 bytes,
+--
+2.51.0
+
--- /dev/null
+From b1cb48fca8c9e3dd219aaabb9dd1abe23ca493b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jan 2026 01:13:38 +0000
+Subject: btrfs: reset block group size class when it becomes empty
+
+From: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+
+[ Upstream commit 5870ec7c8fe57a8b2c65005e5da5efc054faa3e6 ]
+
+Block group size classes are managed consistently everywhere.
+Currently, btrfs_use_block_group_size_class() sets a block group's size
+class to specialize it for a specific allocation size. However, this
+size class remains "stale" even if the block group becomes completely
+empty (both used and reserved bytes reach zero).
+
+This happens in two scenarios:
+
+1. When space reservations are freed (e.g., due to errors or transaction
+ aborts) via btrfs_free_reserved_bytes().
+2. When the last extent in a block group is freed via
+ btrfs_update_block_group().
+
+While size classes are advisory, a stale size class can cause
+find_free_extent to unnecessarily skip candidate block groups during
+initial search loops. This undermines the purpose of size classes to
+reduce fragmentation by keeping block groups restricted to a specific
+size class when they could be reused for any size.
+
+Fix this by resetting the size class to BTRFS_BG_SZ_NONE whenever a
+block group's used and reserved counts both reach zero. This ensures
+that empty block groups are fully available for any allocation size in
+the next cycle.
+
+Fixes: 52bb7a2166af ("btrfs: introduce size class to block group allocator")
+Reviewed-by: Boris Burkov <boris@bur.io>
+Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 144868f02e2aa..f7f6d8cb33114 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -3681,6 +3681,14 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans)
+ return ret;
+ }
+
++static void btrfs_maybe_reset_size_class(struct btrfs_block_group *bg)
++{
++ lockdep_assert_held(&bg->lock);
++ if (btrfs_block_group_should_use_size_class(bg) &&
++ bg->used == 0 && bg->reserved == 0)
++ bg->size_class = BTRFS_BG_SZ_NONE;
++}
++
+ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
+ u64 bytenr, u64 num_bytes, bool alloc)
+ {
+@@ -3745,6 +3753,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
+ old_val -= num_bytes;
+ cache->used = old_val;
+ cache->pinned += num_bytes;
++ btrfs_maybe_reset_size_class(cache);
+ btrfs_space_info_update_bytes_pinned(space_info, num_bytes);
+ space_info->bytes_used -= num_bytes;
+ space_info->disk_used -= num_bytes * factor;
+@@ -3865,6 +3874,7 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache, u64 num_bytes,
+ spin_lock(&cache->lock);
+ bg_ro = cache->ro;
+ cache->reserved -= num_bytes;
++ btrfs_maybe_reset_size_class(cache);
+ if (is_delalloc)
+ cache->delalloc_bytes -= num_bytes;
+ spin_unlock(&cache->lock);
+--
+2.51.0
+
--- /dev/null
+From 8303c29de59b2085b4ed7ce6ca15b27d75fc5a54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 18:03:35 +0000
+Subject: btrfs: use the correct type to initialize block reserve for delayed
+ refs
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 2155d0c0a761a56ce7ede83a26eb23ea0f935260 ]
+
+When initializing the delayed refs block reserve for a transaction handle
+we are passing a type of BTRFS_BLOCK_RSV_DELOPS, which is meant for
+delayed items and not for delayed refs. The correct type for delayed refs
+is BTRFS_BLOCK_RSV_DELREFS.
+
+On release of any excess space reserved in a local delayed refs reserve,
+we also should transfer that excess space to the global block reserve
+(it it's full, we return to the space info for general availability).
+
+By initializing a transaction's local delayed refs block reserve with a
+type of BTRFS_BLOCK_RSV_DELOPS, we were also causing any excess space
+released from the delayed block reserve (fs_info->delayed_block_rsv, used
+for delayed inodes and items) to be transferred to the global block
+reserve instead of the global delayed refs block reserve. This was an
+unintentional change in commit 28270e25c69a ("btrfs: always reserve space
+for delayed refs when starting transaction"), but it's not particularly
+serious as things tend to cancel out each other most of the time and it's
+relatively rare to be anywhere near exhaustion of the global reserve.
+
+Fix this by initializing a transaction's local delayed refs reserve with
+a type of BTRFS_BLOCK_RSV_DELREFS and making btrfs_block_rsv_release()
+attempt to transfer unused space from such a reserve into the global block
+reserve, just as we did before that commit for when the block reserve is
+a delayed refs rsv.
+
+Reported-by: Alex Lyakas <alex.lyakas@zadara.com>
+Link: https://lore.kernel.org/linux-btrfs/CAOcd+r0FHG5LWzTSu=LknwSoqxfw+C00gFAW7fuX71+Z5AfEew@mail.gmail.com/
+Fixes: 28270e25c69a ("btrfs: always reserve space for delayed refs when starting transaction")
+Reviewed-by: Alex Lyakas <alex.lyakas@zadara.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-rsv.c | 7 ++++---
+ fs/btrfs/transaction.c | 2 +-
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c
+index 75cd35570a287..fc378d2038a2d 100644
+--- a/fs/btrfs/block-rsv.c
++++ b/fs/btrfs/block-rsv.c
+@@ -278,10 +278,11 @@ u64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
+ struct btrfs_block_rsv *target = NULL;
+
+ /*
+- * If we are a delayed block reserve then push to the global rsv,
+- * otherwise dump into the global delayed reserve if it is not full.
++ * If we are a delayed refs block reserve then push to the global
++ * reserve, otherwise dump into the global delayed refs reserve if it is
++ * not full.
+ */
+- if (block_rsv->type == BTRFS_BLOCK_RSV_DELOPS)
++ if (block_rsv->type == BTRFS_BLOCK_RSV_DELREFS)
+ target = global_rsv;
+ else if (block_rsv != global_rsv && !btrfs_block_rsv_full(delayed_rsv))
+ target = delayed_rsv;
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index b537bba767806..089712b15d603 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -726,7 +726,7 @@ start_transaction(struct btrfs_root *root, unsigned int num_items,
+
+ h->type = type;
+ INIT_LIST_HEAD(&h->new_bgs);
+- btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELOPS);
++ btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELREFS);
+
+ smp_mb();
+ if (cur_trans->state >= TRANS_STATE_COMMIT_START &&
+--
+2.51.0
+
--- /dev/null
+From 98342d22f83c1f37205de6d558a2b7d63909554f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 00:20:02 +0530
+Subject: cpuidle: Skip governor when only one idle state is available
+
+From: Aboorva Devarajan <aboorvad@linux.ibm.com>
+
+[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ]
+
+On certain platforms (PowerNV systems without a power-mgt DT node),
+cpuidle may register only a single idle state. In cases where that
+single state is a polling state (state 0), the ladder governor may
+incorrectly treat state 1 as the first usable state and pass an
+out-of-bounds index. This can lead to a NULL enter callback being
+invoked, ultimately resulting in a system crash.
+
+[ 13.342636] cpuidle-powernv : Only Snooze is available
+[ 13.351854] Faulting instruction address: 0x00000000
+[ 13.376489] NIP [0000000000000000] 0x0
+[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668
+
+Fix this by adding a bail-out in cpuidle_select() that returns state 0
+directly when state_count <= 1, bypassing the governor and keeping the
+tick running.
+
+Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol")
+Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
+Reviewed-by: Christian Loehle <christian.loehle@arm.com>
+Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/cpuidle.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
+index 56132e843c991..8950796a493de 100644
+--- a/drivers/cpuidle/cpuidle.c
++++ b/drivers/cpuidle/cpuidle.c
+@@ -357,6 +357,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
+ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+ bool *stop_tick)
+ {
++ /*
++ * If there is only a single idle state (or none), there is nothing
++ * meaningful for the governor to choose. Skip the governor and
++ * always use state 0 with the tick running.
++ */
++ if (drv->state_count <= 1) {
++ *stop_tick = false;
++ return 0;
++ }
++
+ return cpuidle_curr_governor->select(drv, dev, stop_tick);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From e9bfb04037f4553b9f09cb85e58c865e4c9fef7a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 20:49:23 +0530
+Subject: drm/amd/display: Fix out-of-bounds stream encoder index v3
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit abde491143e4e12eecc41337910aace4e8d59603 ]
+
+eng_id can be negative and that stream_enc_regs[]
+can be indexed out of bounds.
+
+eng_id is used directly as an index into stream_enc_regs[], which has
+only 5 entries. When eng_id is 5 (ENGINE_ID_DIGF) or negative, this can
+access memory past the end of the array.
+
+Add a bounds check using ARRAY_SIZE() before using eng_id as an index.
+The unsigned cast also rejects negative values.
+
+This avoids out-of-bounds access.
+
+Fixes the below smatch error:
+dcn*_resource.c: stream_encoder_create() may index
+stream_enc_regs[eng_id] out of bounds (size 5).
+
+drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn351/dcn351_resource.c
+ 1246 static struct stream_encoder *dcn35_stream_encoder_create(
+ 1247 enum engine_id eng_id,
+ 1248 struct dc_context *ctx)
+ 1249 {
+
+ ...
+
+ 1255
+ 1256 /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+ 1257 if (eng_id <= ENGINE_ID_DIGF) {
+
+ENGINE_ID_DIGF is 5. should <= be <?
+
+Unrelated but, ugh, why is Smatch saying that "eng_id" can be negative?
+end_id is type signed long, but there are checks in the caller which prevent it from being negative.
+
+ 1258 vpg_inst = eng_id;
+ 1259 afmt_inst = eng_id;
+ 1260 } else
+ 1261 return NULL;
+ 1262
+
+ ...
+
+ 1281
+ 1282 dcn35_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
+ 1283 eng_id, vpg, afmt,
+--> 1284 &stream_enc_regs[eng_id],
+ ^^^^^^^^^^^^^^^^^^^^^^^ This stream_enc_regs[] array has 5 elements so we are one element beyond the end of the array.
+
+ ...
+
+ 1287 return &enc1->base;
+ 1288 }
+
+v2: use explicit bounds check as suggested by Roman/Dan; avoid unsigned int cast
+
+v3: The compiler already knows how to compare the two values, so the
+ cast (int) is not needed. (Roman)
+
+Fixes: 2728e9c7c842 ("drm/amd/display: add DC changes for DCN351")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Mario Limonciello <superm1@kernel.org>
+Cc: Alex Hung <alex.hung@amd.com>
+Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Cc: ChiaHsuan Chung <chiahsuan.chung@amd.com>
+Cc: Roman Li <roman.li@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Roman Li <roman.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/dc/resource/dcn315/dcn315_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn316/dcn316_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn32/dcn32_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn321/dcn321_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 8 ++++----
+ 6 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+index 82cc78c291d82..12c2a0d9fb2a3 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+@@ -1226,12 +1226,12 @@ static struct stream_encoder *dcn315_stream_encoder_create(
+ /*PHYB is wired off in HW, allow front end to remapping, otherwise needs more changes*/
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+index 636110e48d01b..3c77c14c5a5ed 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+@@ -1220,12 +1220,12 @@ static struct stream_encoder *dcn316_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+index 3965a7f1b64b7..9cace432ce364 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+@@ -1208,12 +1208,12 @@ static struct stream_encoder *dcn32_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn32_vpg_create(ctx, vpg_inst);
+ afmt = dcn32_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+index ad214986f7ac7..26fd5c03c0147 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+@@ -1189,12 +1189,12 @@ static struct stream_encoder *dcn321_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn321_vpg_create(ctx, vpg_inst);
+ afmt = dcn321_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+index 06bec7dcc7556..e8d74ceb9dc29 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+@@ -1271,12 +1271,12 @@ static struct stream_encoder *dcn35_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+index 7974e306126e0..532e5d9bc4337 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+@@ -1251,12 +1251,12 @@ static struct stream_encoder *dcn35_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+--
+2.51.0
+
--- /dev/null
+From cadd35ee3a8f39ab21997e5fa69dffa821709d0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jan 2026 15:57:41 +0100
+Subject: drm/amd/display: Reject cursor plane on DCE when scaled differently
+ than primary
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit 41af6215cdbcecd12920f211239479027904abf3 ]
+
+Currently DCE doesn't support the overlay cursor, so the
+dm_crtc_get_cursor_mode() function returns DM_CURSOR_NATIVE_MODE
+unconditionally. The outcome is that it doesn't check for the
+conditions that would necessitate the overlay cursor, meaning
+that it doesn't reject cases where the native cursor mode isn't
+supported on DCE.
+
+Remove the early return from dm_crtc_get_cursor_mode() for
+DCE and instead let it perform the necessary checks and
+return DM_CURSOR_OVERLAY_MODE. Add a later check that rejects
+when DM_CURSOR_OVERLAY_MODE would be used with DCE.
+
+Fixes: 1b04dcca4fb1 ("drm/amd/display: Introduce overlay cursor mode")
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4600
+Suggested-by: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Reviewed-by: Rodrigo Siqueira <siqueira@igalia.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 6252afd1d087f..ccf13bb5281bf 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -12027,10 +12027,9 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev,
+
+ /* Overlay cursor not supported on HW before DCN
+ * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions
+- * as previous DCN generations, so enable native mode on DCN401 in addition to DCE
++ * as previous DCN generations, so enable native mode on DCN401
+ */
+- if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 ||
+- amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {
++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {
+ *cursor_mode = DM_CURSOR_NATIVE_MODE;
+ return 0;
+ }
+@@ -12350,6 +12349,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+ * need to be added for DC to not disable a plane by mistake
+ */
+ if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE) {
++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) {
++ drm_dbg(dev, "Overlay cursor not supported on DCE\n");
++ ret = -EINVAL;
++ goto fail;
++ }
++
+ ret = drm_atomic_add_affected_planes(state, crtc);
+ if (ret)
+ goto fail;
+--
+2.51.0
+
--- /dev/null
+From 533b1f467c143dc4a77774946b9cdfcde84fa94f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 23:38:28 +0100
+Subject: drm/amd/display: Use same max plane scaling limits for all 64 bpp
+ formats
+
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+
+[ Upstream commit f0157ce46cf0e5e2257e19d590c9b16036ce26d4 ]
+
+The plane scaling hw seems to have the same min/max plane scaling limits
+for all 16 bpc / 64 bpp interleaved pixel color formats.
+
+Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for
+all the 16 bpc fixed-point / unorm formats to use the same .fp16
+up/downscaling factor limits as used by the fp16 floating point formats.
+
+So far, 16 bpc unorm formats were not handled, and the default: path
+returned max/min factors for 32 bpp argb8888 formats, which were wrong
+and bigger than what many DCE / DCN hw generations could handle.
+
+The result sometimes was misscaling of framebuffers with
+DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616,
+DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested
+on Polaris11 / DCE-11.2.
+
+So far this went unnoticed, because only few userspace clients used such
+16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they
+did not experience this issue.
+
+With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL
+and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland
+compositor allowing for direct scanout of these formats, the scaling
+hw will be used on these formats if possible for HiDPI display scaling,
+so it is important to use the correct hw scaling limits to avoid wrong
+display.
+
+Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50
+on HiDPI displays with scaling enabled. The mutter Wayland compositor now
+correctly falls back to scaling via desktop compositing instead of direct
+scanout, thereby avoiding wrong image display. For unscaled mode, it
+correctly uses direct scanout.
+
+Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.")
+Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+index e027798ece032..9bb7475e80bad 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+@@ -1059,10 +1059,15 @@ static void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev,
+ *min_downscale = plane_cap->max_downscale_factor.nv12;
+ break;
+
++ /* All 64 bpp formats have the same fp16 scaling limits */
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ABGR16161616F:
++ case DRM_FORMAT_XRGB16161616:
++ case DRM_FORMAT_ARGB16161616:
++ case DRM_FORMAT_XBGR16161616:
++ case DRM_FORMAT_ABGR16161616:
+ *max_upscale = plane_cap->max_upscale_factor.fp16;
+ *min_downscale = plane_cap->max_downscale_factor.fp16;
+ break;
+--
+2.51.0
+
--- /dev/null
+From 87e117f06331f4394b6b4bdbd5fce4fce3a638b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 09:25:32 +0000
+Subject: drm/amdgpu: Fix memory leak in amdgpu_acpi_enumerate_xcc()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit c9be63d565789b56ca7b0197e2cb78a3671f95a8 ]
+
+In amdgpu_acpi_enumerate_xcc(), if amdgpu_acpi_dev_init() returns -ENOMEM,
+the function returns directly without releasing the allocated xcc_info,
+resulting in a memory leak.
+
+Fix this by ensuring that xcc_info is properly freed in the error paths.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: 4d5275ab0b18 ("drm/amdgpu: Add parsing of acpi xcc objects")
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+index 6c62e27b98002..67db986eda3f6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+@@ -1136,8 +1136,10 @@ static int amdgpu_acpi_enumerate_xcc(void)
+ if (!dev_info)
+ ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, sbdf);
+
+- if (ret == -ENOMEM)
++ if (ret == -ENOMEM) {
++ kfree(xcc_info);
+ return ret;
++ }
+
+ if (!dev_info) {
+ kfree(xcc_info);
+--
+2.51.0
+
--- /dev/null
+From c9ceacba32b5a12d7a85763eb33984acabd78c1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 08:35:15 +0000
+Subject: drm/amdgpu: Fix memory leak in amdgpu_ras_init()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit ee41e5b63c8210525c936ee637a2c8d185ce873c ]
+
+When amdgpu_nbio_ras_sw_init() fails in amdgpu_ras_init(), the function
+returns directly without freeing the allocated con structure, leading
+to a memory leak.
+
+Fix this by jumping to the release_con label to properly clean up the
+allocated memory before returning the error code.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: fdc94d3a8c88 ("drm/amdgpu: Rework pcie_bif ras sw_init")
+Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+index e0ee211508607..3fd19859055a5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+@@ -4137,7 +4137,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
+ * to handle fatal error */
+ r = amdgpu_nbio_ras_sw_init(adev);
+ if (r)
+- return r;
++ goto release_con;
+
+ if (adev->nbio.ras &&
+ adev->nbio.ras->init_ras_controller_interrupt) {
+--
+2.51.0
+
--- /dev/null
+From 74a6d8f77438e6e850422616c3cf260bf2d47d0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Oct 2025 17:01:05 -0400
+Subject: drm/amdgpu: move reset debug disable handling
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit ad0a48e531a3137cec16bb5f8f60c8cc8de06b01 ]
+
+Move everything to the supported resets masks rather than
+having an explicit misc checks for this.
+
+Reviewed-by: Jesse Zhang <Jesse.Zhang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 46a2cb7d24f2 ("drm/amdgpu/sdma5: enable queue resets unconditionally")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 8 +++-----
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 3 ---
+ drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 3 ++-
+ drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 6 ++++--
+ drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 3 ++-
+ drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 +-
+ drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 6 ++++--
+ drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 8 ++++++--
+ drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 3 ++-
+ drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 6 ++++--
+ drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 3 ++-
+ drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c | 3 ++-
+ 12 files changed, 32 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+index d020a890a0ea4..630af847f29ff 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+@@ -130,11 +130,9 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job)
+ }
+
+ /* attempt a per ring reset */
+- if (unlikely(adev->debug_disable_gpu_ring_reset)) {
+- dev_err(adev->dev, "Ring reset disabled by debug mask\n");
+- } else if (amdgpu_gpu_recovery &&
+- amdgpu_ring_is_reset_type_supported(ring, AMDGPU_RESET_TYPE_PER_QUEUE) &&
+- ring->funcs->reset) {
++ if (amdgpu_gpu_recovery &&
++ amdgpu_ring_is_reset_type_supported(ring, AMDGPU_RESET_TYPE_PER_QUEUE) &&
++ ring->funcs->reset) {
+ dev_err(adev->dev, "Starting %s ring reset\n",
+ s_job->sched->name);
+ r = amdgpu_ring_reset(ring, job->vmid, &job->hw_fence);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+index 5ec5c3ff22bb0..304564ec2f59a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+@@ -460,9 +460,6 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid,
+ ktime_t deadline;
+ bool ret;
+
+- if (unlikely(ring->adev->debug_disable_soft_recovery))
+- return false;
+-
+ deadline = ktime_add_us(ktime_get(), 10000);
+
+ if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence)
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+index 726b2bdfbba33..003bcece715eb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+@@ -4956,7 +4956,8 @@ static int gfx_v10_0_sw_init(struct amdgpu_ip_block *ip_block)
+ amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]);
+ adev->gfx.compute_supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]);
+- if (!amdgpu_sriov_vf(adev)) {
++ if (!amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset) {
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+index c936772c03725..1dd9fd486eecf 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+@@ -1821,13 +1821,15 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
+ case IP_VERSION(11, 0, 3):
+ if ((adev->gfx.me_fw_version >= 2280) &&
+ (adev->gfx.mec_fw_version >= 2410) &&
+- !amdgpu_sriov_vf(adev)) {
++ !amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset) {
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ }
+ break;
+ default:
+- if (!amdgpu_sriov_vf(adev)) {
++ if (!amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset) {
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+index f80e9e356e252..50e39b9d9df6f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+@@ -1547,7 +1547,8 @@ static int gfx_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
+ case IP_VERSION(12, 0, 1):
+ if ((adev->gfx.me_fw_version >= 2660) &&
+ (adev->gfx.mec_fw_version >= 2920) &&
+- !amdgpu_sriov_vf(adev)) {
++ !amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset) {
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+index dd19a97436db9..7d0a2d239b78d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+@@ -2409,7 +2409,7 @@ static int gfx_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
+ amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]);
+ adev->gfx.compute_supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]);
+- if (!amdgpu_sriov_vf(adev))
++ if (!amdgpu_sriov_vf(adev) && !adev->debug_disable_gpu_ring_reset)
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+
+ r = amdgpu_gfx_kiq_init(adev, GFX9_MEC_HPD_SIZE, 0);
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
+index c90cbe053ef37..a4ebb6c5af557 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
+@@ -1149,14 +1149,16 @@ static int gfx_v9_4_3_sw_init(struct amdgpu_ip_block *ip_block)
+ case IP_VERSION(9, 4, 3):
+ case IP_VERSION(9, 4, 4):
+ if ((adev->gfx.mec_fw_version >= 155) &&
+- !amdgpu_sriov_vf(adev)) {
++ !amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset) {
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_PIPE;
+ }
+ break;
+ case IP_VERSION(9, 5, 0):
+ if ((adev->gfx.mec_fw_version >= 21) &&
+- !amdgpu_sriov_vf(adev)) {
++ !amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset) {
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_PIPE;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+index 36b1ca73c2ed3..a1443990d5c60 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+@@ -2361,11 +2361,15 @@ static void sdma_v4_4_2_update_reset_mask(struct amdgpu_device *adev)
+ switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
+ case IP_VERSION(9, 4, 3):
+ case IP_VERSION(9, 4, 4):
+- if ((adev->gfx.mec_fw_version >= 0xb0) && amdgpu_dpm_reset_sdma_is_supported(adev))
++ if ((adev->gfx.mec_fw_version >= 0xb0) &&
++ amdgpu_dpm_reset_sdma_is_supported(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
+ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ break;
+ case IP_VERSION(9, 5, 0):
+- if ((adev->gfx.mec_fw_version >= 0xf) && amdgpu_dpm_reset_sdma_is_supported(adev))
++ if ((adev->gfx.mec_fw_version >= 0xf) &&
++ amdgpu_dpm_reset_sdma_is_supported(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
+ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ break;
+ default:
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+index 7dc67a22a7a01..8ddc4df06a1fd 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+@@ -1429,7 +1429,8 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block)
+ case IP_VERSION(5, 0, 2):
+ case IP_VERSION(5, 0, 5):
+ if ((adev->sdma.instance[0].fw_version >= 35) &&
+- !amdgpu_sriov_vf(adev))
++ !amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
+ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ break;
+ default:
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+index 3bd44c24f692d..c6a619514a8ad 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+@@ -1348,12 +1348,14 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block)
+ case IP_VERSION(5, 2, 3):
+ case IP_VERSION(5, 2, 4):
+ if ((adev->sdma.instance[0].fw_version >= 76) &&
+- !amdgpu_sriov_vf(adev))
++ !amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
+ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ break;
+ case IP_VERSION(5, 2, 5):
+ if ((adev->sdma.instance[0].fw_version >= 34) &&
+- !amdgpu_sriov_vf(adev))
++ !amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
+ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ break;
+ default:
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+index 3c6568d501994..2170400449872 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+@@ -1356,7 +1356,8 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
+ case IP_VERSION(6, 0, 2):
+ case IP_VERSION(6, 0, 3):
+ if ((adev->sdma.instance[0].fw_version >= 21) &&
+- !amdgpu_sriov_vf(adev))
++ !amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
+ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+ break;
+ default:
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
+index 326ecc8d37d21..2b81344dcd668 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
+@@ -1337,7 +1337,8 @@ static int sdma_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
+
+ adev->sdma.supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
+- if (!amdgpu_sriov_vf(adev))
++ if (!amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
+ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+
+ r = amdgpu_sdma_sysfs_reset_mask_init(adev);
+--
+2.51.0
+
--- /dev/null
+From f10f9e13892a74e454ba44c90dc844e547238d5f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 11:51:45 -0500
+Subject: drm/amdgpu/sdma5: enable queue resets unconditionally
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 46a2cb7d24f21132e970cab52359210c3f5ea3c6 ]
+
+There is no firmware version dependency.
+
+Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask")
+Cc: Jesse Zhang <Jesse.Zhang@amd.com>
+Reviewed-by: Jesse.Zhang <Jesse.zhang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 15 +++------------
+ 1 file changed, 3 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+index 8ddc4df06a1fd..45e2933214a80 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+@@ -1424,18 +1424,9 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block)
+
+ adev->sdma.supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
+- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) {
+- case IP_VERSION(5, 0, 0):
+- case IP_VERSION(5, 0, 2):
+- case IP_VERSION(5, 0, 5):
+- if ((adev->sdma.instance[0].fw_version >= 35) &&
+- !amdgpu_sriov_vf(adev) &&
+- !adev->debug_disable_gpu_ring_reset)
+- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+- break;
+- default:
+- break;
+- }
++ if (!amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+
+ /* Allocate memory for SDMA IP Dump buffer */
+ ptr = kcalloc(adev->sdma.num_instances * reg_count, sizeof(uint32_t), GFP_KERNEL);
+--
+2.51.0
+
--- /dev/null
+From aff1ed03d87acbd386e105d9d8953e5eb51fdc1d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 11:52:46 -0500
+Subject: drm/amdgpu/sdma5.2: enable queue resets unconditionally
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 314d30ad50622fc0d70da71509f9dff21545be14 ]
+
+There is no firmware version dependency. This also
+enables sdma queue resets on all SDMA 5.2.x based
+chips.
+
+Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask")
+Cc: Jesse Zhang <Jesse.Zhang@amd.com>
+Reviewed-by: Jesse.Zhang <Jesse.zhang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 22 +++-------------------
+ 1 file changed, 3 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+index c6a619514a8ad..5b982cc91af39 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+@@ -1342,25 +1342,9 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block)
+
+ adev->sdma.supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
+- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) {
+- case IP_VERSION(5, 2, 0):
+- case IP_VERSION(5, 2, 2):
+- case IP_VERSION(5, 2, 3):
+- case IP_VERSION(5, 2, 4):
+- if ((adev->sdma.instance[0].fw_version >= 76) &&
+- !amdgpu_sriov_vf(adev) &&
+- !adev->debug_disable_gpu_ring_reset)
+- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+- break;
+- case IP_VERSION(5, 2, 5):
+- if ((adev->sdma.instance[0].fw_version >= 34) &&
+- !amdgpu_sriov_vf(adev) &&
+- !adev->debug_disable_gpu_ring_reset)
+- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+- break;
+- default:
+- break;
+- }
++ if (!amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+
+ /* Allocate memory for SDMA IP Dump buffer */
+ ptr = kcalloc(adev->sdma.num_instances * reg_count, sizeof(uint32_t), GFP_KERNEL);
+--
+2.51.0
+
--- /dev/null
+From 7fb2238888be8ca211843bf9f65feb152ccedf87 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 11:53:51 -0500
+Subject: drm/amdgpu/sdma6: enable queue resets unconditionally
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 56423871e9eef1dd069bddef895207fa5ce275fe ]
+
+There is no firmware version dependency. This also
+enables sdma queue resets on all SDMA 6.x based
+chips.
+
+Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask")
+Cc: Jesse Zhang <Jesse.Zhang@amd.com>
+Reviewed-by: Jesse.Zhang <Jesse.zhang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 15 +++------------
+ 1 file changed, 3 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+index 2170400449872..6809c6d4be5b1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+@@ -1351,18 +1351,9 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
+
+ adev->sdma.supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
+- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) {
+- case IP_VERSION(6, 0, 0):
+- case IP_VERSION(6, 0, 2):
+- case IP_VERSION(6, 0, 3):
+- if ((adev->sdma.instance[0].fw_version >= 21) &&
+- !amdgpu_sriov_vf(adev) &&
+- !adev->debug_disable_gpu_ring_reset)
+- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+- break;
+- default:
+- break;
+- }
++ if (!amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+
+ if (amdgpu_sdma_ras_sw_init(adev)) {
+ dev_err(adev->dev, "Failed to initialize sdma ras block!\n");
+--
+2.51.0
+
--- /dev/null
+From c71a8b57e674ac23f19b5761eea5add9e3113464 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 09:05:42 +0000
+Subject: drm/amdgpu: Use kvfree instead of kfree in
+ amdgpu_gmc_get_nps_memranges()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit 0c44d61945c4a80775292d96460aa2f22e62f86c ]
+
+amdgpu_discovery_get_nps_info() internally allocates memory for ranges
+using kvcalloc(), which may use vmalloc() for large allocation. Using
+kfree() to release vmalloc memory will lead to a memory corruption.
+
+Use kvfree() to safely handle both kmalloc and vmalloc allocations.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: b194d21b9bcc ("drm/amdgpu: Use NPS ranges from discovery table")
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+index aef1ba1bdca9e..01ad5cc008a96 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+@@ -1381,7 +1381,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
+ if (!*exp_ranges)
+ *exp_ranges = range_cnt;
+ err:
+- kfree(ranges);
++ kvfree(ranges);
+
+ return ret;
+ }
+--
+2.51.0
+
--- /dev/null
+From 231fb5d2f186aaefca650e5203997395d1a32ad0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 21:18:11 +0530
+Subject: drm/amdkfd: Fix watch_id bounds checking in debug address watch v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit 5a19302cab5cec7ae7f1a60c619951e6c17d8742 ]
+
+The address watch clear code receives watch_id as an unsigned value
+(u32), but some helper functions were using a signed int and checked
+bits by shifting with watch_id.
+
+If a very large watch_id is passed from userspace, it can be converted
+to a negative value. This can cause invalid shifts and may access
+memory outside the watch_points array.
+
+drm/amdkfd: Fix watch_id bounds checking in debug address watch v2
+
+Fix this by checking that watch_id is within MAX_WATCH_ADDRESSES before
+using it. Also use BIT(watch_id) to test and clear bits safely.
+
+This keeps the behavior unchanged for valid watch IDs and avoids
+undefined behavior for invalid ones.
+
+Fixes the below:
+drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c:448
+kfd_dbg_trap_clear_dev_address_watch() error: buffer overflow
+'pdd->watch_points' 4 <= u32max user_rl='0-3,2147483648-u32max' uncapped
+
+drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c
+ 433 int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd,
+ 434 uint32_t watch_id)
+ 435 {
+ 436 int r;
+ 437
+ 438 if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id))
+
+kfd_dbg_owns_dev_watch_id() doesn't check for negative values so if
+watch_id is larger than INT_MAX it leads to a buffer overflow.
+(Negative shifts are undefined).
+
+ 439 return -EINVAL;
+ 440
+ 441 if (!pdd->dev->kfd->shared_resources.enable_mes) {
+ 442 r = debug_lock_and_unmap(pdd->dev->dqm);
+ 443 if (r)
+ 444 return r;
+ 445 }
+ 446
+ 447 amdgpu_gfx_off_ctrl(pdd->dev->adev, false);
+--> 448 pdd->watch_points[watch_id] = pdd->dev->kfd2kgd->clear_address_watch(
+ 449 pdd->dev->adev,
+ 450 watch_id);
+
+v2: (as per, Jonathan Kim)
+ - Add early watch_id >= MAX_WATCH_ADDRESSES validation in the set path to
+ match the clear path.
+ - Drop the redundant bounds check in kfd_dbg_owns_dev_watch_id().
+
+Fixes: e0f85f4690d0 ("drm/amdkfd: add debug set and clear address watch points operation")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Cc: Jonathan Kim <jonathan.kim@amd.com>
+Cc: Felix Kuehling <felix.kuehling@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Jonathan Kim <jonathan.kim@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+index ba99e0f258aee..986cb297de8f8 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+@@ -401,27 +401,25 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i
+ return -ENOMEM;
+ }
+
+-static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id)
++static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id)
+ {
+ spin_lock(&pdd->dev->watch_points_lock);
+
+ /* process owns device watch point so safe to clear */
+- if ((pdd->alloc_watch_ids >> watch_id) & 0x1) {
+- pdd->alloc_watch_ids &= ~(0x1 << watch_id);
+- pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id);
++ if (pdd->alloc_watch_ids & BIT(watch_id)) {
++ pdd->alloc_watch_ids &= ~BIT(watch_id);
++ pdd->dev->alloc_watch_ids &= ~BIT(watch_id);
+ }
+
+ spin_unlock(&pdd->dev->watch_points_lock);
+ }
+
+-static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id)
++static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id)
+ {
+ bool owns_watch_id = false;
+
+ spin_lock(&pdd->dev->watch_points_lock);
+- owns_watch_id = watch_id < MAX_WATCH_ADDRESSES &&
+- ((pdd->alloc_watch_ids >> watch_id) & 0x1);
+-
++ owns_watch_id = pdd->alloc_watch_ids & BIT(watch_id);
+ spin_unlock(&pdd->dev->watch_points_lock);
+
+ return owns_watch_id;
+@@ -432,6 +430,9 @@ int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd,
+ {
+ int r;
+
++ if (watch_id >= MAX_WATCH_ADDRESSES)
++ return -EINVAL;
++
+ if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id))
+ return -EINVAL;
+
+@@ -469,6 +470,9 @@ int kfd_dbg_trap_set_dev_address_watch(struct kfd_process_device *pdd,
+ if (r)
+ return r;
+
++ if (*watch_id >= MAX_WATCH_ADDRESSES)
++ return -EINVAL;
++
+ if (!pdd->dev->kfd->shared_resources.enable_mes) {
+ r = debug_lock_and_unmap(pdd->dev->dqm);
+ if (r) {
+--
+2.51.0
+
--- /dev/null
+From 9e21ea5280336714a9f9e24a3ae19987884c4a78 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jan 2026 08:55:49 +0530
+Subject: drm/i915/acpi: free _DSM package when no connectors
+
+From: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+
+[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ]
+
+acpi_evaluate_dsm_typed() returns an ACPI package in pkg.
+When pkg->package.count == 0, we returned without freeing pkg,
+leaking memory. Free pkg before returning on the empty case.
+
+Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_acpi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c
+index 1addd62882413..1e8b9d1756988 100644
+--- a/drivers/gpu/drm/i915/display/intel_acpi.c
++++ b/drivers/gpu/drm/i915/display/intel_acpi.c
+@@ -96,6 +96,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle)
+
+ if (!pkg->package.count) {
+ DRM_DEBUG_DRIVER("no connection in _DSM\n");
++ ACPI_FREE(pkg);
+ return;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From c9bd8a093489c0f777148a40bf4b893e637efcae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 11:26:22 +0530
+Subject: drm/xe/bo: Redirect faults to dummy page for wedged device
+
+From: Raag Jadav <raag.jadav@intel.com>
+
+[ Upstream commit 4e83a8d58e1c721a89b3ffe15f549007080272e2 ]
+
+As per uapi documentation[1], the prerequisite for wedged device is to
+redirected page faults to a dummy page. Follow it.
+
+[1] Documentation/gpu/drm-uapi.rst
+
+v2: Add uapi reference and fixes tag (Matthew Brost)
+
+Fixes: 7bc00751f877 ("drm/xe: Use device wedged event")
+Signed-off-by: Raag Jadav <raag.jadav@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patch.msgid.link/20260212055622.2054991-1-raag.jadav@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit c020fff70d757612933711dd3cc3751d7d782d3c)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index e2e28ff73925b..a270aef7c4980 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -1895,7 +1895,7 @@ static vm_fault_t xe_bo_cpu_fault(struct vm_fault *vmf)
+ int err = 0;
+ int idx;
+
+- if (!drm_dev_enter(&xe->drm, &idx))
++ if (xe_device_wedged(xe) || !drm_dev_enter(&xe->drm, &idx))
+ return ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
+
+ ret = xe_bo_cpu_fault_fastpath(vmf, xe, bo, needs_rpm);
+--
+2.51.0
+
--- /dev/null
+From ebb4e29b7ad45d4c5d476daac69d59fe693ee85d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 20:37:45 +0100
+Subject: drm/xe/configfs: Fix 'parameter name omitted' errors
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ Upstream commit 2a673fb4d787ce6672862cb693112378bff86abb ]
+
+On some configs and old compilers we can get following build errors:
+
+ ../drivers/gpu/drm/xe/xe_configfs.h: In function 'xe_configfs_get_ctx_restore_mid_bb':
+ ../drivers/gpu/drm/xe/xe_configfs.h:40:76: error: parameter name omitted
+ static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class,
+ ^~~~~~~~~~~~~~~~~~~~
+ ../drivers/gpu/drm/xe/xe_configfs.h: In function 'xe_configfs_get_ctx_restore_post_bb':
+ ../drivers/gpu/drm/xe/xe_configfs.h:42:77: error: parameter name omitted
+ static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class,
+ ^~~~~~~~~~~~~~~~~~~~
+when trying to define our configfs stub functions. Fix that.
+
+Fixes: 7a4756b2fd04 ("drm/xe/lrc: Allow to add user commands mid context switch")
+Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Reviewed-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260203193745.576-1-michal.wajdeczko@intel.com
+(cherry picked from commit f59cde8a2452b392115d2af8f1143a94725f4827)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_configfs.h | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_configfs.h b/drivers/gpu/drm/xe/xe_configfs.h
+index c61e0e47ed94c..08cce375ae0f3 100644
+--- a/drivers/gpu/drm/xe/xe_configfs.h
++++ b/drivers/gpu/drm/xe/xe_configfs.h
+@@ -19,9 +19,11 @@ void xe_configfs_check_device(struct pci_dev *pdev);
+ bool xe_configfs_get_survivability_mode(struct pci_dev *pdev);
+ u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev);
+ bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev);
+-u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class,
++u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev,
++ enum xe_engine_class class,
+ const u32 **cs);
+-u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class,
++u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev,
++ enum xe_engine_class class,
+ const u32 **cs);
+ #else
+ static inline int xe_configfs_init(void) { return 0; }
+@@ -30,9 +32,11 @@ static inline void xe_configfs_check_device(struct pci_dev *pdev) { }
+ static inline bool xe_configfs_get_survivability_mode(struct pci_dev *pdev) { return false; }
+ static inline u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev) { return U64_MAX; }
+ static inline bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev) { return false; }
+-static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class,
++static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev,
++ enum xe_engine_class class,
+ const u32 **cs) { return 0; }
+-static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class,
++static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev,
++ enum xe_engine_class class,
+ const u32 **cs) { return 0; }
+ #endif
+
+--
+2.51.0
+
--- /dev/null
+From ba52df08bb8f158a94838164cc6b3a56638d9e73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 18:18:54 +0000
+Subject: drm/xe: Make xe_modparam.force_vram_bar_size signed
+
+From: Shuicheng Lin <shuicheng.lin@intel.com>
+
+[ Upstream commit 1acec6ef0511b92e7974cc5a8768bfd3a659feaf ]
+
+vram_bar_size is registered as an int module parameter and is documented
+to accept negative values to disable BAR resizing.
+Store it as an int in xe_modparam as well, so negative values work as
+intended and the module_param type matches.
+
+Fixes: 80742a1aa26e ("drm/xe: Allow to drop vram resizing")
+Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Signed-off-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260202181853.1095736-2-shuicheng.lin@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit 25c9aa4dcb5ef2ad9f354d19f8f1eeb690d1c161)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_module.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_module.h b/drivers/gpu/drm/xe/xe_module.h
+index 5a3bfea8b7b4c..b668495392701 100644
+--- a/drivers/gpu/drm/xe/xe_module.h
++++ b/drivers/gpu/drm/xe/xe_module.h
+@@ -12,7 +12,7 @@
+ struct xe_modparam {
+ bool force_execlist;
+ bool probe_display;
+- u32 force_vram_bar_size;
++ int force_vram_bar_size;
+ int guc_log_level;
+ char *guc_firmware_path;
+ char *huc_firmware_path;
+--
+2.51.0
+
--- /dev/null
+From bc09ff709096cc0333fd8d0078394e1463864a12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jan 2026 16:56:22 +0000
+Subject: drm/xe/mmio: Avoid double-adjust in 64-bit reads
+
+From: Shuicheng Lin <shuicheng.lin@intel.com>
+
+[ Upstream commit 4a9b4e1fa52a6aaa1adbb7f759048df14afed54c ]
+
+xe_mmio_read64_2x32() was adjusting register addresses and then
+calling xe_mmio_read32(), which applies the adjustment again.
+This may shift accesses twice if adj_offset < adj_limit. There is
+no issue currently, as for media gt, adj_offset > adj_limit, so
+the 2nd adjust will be a no-op. But it may not work in future.
+
+To fix it, replace the adjusted-address comparison with a direct
+sanity check that ensures the MMIO address adjustment cutoff never
+falls within the 8-byte range of a 64-bit register. And let
+xe_mmio_read32() handle address translation.
+
+v2: rewrite the sanity check in a more natural way. (Matt)
+v3: Add Fixes tag. (Jani)
+
+Fixes: 07431945d8ae ("drm/xe: Avoid 64-bit register reads")
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Cc: Jani Nikula <jani.nikula@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260130165621.471408-2-shuicheng.lin@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit a30f999681126b128a43137793ac84b6a5b7443f)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_mmio.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
+index ef6f3ea573a2c..6752881af093a 100644
+--- a/drivers/gpu/drm/xe/xe_mmio.c
++++ b/drivers/gpu/drm/xe/xe_mmio.c
+@@ -260,11 +260,11 @@ u64 xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg)
+ struct xe_reg reg_udw = { .addr = reg.addr + 0x4 };
+ u32 ldw, udw, oldudw, retries;
+
+- reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr);
+- reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr);
+-
+- /* we shouldn't adjust just one register address */
+- xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4);
++ /*
++ * The two dwords of a 64-bit register can never straddle the offset
++ * adjustment cutoff.
++ */
++ xe_tile_assert(mmio->tile, !in_range(mmio->adj_limit, reg.addr + 1, 7));
+
+ oldudw = xe_mmio_read32(mmio, reg_udw);
+ for (retries = 5; retries; --retries) {
+--
+2.51.0
+
--- /dev/null
+From cbf7d860fb7a8249fe0901b603b5840583f041a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Feb 2026 14:05:09 -0800
+Subject: drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit bc6387a2e0c1562faa56ce2a98cef50cab809e08 ]
+
+The PSS_CHICKEN register has been part of the RCS engine's LRC since it
+was first introduced in Xe_LP. That means that any workarounds that
+adjust its value (such as Wa_14019988906 and Wa_14019877138) need to be
+implemented in the lrc_was[] table so that they become part of the
+default LRC from which all subsequent LRCs are copied. Although these
+workarounds were implemented correctly on most platforms, they were
+incorrectly placed on the engine_was[] table for Xe2_HPG.
+
+Move the workarounds to the proper lrc_was[] table and switch the
+'xe_rtp_match_first_render_or_compute' rule to specifically match the
+RCS since that's the engine whose LRC manages the register.
+
+Bspec: 65182
+Fixes: 7f3ee7d88058 ("drm/xe/xe2hpg: Add initial GT workarounds")
+Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com>
+Link: https://patch.msgid.link/20260205220508.51905-2-matthew.d.roper@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit e04c609eedf4d6748ac0bcada4de1275b034fed6)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_wa.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
+index d209434fd7fc2..2a2e9f2c09163 100644
+--- a/drivers/gpu/drm/xe/xe_wa.c
++++ b/drivers/gpu/drm/xe/xe_wa.c
+@@ -567,16 +567,6 @@ static const struct xe_rtp_entry_sr engine_was[] = {
+ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS))
+ },
+- { XE_RTP_NAME("14019988906"),
+- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
+- FUNC(xe_rtp_match_first_render_or_compute)),
+- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD))
+- },
+- { XE_RTP_NAME("14019877138"),
+- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
+- FUNC(xe_rtp_match_first_render_or_compute)),
+- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT))
+- },
+ { XE_RTP_NAME("14020338487"),
+ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
+ FUNC(xe_rtp_match_first_render_or_compute)),
+@@ -873,6 +863,14 @@ static const struct xe_rtp_entry_sr lrc_was[] = {
+ XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(WM_CHICKEN3, HIZ_PLANE_COMPRESSION_DIS))
+ },
++ { XE_RTP_NAME("14019988906"),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)),
++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD))
++ },
++ { XE_RTP_NAME("14019877138"),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)),
++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT))
++ },
+ { XE_RTP_NAME("14021490052"),
+ XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(FF_MODE,
+--
+2.51.0
+
--- /dev/null
+From ba05d9cdaa7e499762e11d6affd7196889b67910 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 10:49:56 +0000
+Subject: efi: Fix reservation of unaccepted memory table
+
+From: Kiryl Shutsemau (Meta) <kas@kernel.org>
+
+[ Upstream commit 0862438c90487e79822d5647f854977d50381505 ]
+
+The reserve_unaccepted() function incorrectly calculates the size of the
+memblock reservation for the unaccepted memory table. It aligns the
+size of the table, but fails to account for cases where the table's
+starting physical address (efi.unaccepted) is not page-aligned.
+
+If the table starts at an offset within a page and its end crosses into
+a subsequent page that the aligned size does not cover, the end of the
+table will not be reserved. This can lead to the table being overwritten
+or inaccessible, causing a kernel panic in accept_memory().
+
+This issue was observed when starting Intel TDX VMs with specific memory
+sizes (e.g., > 64GB).
+
+Fix this by calculating the end address first (including the unaligned
+start) and then aligning it up, ensuring the entire range is covered
+by the reservation.
+
+Fixes: 8dbe33956d96 ("efi/unaccepted: Make sure unaccepted table is mapped")
+Reported-by: Moritz Sanft <ms@edgeless.systems>
+Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/efi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index fc407d891348f..c3cf5541ed682 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -691,13 +691,13 @@ static __init int match_config_table(const efi_guid_t *guid,
+
+ static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted)
+ {
+- phys_addr_t start, size;
++ phys_addr_t start, end;
+
+ start = PAGE_ALIGN_DOWN(efi.unaccepted);
+- size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size);
++ end = PAGE_ALIGN(efi.unaccepted + sizeof(*unaccepted) + unaccepted->size);
+
+- memblock_add(start, size);
+- memblock_reserve(start, size);
++ memblock_add(start, end - start);
++ memblock_reserve(start, end - start);
+ }
+
+ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+--
+2.51.0
+
--- /dev/null
+From 0967448eeaff2761a98e5742ba3ec4a40412ae20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Feb 2026 09:19:49 -0800
+Subject: eth: fbnic: Add validation for MTU changes
+
+From: Dimitri Daskalakis <dimitri.daskalakis1@gmail.com>
+
+[ Upstream commit ccd8e87748ad083047d6c8544c5809b7f96cc8df ]
+
+Increasing the MTU beyond the HDS threshold causes the hardware to
+fragment packets across multiple buffers. If a single-buffer XDP program
+is attached, the driver will drop all multi-frag frames. While we can't
+prevent a remote sender from sending non-TCP packets larger than the MTU,
+this will prevent users from inadvertently breaking new TCP streams.
+
+Traditionally, drivers supported XDP with MTU less than 4Kb
+(packet per page). Fbnic currently prevents attaching XDP when MTU is too high.
+But it does not prevent increasing MTU after XDP is attached.
+
+Fixes: 1b0a3950dbd4 ("eth: fbnic: Add XDP pass, drop, abort support")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Dimitri Daskalakis <dimitri.daskalakis1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+index e95be0e7bd9e0..5cbf3ad175a54 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+@@ -262,6 +262,23 @@ static int fbnic_set_mac(struct net_device *netdev, void *p)
+ return 0;
+ }
+
++static int fbnic_change_mtu(struct net_device *dev, int new_mtu)
++{
++ struct fbnic_net *fbn = netdev_priv(dev);
++
++ if (fbnic_check_split_frames(fbn->xdp_prog, new_mtu, fbn->hds_thresh)) {
++ dev_err(&dev->dev,
++ "MTU %d is larger than HDS threshold %d in XDP mode\n",
++ new_mtu, fbn->hds_thresh);
++
++ return -EINVAL;
++ }
++
++ WRITE_ONCE(dev->mtu, new_mtu);
++
++ return 0;
++}
++
+ void fbnic_clear_rx_mode(struct fbnic_dev *fbd)
+ {
+ struct net_device *netdev = fbd->netdev;
+@@ -533,6 +550,7 @@ static const struct net_device_ops fbnic_netdev_ops = {
+ .ndo_start_xmit = fbnic_xmit_frame,
+ .ndo_features_check = fbnic_features_check,
+ .ndo_set_mac_address = fbnic_set_mac,
++ .ndo_change_mtu = fbnic_change_mtu,
+ .ndo_set_rx_mode = fbnic_set_rx_mode,
+ .ndo_get_stats64 = fbnic_get_stats64,
+ .ndo_bpf = fbnic_bpf,
+--
+2.51.0
+
--- /dev/null
+From 4215c7e621fc72897ad6290fe887722445c1c581 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 19:06:20 -0800
+Subject: eth: fbnic: Advertise supported XDP features.
+
+From: Dimitri Daskalakis <dimitri.daskalakis1@gmail.com>
+
+[ Upstream commit e977fcb3a318b53b47f23b44ac237fceb1b731fe ]
+
+Drivers are supposed to advertise the XDP features they support. This was
+missed while adding XDP support.
+
+Before:
+$ ynl --family netdev --dump dev-get
+...
+ {'ifindex': 3,
+ 'xdp-features': set(),
+ 'xdp-rx-metadata-features': set(),
+ 'xsk-features': set()},
+...
+
+After:
+$ ynl --family netdev --dump dev-get
+...
+ {'ifindex': 3,
+ 'xdp-features': {'basic', 'rx-sg'},
+ 'xdp-rx-metadata-features': set(),
+ 'xsk-features': set()},
+...
+
+Fixes: 168deb7b31b2 ("eth: fbnic: Add support for XDP_TX action")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Dimitri Daskalakis <dimitri.daskalakis1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260218030620.3329608-1-dimitri.daskalakis1@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+index 5cbf3ad175a54..cbedaa037cfa8 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+@@ -808,6 +808,8 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)
+ netdev->hw_enc_features |= netdev->features;
+ netdev->features |= NETIF_F_NTUPLE;
+
++ netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_RX_SG;
++
+ netdev->min_mtu = IPV6_MIN_MTU;
+ netdev->max_mtu = FBNIC_MAX_JUMBO_FRAME_SIZE - ETH_HLEN;
+
+--
+2.51.0
+
--- /dev/null
+From d2b99fd71520efd07b71ba3cdf07406eefe47826 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Nov 2025 15:26:10 -0800
+Subject: eth: fbnic: Configure RDE settings for pause frame
+
+From: Mohsin Bashir <mohsin.bashr@gmail.com>
+
+[ Upstream commit 0135333914d63181f823bd340ae96737c8a820ca ]
+
+fbnic supports pause frames. When pause frames are enabled presumably
+user expects lossless operation from the NIC. Make sure we configure
+RDE (Rx DMA Engine) to DROP_NEVER mode to avoid discards due to delays
+in fetching Rx descriptors from the host.
+
+While at it enable DROP_NEVER when NIC only has a single queue
+configured. In this case the NIC acts as a FIFO so there's no risk
+of head-of-line blocking other queues by making RDE wait. If pause
+is disabled this just moves the packet loss from the DMA engine to
+the Rx buffer.
+
+Remove redundant call to fbnic_config_drop_mode_rcq(), introduced by
+commit 0cb4c0a13723 ("eth: fbnic: Implement Rx queue
+alloc/start/stop/free"). This call does not add value as
+fbnic_enable_rcq(), which is called immediately afterward, already
+handles this.
+
+Although we do not support autoneg at this time, preserve tx_pause in
+.mac_link_up instead of fbnic_phylink_get_pauseparam()
+
+Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20251113232610.1151712-1-mohsin.bashr@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: bbeb3bfbffe0 ("eth: fbnic: set FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT on RDE_CTL0")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/meta/fbnic/fbnic_netdev.h | 2 ++
+ .../net/ethernet/meta/fbnic/fbnic_phylink.c | 3 +++
+ drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 26 ++++++++++++++++---
+ drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 1 +
+ 4 files changed, 28 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
+index b0a87c57910f2..e6ca23a9957d9 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.h
+@@ -73,6 +73,8 @@ struct fbnic_net {
+
+ /* Time stamping filter config */
+ struct kernel_hwtstamp_config hwtstamp_config;
++
++ bool tx_pause;
+ };
+
+ int __fbnic_open(struct fbnic_net *fbn);
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c b/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
+index 7ce3fdd252828..62701923cfe96 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
+@@ -208,6 +208,9 @@ fbnic_phylink_mac_link_up(struct phylink_config *config,
+ struct fbnic_net *fbn = netdev_priv(netdev);
+ struct fbnic_dev *fbd = fbn->fbd;
+
++ fbn->tx_pause = tx_pause;
++ fbnic_config_drop_mode(fbn, tx_pause);
++
+ fbd->mac->link_up(fbd, tx_pause, rx_pause);
+ }
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+index b1e8ce89870f7..e99d17660230c 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+@@ -2573,11 +2573,15 @@ static void fbnic_enable_bdq(struct fbnic_ring *hpq, struct fbnic_ring *ppq)
+ }
+
+ static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv,
+- struct fbnic_ring *rcq)
++ struct fbnic_ring *rcq, bool tx_pause)
+ {
++ struct fbnic_net *fbn = netdev_priv(nv->napi.dev);
+ u32 drop_mode, rcq_ctl;
+
+- drop_mode = FBNIC_QUEUE_RDE_CTL0_DROP_IMMEDIATE;
++ if (!tx_pause && fbn->num_rx_queues > 1)
++ drop_mode = FBNIC_QUEUE_RDE_CTL0_DROP_IMMEDIATE;
++ else
++ drop_mode = FBNIC_QUEUE_RDE_CTL0_DROP_NEVER;
+
+ /* Specify packet layout */
+ rcq_ctl = FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_DROP_MODE_MASK, drop_mode) |
+@@ -2587,6 +2591,21 @@ static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv,
+ fbnic_ring_wr32(rcq, FBNIC_QUEUE_RDE_CTL0, rcq_ctl);
+ }
+
++void fbnic_config_drop_mode(struct fbnic_net *fbn, bool tx_pause)
++{
++ int i, t;
++
++ for (i = 0; i < fbn->num_napi; i++) {
++ struct fbnic_napi_vector *nv = fbn->napi[i];
++
++ for (t = 0; t < nv->rxt_count; t++) {
++ struct fbnic_q_triad *qt = &nv->qt[nv->txt_count + t];
++
++ fbnic_config_drop_mode_rcq(nv, &qt->cmpl, tx_pause);
++ }
++ }
++}
++
+ static void fbnic_config_rim_threshold(struct fbnic_ring *rcq, u16 nv_idx, u32 rx_desc)
+ {
+ u32 threshold;
+@@ -2636,7 +2655,7 @@ static void fbnic_enable_rcq(struct fbnic_napi_vector *nv,
+ u32 hds_thresh = fbn->hds_thresh;
+ u32 rcq_ctl = 0;
+
+- fbnic_config_drop_mode_rcq(nv, rcq);
++ fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause);
+
+ /* Force lower bound on MAX_HEADER_BYTES. Below this, all frames should
+ * be split at L4. It would also result in the frames being split at
+@@ -2699,7 +2718,6 @@ static void __fbnic_nv_enable(struct fbnic_napi_vector *nv)
+ &nv->napi);
+
+ fbnic_enable_bdq(&qt->sub0, &qt->sub1);
+- fbnic_config_drop_mode_rcq(nv, &qt->cmpl);
+ fbnic_enable_rcq(nv, &qt->cmpl);
+ }
+ }
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+index ca37da5a0b179..27776e844e29b 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+@@ -184,6 +184,7 @@ void fbnic_reset_netif_queues(struct fbnic_net *fbn);
+ irqreturn_t fbnic_msix_clean_rings(int irq, void *data);
+ void fbnic_napi_enable(struct fbnic_net *fbn);
+ void fbnic_napi_disable(struct fbnic_net *fbn);
++void fbnic_config_drop_mode(struct fbnic_net *fbn, bool tx_pause);
+ void fbnic_enable(struct fbnic_net *fbn);
+ void fbnic_disable(struct fbnic_net *fbn);
+ void fbnic_flush(struct fbnic_net *fbn);
+--
+2.51.0
+
--- /dev/null
+From ea1e18ab3a17b2fcba094112b3bfebcaf45822df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 17:00:42 -0800
+Subject: eth: fbnic: increase FBNIC_HDR_BYTES_MIN from 128 to 256 bytes
+
+From: Bobby Eshleman <bobbyeshleman@meta.com>
+
+[ Upstream commit bd254115f38db3c046332bb62e8719e0dc7c2b53 ]
+
+Increase FBNIC_HDR_BYTES_MIN from 128 to 256 bytes. The previous minimum
+was too small to guarantee that very long L2+L3+L4 headers always fit
+within the header buffer. When EN_HDR_SPLIT is disabled and a packet
+exceeds MAX_HEADER_BYTES, splitting occurs at that byte offset instead
+of the header boundary, resulting in some of the header landing in the
+payload page. The increased minimum ensures headers always fit with the
+MAX_HEADER_BYTES cut off and land in the header page.
+
+Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration")
+Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
+Acked-by: Mohsin Bashir <mohsin.bashr@gmail.com>
+Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-2-55d050e6f606@meta.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+index 27776e844e29b..51a98f27d5d91 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+@@ -66,7 +66,7 @@ struct fbnic_net;
+ (4096 - FBNIC_RX_HROOM - FBNIC_RX_TROOM - FBNIC_RX_PAD)
+ #define FBNIC_HDS_THRESH_DEFAULT \
+ (1536 - FBNIC_RX_PAD)
+-#define FBNIC_HDR_BYTES_MIN 128
++#define FBNIC_HDR_BYTES_MIN 256
+
+ struct fbnic_pkt_buff {
+ struct xdp_buff buff;
+--
+2.51.0
+
--- /dev/null
+From b16da16ef967ea7b9cd07b8af90da1a2fd85efc0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 17:00:43 -0800
+Subject: eth: fbnic: set DMA_HINT_L4 for all flows
+
+From: Bobby Eshleman <bobbyeshleman@meta.com>
+
+[ Upstream commit 0f30a31b55c4179fc55613a75ef41d496687d465 ]
+
+fbnic always advertises ETHTOOL_TCP_DATA_SPLIT_ENABLED via ethtool
+.get_ringparam. To enable proper splitting for all flow types, even for
+IP/Ethernet flows, this patch sets DMA_HINT_L4 unconditionally for all
+RSS and NFC flow steering rules. According to the spec, L4 falls back to
+L3 if no valid L4 is found, and L3 falls back to L2 if no L3 is found.
+This makes sure that the correct header boundary is used regardless of
+traffic type. This is important for zero-copy use cases where we must
+ensure that all ZC packets are split correctly.
+
+Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration")
+Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
+Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-3-55d050e6f606@meta.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c | 3 +++
+ drivers/net/ethernet/meta/fbnic/fbnic_rpc.c | 5 ++---
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+index 95fac020eb93c..08aed4103323e 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+@@ -1142,6 +1142,9 @@ static int fbnic_set_cls_rule_ins(struct fbnic_net *fbn,
+ return -EINVAL;
+ }
+
++ dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT,
++ FBNIC_RCD_HDR_AL_DMA_HINT_L4);
++
+ /* Write action table values */
+ act_tcam->dest = dest;
+ act_tcam->rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, hash_idx);
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
+index 7f31e890031c0..42a186db43ea9 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
+@@ -338,9 +338,8 @@ void fbnic_rss_reinit(struct fbnic_dev *fbd, struct fbnic_net *fbn)
+ else if (tstamp_mask & (1u << flow_type))
+ dest |= FBNIC_RPC_ACT_TBL0_TS_ENA;
+
+- if (act1_value[flow_type] & FBNIC_RPC_TCAM_ACT1_L4_VALID)
+- dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT,
+- FBNIC_RCD_HDR_AL_DMA_HINT_L4);
++ dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT,
++ FBNIC_RCD_HDR_AL_DMA_HINT_L4);
+
+ rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, flow_type);
+
+--
+2.51.0
+
--- /dev/null
+From 3fa6110e36d85cf6ce68520a4abe27487253f6c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 17:00:41 -0800
+Subject: eth: fbnic: set FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT on RDE_CTL0
+
+From: Bobby Eshleman <bobbyeshleman@meta.com>
+
+[ Upstream commit bbeb3bfbffe0279fa47c041658b037fb38a93965 ]
+
+Fix EN_HDR_SPLIT configuration by writing the field to RDE_CTL0 instead
+of RDE_CTL1.
+
+Because drop mode configuration and header splitting enablement both use
+RDE_CTL0, we consolidate these configurations into the single function
+fbnic_config_drop_mode.
+
+Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration")
+Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
+Acked-by: Mohsin Bashir <mohsin.bashr@gmail.com>
+Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-1-55d050e6f606@meta.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 25 +++++++++++---------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+index e99d17660230c..fbdf79b6ad2de 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+@@ -2573,7 +2573,8 @@ static void fbnic_enable_bdq(struct fbnic_ring *hpq, struct fbnic_ring *ppq)
+ }
+
+ static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv,
+- struct fbnic_ring *rcq, bool tx_pause)
++ struct fbnic_ring *rcq, bool tx_pause,
++ bool hdr_split)
+ {
+ struct fbnic_net *fbn = netdev_priv(nv->napi.dev);
+ u32 drop_mode, rcq_ctl;
+@@ -2586,22 +2587,26 @@ static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv,
+ /* Specify packet layout */
+ rcq_ctl = FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_DROP_MODE_MASK, drop_mode) |
+ FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_HROOM_MASK, FBNIC_RX_HROOM) |
+- FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_TROOM_MASK, FBNIC_RX_TROOM);
++ FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_TROOM_MASK, FBNIC_RX_TROOM) |
++ FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT, hdr_split);
+
+ fbnic_ring_wr32(rcq, FBNIC_QUEUE_RDE_CTL0, rcq_ctl);
+ }
+
+-void fbnic_config_drop_mode(struct fbnic_net *fbn, bool tx_pause)
++void fbnic_config_drop_mode(struct fbnic_net *fbn, bool txp)
+ {
++ bool hds;
+ int i, t;
+
++ hds = fbn->hds_thresh < FBNIC_HDR_BYTES_MIN;
++
+ for (i = 0; i < fbn->num_napi; i++) {
+ struct fbnic_napi_vector *nv = fbn->napi[i];
+
+ for (t = 0; t < nv->rxt_count; t++) {
+ struct fbnic_q_triad *qt = &nv->qt[nv->txt_count + t];
+
+- fbnic_config_drop_mode_rcq(nv, &qt->cmpl, tx_pause);
++ fbnic_config_drop_mode_rcq(nv, &qt->cmpl, txp, hds);
+ }
+ }
+ }
+@@ -2652,20 +2657,18 @@ static void fbnic_enable_rcq(struct fbnic_napi_vector *nv,
+ {
+ struct fbnic_net *fbn = netdev_priv(nv->napi.dev);
+ u32 log_size = fls(rcq->size_mask);
+- u32 hds_thresh = fbn->hds_thresh;
+ u32 rcq_ctl = 0;
+-
+- fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause);
++ bool hdr_split;
++ u32 hds_thresh;
+
+ /* Force lower bound on MAX_HEADER_BYTES. Below this, all frames should
+ * be split at L4. It would also result in the frames being split at
+ * L2/L3 depending on the frame size.
+ */
+- if (fbn->hds_thresh < FBNIC_HDR_BYTES_MIN) {
+- rcq_ctl = FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT;
+- hds_thresh = FBNIC_HDR_BYTES_MIN;
+- }
++ hdr_split = fbn->hds_thresh < FBNIC_HDR_BYTES_MIN;
++ fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause, hdr_split);
+
++ hds_thresh = max(fbn->hds_thresh, FBNIC_HDR_BYTES_MIN);
+ rcq_ctl |= FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_PADLEN_MASK, FBNIC_RX_PAD) |
+ FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_MAX_HDR_MASK, hds_thresh) |
+ FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_PAYLD_OFF_MASK,
+--
+2.51.0
+
--- /dev/null
+From 852df3e8f930875453c992ac4b545e97e4ff4358 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 19:13:29 +0000
+Subject: fbnic: close fw_log race between users and teardown
+
+From: Chengfeng Ye <dg573847474@gmail.com>
+
+[ Upstream commit ee5492fd88cfc079c19fbeac78e9e53b7f6c04f3 ]
+
+Fixes a theoretical race on fw_log between the teardown path and fw_log
+write functions.
+
+fw_log is written inside fbnic_fw_log_write() and can be reached from
+the mailbox handler fbnic_fw_msix_intr(), but fw_log is freed before
+IRQ/MBX teardown during cleanup, resulting in a potential data race of
+dereferencing a freed/null variable.
+
+Possible Interleaving Scenario:
+ CPU0: fbnic_fw_msix_intr() // Entry
+ fbnic_fw_log_write()
+ if (fbnic_fw_log_ready()) // true
+ ... preempt ...
+ CPU1: fbnic_remove() // Entry
+ fbnic_fw_log_free()
+ vfree(log->data_start);
+ log->data_start = NULL;
+ CPU0: continues, walks log->entries or writes to log->data_start
+
+The initialization also has an incorrect order problem, as the fw_log
+is currently allocated after MBX setup during initialization.
+Fix the problems by adjusting the synchronization order to put
+initialization in place before the mailbox is enabled, and not cleared
+until after the mailbox has been disabled.
+
+Fixes: ecc53b1b46c89 ("eth: fbnic: Enable firmware logging")
+Signed-off-by: Chengfeng Ye <dg573847474@gmail.com>
+Link: https://patch.msgid.link/20260211191329.530886-1-dg573847474@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/meta/fbnic/fbnic_fw_log.c | 3 ---
+ drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 19 ++++++++++++-------
+ 2 files changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c
+index 85a883dba385f..d8a9a7d7c2375 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c
+@@ -51,8 +51,6 @@ int fbnic_fw_log_init(struct fbnic_dev *fbd)
+ log->data_start = data;
+ log->data_end = data + FBNIC_FW_LOG_SIZE;
+
+- fbnic_fw_log_enable(fbd, true);
+-
+ return 0;
+ }
+
+@@ -63,7 +61,6 @@ void fbnic_fw_log_free(struct fbnic_dev *fbd)
+ if (!fbnic_fw_log_ready(fbd))
+ return;
+
+- fbnic_fw_log_disable(fbd);
+ INIT_LIST_HEAD(&log->entries);
+ log->size = 0;
+ vfree(log->data_start);
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+index 0fa90baad5f88..698b8a85afb31 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+@@ -303,11 +303,17 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ goto free_irqs;
+ }
+
++ err = fbnic_fw_log_init(fbd);
++ if (err)
++ dev_warn(fbd->dev,
++ "Unable to initialize firmware log buffer: %d\n",
++ err);
++
+ err = fbnic_fw_request_mbx(fbd);
+ if (err) {
+ dev_err(&pdev->dev,
+ "Firmware mailbox initialization failure\n");
+- goto free_irqs;
++ goto free_fw_log;
+ }
+
+ /* Send the request to enable the FW logging to host. Note if this
+@@ -315,11 +321,7 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ * possible the FW is just too old to support the logging and needs
+ * to be updated.
+ */
+- err = fbnic_fw_log_init(fbd);
+- if (err)
+- dev_warn(fbd->dev,
+- "Unable to initialize firmware log buffer: %d\n",
+- err);
++ fbnic_fw_log_enable(fbd, true);
+
+ fbnic_devlink_register(fbd);
+ fbnic_devlink_otp_check(fbd, "error detected during probe");
+@@ -363,6 +365,8 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ * firmware updates for fixes.
+ */
+ return 0;
++free_fw_log:
++ fbnic_fw_log_free(fbd);
+ free_irqs:
+ fbnic_free_irqs(fbd);
+ err_destroy_health:
+@@ -397,8 +401,9 @@ static void fbnic_remove(struct pci_dev *pdev)
+ fbnic_hwmon_unregister(fbd);
+ fbnic_dbg_fbd_exit(fbd);
+ fbnic_devlink_unregister(fbd);
+- fbnic_fw_log_free(fbd);
++ fbnic_fw_log_disable(fbd);
+ fbnic_fw_free_mbx(fbd);
++ fbnic_fw_log_free(fbd);
+ fbnic_free_irqs(fbd);
+
+ fbnic_devlink_health_destroy(fbd);
+--
+2.51.0
+
--- /dev/null
+From fb9753a59f1270e70a5c2dc6973eb0a094282474 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jan 2026 16:50:24 +0000
+Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot
+
+From: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+
+[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ]
+
+In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the
+entry size ('esize') is retrieved from the log record without adequate
+bounds checking.
+
+Specifically, the code calculates the end of the entry ('e2') using:
+ e2 = Add2Ptr(e1, esize);
+
+It then calculates the size for memmove using 'PtrOffset(e2, ...)',
+which subtracts the end pointer from the buffer limit. If 'esize' is
+maliciously large, 'e2' exceeds the used buffer size. This results in
+a negative offset which, when cast to size_t for memmove, interprets
+as a massive unsigned integer, leading to a heap buffer overflow.
+
+This commit adds a check to ensure that the entry size ('esize') strictly
+fits within the remaining used space of the index header before performing
+memory operations.
+
+Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
+Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/fslog.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
+index 38934e6978ece..28bd611f580d9 100644
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -3429,6 +3429,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe,
+
+ e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off));
+ esize = le16_to_cpu(e1->size);
++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize)
++ goto dirty_vol;
++
+ e2 = Add2Ptr(e1, esize);
+
+ memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used)));
+--
+2.51.0
+
--- /dev/null
+From 266fe65acab12925f6ae004c2db92141100039cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 23:02:51 +0100
+Subject: fs/ntfs3: Initialize new folios before use
+
+From: Bartlomiej Kubik <kubik.bartlomiej@gmail.com>
+
+[ Upstream commit f223ebffa185cc8da934333c5a31ff2d4f992dc9 ]
+
+KMSAN reports an uninitialized value in longest_match_std(), invoked
+from ntfs_compress_write(). When new folios are allocated without being
+marked uptodate and ni_read_frame() is skipped because the caller expects
+the frame to be completely overwritten, some reserved folios may remain
+only partially filled, leaving the rest memory uninitialized.
+
+Fixes: 584f60ba22f7 ("ntfs3: Convert ntfs_get_frame_pages() to use a folio")
+Tested-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com
+Reported-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=08d8956768c96a2c52cf
+
+Signed-off-by: Bartlomiej Kubik <kubik.bartlomiej@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index 83f0072f0896c..3e61eaf28e088 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -930,7 +930,7 @@ static int ntfs_get_frame_pages(struct address_space *mapping, pgoff_t index,
+
+ folio = __filemap_get_folio(mapping, index,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
+- gfp_mask);
++ gfp_mask | __GFP_ZERO);
+ if (IS_ERR(folio)) {
+ while (npages--) {
+ folio = page_folio(pages[npages]);
+--
+2.51.0
+
--- /dev/null
+From ffb34cc517631bc47a65514d64443654aebd0082 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Dec 2025 11:53:25 +0800
+Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the
+ same
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ]
+
+When processing valid within the range [valid : pos), if valid cannot
+be retrieved correctly, for example, if the retrieved valid value is
+always the same, this can trigger a potential infinite loop, similar
+to the hung problem reported by syzbot [1].
+
+Adding a check for the valid value within the loop body, and terminating
+the loop and returning -EINVAL if the value is the same as the current
+value, can prevent this.
+
+[1]
+INFO: task syz.4.21:6056 blocked for more than 143 seconds.
+Call Trace:
+ rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244
+ inode_lock include/linux/fs.h:1027 [inline]
+ ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284
+
+Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
+Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/file.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index 3e61eaf28e088..cd7aaeef45fe9 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -1012,8 +1012,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from)
+ goto out;
+
+ if (lcn == SPARSE_LCN) {
+- ni->i_valid = valid =
+- frame_vbo + ((u64)clen << sbi->cluster_bits);
++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits);
++ if (ni->i_valid == valid) {
++ err = -EINVAL;
++ goto out;
++ }
++ ni->i_valid = valid;
+ continue;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 5bca349b9bab6be4d4fc5f8c7b17ccad3ac21eac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 14:11:49 -0800
+Subject: gpio: amd-fch: ionly return allowed values from amd_fch_gpio_get()
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+[ Upstream commit fbd03587ba732c612b8a569d1cf5bed72bd3a27c ]
+
+As of 86ef402d805d ("gpiolib: sanitize the return value of
+gpio_chip::get()") gpiolib requires drivers implementing GPIOs to only
+return 0, 1 or negative error for the get() callbacks. Ensure that
+amd-fch complies with this requirement.
+
+Fixes: 86ef402d805d ("gpiolib: sanitize the return value of gpio_chip::get()")
+Reported-and-tested-by: Tj <tj.iam.tj@proton.me>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Link: https://patch.msgid.link/aZTlwnvHt2Gho4yN@google.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-amd-fch.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpio/gpio-amd-fch.c b/drivers/gpio/gpio-amd-fch.c
+index e6c6c3ec7656e..9f329938202bf 100644
+--- a/drivers/gpio/gpio-amd-fch.c
++++ b/drivers/gpio/gpio-amd-fch.c
+@@ -8,6 +8,7 @@
+ *
+ */
+
++#include <linux/bitfield.h>
+ #include <linux/err.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+@@ -120,15 +121,15 @@ static int amd_fch_gpio_get(struct gpio_chip *gc,
+ unsigned int offset)
+ {
+ unsigned long flags;
+- int ret;
++ u32 val;
+ struct amd_fch_gpio_priv *priv = gpiochip_get_data(gc);
+ void __iomem *ptr = amd_fch_gpio_addr(priv, offset);
+
+ spin_lock_irqsave(&priv->lock, flags);
+- ret = (readl_relaxed(ptr) & AMD_FCH_GPIO_FLAG_READ);
++ val = readl_relaxed(ptr);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+- return ret;
++ return FIELD_GET(AMD_FCH_GPIO_FLAG_READ, val);
+ }
+
+ static int amd_fch_gpio_request(struct gpio_chip *chip,
+--
+2.51.0
+
--- /dev/null
+From 7f1341d2edb60172b067945258c78e6c863339c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:28 +0000
+Subject: icmp: prevent possible overflow in icmp_global_allow()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 034bbd806298e9ba4197dd1587b0348ee30996ea ]
+
+Following expression can overflow
+if sysctl_icmp_msgs_per_sec is big enough.
+
+sysctl_icmp_msgs_per_sec * delta / HZ;
+
+Fixes: 4cdf507d5452 ("icmp: add a global rate limitation")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216142832.3834174-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/icmp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index 9323ee0a6ac48..3e19a5d465b83 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -248,7 +248,8 @@ bool icmp_global_allow(struct net *net)
+ if (delta < HZ / 50)
+ return false;
+
+- incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ;
++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec);
++ incr = div_u64((u64)incr * delta, HZ);
+ if (!incr)
+ return false;
+
+--
+2.51.0
+
--- /dev/null
+From a60aa7140a3d6ea2ead93d0fd0dd3062459fc506 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:29 +0000
+Subject: inet: move icmp_global_{credit,stamp} to a separate cache line
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87b08913a9ae82082e276d237ece08fc8ee24380 ]
+
+icmp_global_credit was meant to be changed ~1000 times per second,
+but if an admin sets net.ipv4.icmp_msgs_per_sec to a very high value,
+icmp_global_credit changes can inflict false sharing to surrounding
+fields that are read mostly.
+
+Move icmp_global_credit and icmp_global_stamp to a separate
+cacheline aligned group.
+
+Fixes: b056b4cd9178 ("icmp: move icmp_global.credit and icmp_global.stamp to per netns storage")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216142832.3834174-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netns/ipv4.h | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 34eb3aecb3f21..62166da045548 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -87,6 +87,12 @@ struct netns_ipv4 {
+ int sysctl_tcp_rmem[3];
+ __cacheline_group_end(netns_ipv4_read_rx);
+
++ /* ICMP rate limiter hot cache line. */
++ __cacheline_group_begin_aligned(icmp);
++ atomic_t icmp_global_credit;
++ u32 icmp_global_stamp;
++ __cacheline_group_end_aligned(icmp);
++
+ struct inet_timewait_death_row tcp_death_row;
+ struct udp_table *udp_table;
+
+@@ -139,8 +145,7 @@ struct netns_ipv4 {
+ int sysctl_icmp_ratemask;
+ int sysctl_icmp_msgs_per_sec;
+ int sysctl_icmp_msgs_burst;
+- atomic_t icmp_global_credit;
+- u32 icmp_global_stamp;
++
+ u32 ip_rt_min_pmtu;
+ int ip_rt_mtu_expires;
+ int ip_rt_min_advmss;
+--
+2.51.0
+
--- /dev/null
+From f9baf68961d92be290b7176edbc2fedc806773c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:22:02 +0000
+Subject: ipv6: fix a race in ip6_sock_set_v6only()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ]
+
+It is unlikely that this function will be ever called
+with isk->inet_num being not zero.
+
+Perform the check on isk->inet_num inside the locked section
+for complete safety.
+
+Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ipv6.h | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index 2ccdf85f34f16..f0936df7567e3 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -1280,12 +1280,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
+
+ static inline int ip6_sock_set_v6only(struct sock *sk)
+ {
+- if (inet_sk(sk)->inet_num)
+- return -EINVAL;
++ int ret = 0;
++
+ lock_sock(sk);
+- sk->sk_ipv6only = true;
++ if (inet_sk(sk)->inet_num)
++ ret = -EINVAL;
++ else
++ sk->sk_ipv6only = true;
+ release_sock(sk);
+- return 0;
++ return ret;
+ }
+
+ static inline void ip6_sock_set_recverr(struct sock *sk)
+--
+2.51.0
+
--- /dev/null
+From 493cc1cc2d90d492db06e2fb030bbf47fab9e7ea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 17:50:21 +0000
+Subject: ipv6: Fix out-of-bound access in fib6_add_rt2node().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 8244f959e2c125c849e569f5b23ed49804cce695 ]
+
+syzbot reported out-of-bound read in fib6_add_rt2node(). [0]
+
+When IPv6 route is created with RTA_NH_ID, struct fib6_info
+does not have the trailing struct fib6_nh.
+
+The cited commit started to check !iter->fib6_nh->fib_nh_gw_family
+to ensure that rt6_qualify_for_ecmp() will return false for iter.
+
+If iter->nh is not NULL, rt6_qualify_for_ecmp() returns false anyway.
+
+Let's check iter->nh before reading iter->fib6_nh and avoid OOB read.
+
+[0]:
+BUG: KASAN: slab-out-of-bounds in fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142
+Read of size 1 at addr ffff8880384ba6de by task syz.0.18/5500
+
+CPU: 0 UID: 0 PID: 5500 Comm: syz.0.18 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xba/0x230 mm/kasan/report.c:482
+ kasan_report+0x117/0x150 mm/kasan/report.c:595
+ fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142
+ fib6_add_rt2node_nh net/ipv6/ip6_fib.c:1363 [inline]
+ fib6_add+0x910/0x18c0 net/ipv6/ip6_fib.c:1531
+ __ip6_ins_rt net/ipv6/route.c:1351 [inline]
+ ip6_route_add+0xde/0x1b0 net/ipv6/route.c:3957
+ inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660
+ rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f9316b9aeb9
+Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007ffd8809b678 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f9316e15fa0 RCX: 00007f9316b9aeb9
+RDX: 0000000000000000 RSI: 0000200000004380 RDI: 0000000000000003
+RBP: 00007f9316c08c1f R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 00007f9316e15fac R14: 00007f9316e15fa0 R15: 00007f9316e15fa0
+ </TASK>
+
+Allocated by task 5499:
+ kasan_save_stack mm/kasan/common.c:57 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263 [inline]
+ __do_kmalloc_node mm/slub.c:5657 [inline]
+ __kmalloc_noprof+0x40c/0x7e0 mm/slub.c:5669
+ kmalloc_noprof include/linux/slab.h:961 [inline]
+ kzalloc_noprof include/linux/slab.h:1094 [inline]
+ fib6_info_alloc+0x30/0xf0 net/ipv6/ip6_fib.c:155
+ ip6_route_info_create+0x142/0x860 net/ipv6/route.c:3820
+ ip6_route_add+0x49/0x1b0 net/ipv6/route.c:3949
+ inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660
+ rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: bbf4a17ad9ff ("ipv6: Fix ECMP sibling count mismatch when clearing RTF_ADDRCONF")
+Reported-by: syzbot+707d6a5da1ab9e0c6f9d@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/698cbfba.050a0220.2eeac1.009d.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Reviewed-by: Shigeru Yoshida <syoshida@redhat.com>
+Link: https://patch.msgid.link/20260211175133.3657034-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_fib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index c6439e30e892a..cc149227b49f4 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -1139,7 +1139,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
+ fib6_add_gc_list(iter);
+ }
+ if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) &&
+- !iter->fib6_nh->fib_nh_gw_family) {
++ (iter->nh || !iter->fib6_nh->fib_nh_gw_family)) {
+ iter->fib6_flags &= ~RTF_ADDRCONF;
+ iter->fib6_flags &= ~RTF_PREFIX_RT;
+ }
+--
+2.51.0
+
--- /dev/null
+From 948d9b79c53c81ed65ebf63dac11fa6dd96a4b53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:30 +0000
+Subject: ipv6: icmp: remove obsolete code in icmpv6_xrlim_allow()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0201eedb69b24a6be9b7c1716287a89c4dde2320 ]
+
+Following part was needed before the blamed commit, because
+inet_getpeer_v6() second argument was the prefix.
+
+ /* Give more bandwidth to wider prefixes. */
+ if (rt->rt6i_dst.plen < 128)
+ tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
+
+Now inet_getpeer_v6() retrieves hosts, we need to remove
+@tmo adjustement or wider prefixes likes /24 allow 8x
+more ICMP to be sent for a given ratelimit.
+
+As we had this issue for a while, this patch changes net.ipv6.icmp.ratelimit
+default value from 1000ms to 100ms to avoid potential regressions.
+
+Also add a READ_ONCE() when reading net->ipv6.sysctl.icmpv6_time.
+
+Fixes: fd0273d7939f ("ipv6: Remove external dependency on rt6i_dst and rt6i_src")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Cc: Martin KaFai Lau <martin.lau@kernel.org>
+Link: https://patch.msgid.link/20260216142832.3834174-4-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/networking/ip-sysctl.rst | 7 ++++---
+ net/ipv6/af_inet6.c | 2 +-
+ net/ipv6/icmp.c | 7 +------
+ 3 files changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
+index a06cb99d66dcd..7a637e87005fe 100644
+--- a/Documentation/networking/ip-sysctl.rst
++++ b/Documentation/networking/ip-sysctl.rst
+@@ -3195,12 +3195,13 @@ enhanced_dad - BOOLEAN
+ ===========
+
+ ratelimit - INTEGER
+- Limit the maximal rates for sending ICMPv6 messages.
++ Limit the maximal rates for sending ICMPv6 messages to a particular
++ peer.
+
+ 0 to disable any limiting,
+- otherwise the minimal space between responses in milliseconds.
++ otherwise the space between responses in milliseconds.
+
+- Default: 1000
++ Default: 100
+
+ ratemask - list of comma separated ranges
+ For ICMPv6 message types matching the ranges in the ratemask, limit
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index 1b0314644e0cc..0e8f48835869c 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -955,7 +955,7 @@ static int __net_init inet6_net_init(struct net *net)
+ int err = 0;
+
+ net->ipv6.sysctl.bindv6only = 0;
+- net->ipv6.sysctl.icmpv6_time = 1*HZ;
++ net->ipv6.sysctl.icmpv6_time = HZ / 10;
+ net->ipv6.sysctl.icmpv6_echo_ignore_all = 0;
+ net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0;
+ net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0;
+diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
+index 306eec18e82c1..35b32dcf581ff 100644
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -217,14 +217,9 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
+ } else if (dev && (dev->flags & IFF_LOOPBACK)) {
+ res = true;
+ } else {
+- struct rt6_info *rt = dst_rt6_info(dst);
+- int tmo = net->ipv6.sysctl.icmpv6_time;
++ int tmo = READ_ONCE(net->ipv6.sysctl.icmpv6_time);
+ struct inet_peer *peer;
+
+- /* Give more bandwidth to wider prefixes. */
+- if (rt->rt6i_dst.plen < 128)
+- tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
+-
+ peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr);
+ res = inet_peer_xrlim_allow(peer, tmo);
+ }
+--
+2.51.0
+
--- /dev/null
+From 8d3b11d605b14169844a33faa3bd8039fa1e890a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Feb 2026 16:58:50 +0200
+Subject: ipvs: do not keep dest_dst if dev is going down
+
+From: Julian Anastasov <ja@ssi.bg>
+
+[ Upstream commit 8fde939b0206afc1d5846217a01a16b9bc8c7896 ]
+
+There is race between the netdev notifier ip_vs_dst_event()
+and the code that caches dst with dev that is going down.
+As the FIB can be notified for the closed device after our
+handler finishes, it is possible valid route to be returned
+and cached resuling in a leaked dev reference until the dest
+is not removed.
+
+To prevent new dest_dst to be attached to dest just after the
+handler dropped the old one, add a netif_running() check
+to make sure the notifier handler is not currently running
+for device that is closing.
+
+Fixes: 7a4f0761fce3 ("IPVS: init and cleanup restructuring")
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 46 ++++++++++++++++++++++++++-------
+ 1 file changed, 36 insertions(+), 10 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index 618fbe1240b54..ecbcdc43263d6 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -295,6 +295,12 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs,
+ return true;
+ }
+
++/* rt has device that is down */
++static bool rt_dev_is_down(const struct net_device *dev)
++{
++ return dev && !netif_running(dev);
++}
++
+ /* Get route to destination or remote server */
+ static int
+ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+@@ -310,9 +316,11 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+
+ if (dest) {
+ dest_dst = __ip_vs_dst_check(dest);
+- if (likely(dest_dst))
++ if (likely(dest_dst)) {
+ rt = dst_rtable(dest_dst->dst_cache);
+- else {
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.ip;
++ } else {
+ dest_dst = ip_vs_dest_dst_alloc();
+ spin_lock_bh(&dest->dst_lock);
+ if (!dest_dst) {
+@@ -328,14 +336,22 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+ ip_vs_dest_dst_free(dest_dst);
+ goto err_unreach;
+ }
+- __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0);
++ /* It is forbidden to attach dest->dest_dst if
++ * device is going down.
++ */
++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst)))
++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0);
++ else
++ noref = 0;
+ spin_unlock_bh(&dest->dst_lock);
+ IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d\n",
+ &dest->addr.ip, &dest_dst->dst_saddr.ip,
+ rcuref_read(&rt->dst.__rcuref));
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.ip;
++ if (!noref)
++ ip_vs_dest_dst_free(dest_dst);
+ }
+- if (ret_saddr)
+- *ret_saddr = dest_dst->dst_saddr.ip;
+ } else {
+ noref = 0;
+
+@@ -472,9 +488,11 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+
+ if (dest) {
+ dest_dst = __ip_vs_dst_check(dest);
+- if (likely(dest_dst))
++ if (likely(dest_dst)) {
+ rt = dst_rt6_info(dest_dst->dst_cache);
+- else {
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.in6;
++ } else {
+ u32 cookie;
+
+ dest_dst = ip_vs_dest_dst_alloc();
+@@ -495,14 +513,22 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+ }
+ rt = dst_rt6_info(dst);
+ cookie = rt6_get_cookie(rt);
+- __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie);
++ /* It is forbidden to attach dest->dest_dst if
++ * device is going down.
++ */
++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst)))
++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie);
++ else
++ noref = 0;
+ spin_unlock_bh(&dest->dst_lock);
+ IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n",
+ &dest->addr.in6, &dest_dst->dst_saddr.in6,
+ rcuref_read(&rt->dst.__rcuref));
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.in6;
++ if (!noref)
++ ip_vs_dest_dst_free(dest_dst);
+ }
+- if (ret_saddr)
+- *ret_saddr = dest_dst->dst_saddr.in6;
+ } else {
+ noref = 0;
+ dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm,
+--
+2.51.0
+
--- /dev/null
+From 55f45cd8dad081264b36665a7357e6c71061bc0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 13:45:22 -0800
+Subject: kbuild: Add objtool to top-level clean target
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 68b4fe32d73789dea23e356f468de67c8367ef8f ]
+
+Objtool is an integral part of the build, make sure it gets cleaned by
+"make clean" and "make mrproper".
+
+Fixes: 442f04c34a1a ("objtool: Add tool to perform compile-time stack metadata validation")
+Reported-by: Jens Remus <jremus@linux.ibm.com>
+Closes: https://lore.kernel.org/15f2af3b-be33-46fc-b972-6b8e7e0aa52e@linux.ibm.com
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Tested-by: Jens Remus <jremus@linux.ibm.com>
+Link: https://patch.msgid.link/968faf2ed30fa8b3519f79f01a1ecfe7929553e5.1770759919.git.jpoimboe@kernel.org
+[nathan: use Closes: instead of Link: per checkpatch.pl]
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile | 11 ++++++++++-
+ tools/objtool/Makefile | 2 ++
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index c4b22ec262784..bc34a825aba80 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1440,6 +1440,15 @@ ifneq ($(wildcard $(resolve_btfids_O)),)
+ $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean
+ endif
+
++PHONY += objtool_clean
++
++objtool_O = $(abspath $(objtree))/tools/objtool
++
++objtool_clean:
++ifneq ($(wildcard $(objtool_O)),)
++ $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean
++endif
++
+ tools/: FORCE
+ $(Q)mkdir -p $(objtree)/tools
+ $(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/
+@@ -1603,7 +1612,7 @@ vmlinuxclean:
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean
+ $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean)
+
+-clean: archclean vmlinuxclean resolve_btfids_clean
++clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean
+
+ # mrproper - Delete all generated files, including .config
+ #
+diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
+index 8c20361dd100e..99d3897e046c6 100644
+--- a/tools/objtool/Makefile
++++ b/tools/objtool/Makefile
+@@ -7,6 +7,8 @@ srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+ srctree := $(patsubst %/,%,$(dir $(srctree)))
+ endif
+
++RM ?= rm -f
++
+ LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/
+ ifneq ($(OUTPUT),)
+ LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd
+--
+2.51.0
+
--- /dev/null
+From 58f3c80b91b4d29fdb06c9a283388439b58021df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 15:01:34 -0800
+Subject: libbpf: Fix invalid write loop logic in bpf_linker__add_buf()
+
+From: Amery Hung <ameryhung@gmail.com>
+
+[ Upstream commit 04999b99e81eaa7b6223ec1c03af3bcb4ac57aaa ]
+
+Fix bpf_linker__add_buf()'s logic of copying data from memory buffer into
+memfd. In the event of short write not writing entire buf_sz bytes into memfd
+file, we'll append bytes from the beginning of buf *again* (corrupting ELF
+file contents) instead of correctly appending the rest of not-yet-read buf
+contents.
+
+Closes: https://github.com/libbpf/libbpf/issues/945
+Fixes: 6d5e5e5d7ce1 ("libbpf: Extend linker API to support in-memory ELF files")
+Signed-off-by: Amery Hung <ameryhung@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Link: https://lore.kernel.org/bpf/20260209230134.3530521-1-ameryhung@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/linker.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
+index 56ae77047bc36..b86b8ae3b6341 100644
+--- a/tools/lib/bpf/linker.c
++++ b/tools/lib/bpf/linker.c
+@@ -581,7 +581,7 @@ int bpf_linker__add_buf(struct bpf_linker *linker, void *buf, size_t buf_sz,
+
+ written = 0;
+ while (written < buf_sz) {
+- ret = write(fd, buf, buf_sz);
++ ret = write(fd, buf + written, buf_sz - written);
+ if (ret < 0) {
+ ret = -errno;
+ pr_warn("failed to write '%s': %s\n", filename, errstr(ret));
+--
+2.51.0
+
--- /dev/null
+From 25fbd119df3980bc8fb1beddb5bab0dca0304971 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:25:57 +0000
+Subject: macvlan: observe an RCU grace period in macvlan_common_newlink()
+ error path
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ]
+
+valis reported that a race condition still happens after my prior patch.
+
+macvlan_common_newlink() might have made @dev visible before
+detecting an error, and its caller will directly call free_netdev(dev).
+
+We must respect an RCU period, either in macvlan or the core networking
+stack.
+
+After adding a temporary mdelay(1000) in macvlan_forward_source_one()
+to open the race window, valis repro was:
+
+ip link add p1 type veth peer p2
+ip link set address 00:00:00:00:00:20 dev p1
+ip link set up dev p1
+ip link set up dev p2
+ip link add mv0 link p2 type macvlan mode source
+
+(ip link add invalid% link p2 type macvlan mode source macaddr add
+00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4
+PING 1.2.3.4 (1.2.3.4): 56 data bytes
+RTNETLINK answers: Invalid argument
+
+BUG: KASAN: slab-use-after-free in macvlan_forward_source
+(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+Read of size 8 at addr ffff888016bb89c0 by task e/175
+
+CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
+Call Trace:
+<IRQ>
+dump_stack_lvl (lib/dump_stack.c:123)
+print_report (mm/kasan/report.c:379 mm/kasan/report.c:482)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+kasan_report (mm/kasan/report.c:597)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+? tasklet_init (kernel/softirq.c:983)
+macvlan_handle_frame (drivers/net/macvlan.c:501)
+
+Allocated by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+__kasan_kmalloc (mm/kasan/common.c:419)
+__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657
+mm/slub.c:7140)
+alloc_netdev_mqs (net/core/dev.c:12012)
+rtnl_create_link (net/core/rtnetlink.c:3648)
+rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Freed by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+kasan_save_free_info (mm/kasan/generic.c:587)
+__kasan_slab_free (mm/kasan/common.c:287)
+kfree (mm/slub.c:6674 mm/slub.c:6882)
+rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: valis <sec@valis.email>
+Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macvlan.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index c509228be84d1..4433b8e95b6ac 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1572,6 +1572,11 @@ int macvlan_common_newlink(struct net_device *dev,
+ if (create)
+ macvlan_port_destroy(port->dev);
+ }
++ /* @dev might have been made visible before an error was detected.
++ * Make sure to observe an RCU grace period before our caller
++ * (rtnl_newlink()) frees it.
++ */
++ synchronize_net();
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(macvlan_common_newlink);
+--
+2.51.0
+
--- /dev/null
+From 4e63ce5d292c0cf2657fa9439886bcd7474e3024 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Feb 2026 04:40:10 -0500
+Subject: mshv: fix SRCU protection in irqfd resampler ack handler
+
+From: Li RongQing <lirongqing@baidu.com>
+
+[ Upstream commit 2e7577cd5ddc1f86d1b6c48caf3cfa87dbb14e34 ]
+
+Replace hlist_for_each_entry_rcu() with hlist_for_each_entry_srcu()
+in mshv_irqfd_resampler_ack() to correctly handle SRCU-protected
+linked list traversal.
+
+The function uses SRCU (sleepable RCU) synchronization via
+partition->pt_irq_srcu, but was incorrectly using the RCU variant
+for list iteration. This could lead to race conditions when the
+list is modified concurrently.
+
+Also add srcu_read_lock_held() assertion as required by
+hlist_for_each_entry_srcu() to ensure we're in the proper
+read-side critical section.
+
+Fixes: 621191d709b14 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs")
+Signed-off-by: Li RongQing <lirongqing@baidu.com>
+Reviewed-by: Anirudh Rayabharam (Microsoft) <anirudh@anirudhrb.com>
+Acked-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/mshv_eventfd.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hv/mshv_eventfd.c b/drivers/hv/mshv_eventfd.c
+index 806674722868b..05d643f54f45a 100644
+--- a/drivers/hv/mshv_eventfd.c
++++ b/drivers/hv/mshv_eventfd.c
+@@ -87,8 +87,9 @@ static void mshv_irqfd_resampler_ack(struct mshv_irq_ack_notifier *mian)
+
+ idx = srcu_read_lock(&partition->pt_irq_srcu);
+
+- hlist_for_each_entry_rcu(irqfd, &resampler->rsmplr_irqfd_list,
+- irqfd_resampler_hnode) {
++ hlist_for_each_entry_srcu(irqfd, &resampler->rsmplr_irqfd_list,
++ irqfd_resampler_hnode,
++ srcu_read_lock_held(&partition->pt_irq_srcu)) {
+ if (hv_should_clear_interrupt(irqfd->irqfd_lapic_irq.lapic_control.interrupt_type))
+ hv_call_clear_virtual_interrupt(partition->pt_id);
+
+--
+2.51.0
+
--- /dev/null
+From 1c9667ad0f6820a0f57947d696c0e982e4b5158d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 09:00:30 +0200
+Subject: net: bridge: mcast: always update mdb_n_entries for vlan contexts
+
+From: Nikolay Aleksandrov <nikolay@nvidia.com>
+
+[ Upstream commit 8b769e311a86bb9d15c5658ad283b86fc8f080a2 ]
+
+syzbot triggered a warning[1] about the number of mdb entries in a context.
+It turned out that there are multiple ways to trigger that warning today
+(some got added during the years), the root cause of the problem is that
+the increase is done conditionally, and over the years these different
+conditions increased so there were new ways to trigger the warning, that is
+to do a decrease which wasn't paired with a previous increase.
+
+For example one way to trigger it is with flush:
+ $ ip l add br0 up type bridge vlan_filtering 1 mcast_snooping 1
+ $ ip l add dumdum up master br0 type dummy
+ $ bridge mdb add dev br0 port dumdum grp 239.0.0.1 permanent vid 1
+ $ ip link set dev br0 down
+ $ ip link set dev br0 type bridge mcast_vlan_snooping 1
+ ^^^^ this will enable snooping, but will not update mdb_n_entries
+ because in __br_multicast_enable_port_ctx() we check !netif_running
+ $ bridge mdb flush dev br0
+ ^^^ this will trigger the warning because it will delete the pg which
+ we added above, which will try to decrease mdb_n_entries
+
+Fix the problem by removing the conditional increase and always keep the
+count up-to-date while the vlan exists. In order to do that we have to
+first initialize it on port-vlan context creation, and then always increase
+or decrease the value regardless of mcast options. To keep the current
+behaviour we have to enforce the mdb limit only if the context is port's or
+if the port-vlan's mcast snooping is enabled.
+
+[1]
+ ------------[ cut here ]------------
+ n == 0
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline], CPU#0: syz.4.4607/22043
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline], CPU#0: syz.4.4607/22043
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825, CPU#0: syz.4.4607/22043
+ Modules linked in:
+ CPU: 0 UID: 0 PID: 22043 Comm: syz.4.4607 Not tainted syzkaller #0 PREEMPT(full)
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026
+ RIP: 0010:br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline]
+ RIP: 0010:br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline]
+ RIP: 0010:br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825
+ Code: 41 5f 5d e9 04 7a 48 f7 e8 3f 73 5c f7 90 0f 0b 90 e9 cf fd ff ff e8 31 73 5c f7 90 0f 0b 90 e9 16 fd ff ff e8 23 73 5c f7 90 <0f> 0b 90 e9 60 fd ff ff e8 15 73 5c f7 eb 05 e8 0e 73 5c f7 48 8b
+ RSP: 0018:ffffc9000c207220 EFLAGS: 00010293
+ RAX: ffffffff8a68042d RBX: ffff88807c6f1800 RCX: ffff888066e90000
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+ RBP: 0000000000000000 R08: ffff888066e90000 R09: 000000000000000c
+ R10: 000000000000000c R11: 0000000000000000 R12: ffff8880303ef800
+ R13: dffffc0000000000 R14: ffff888050eb11c4 R15: 1ffff1100a1d6238
+ FS: 00007fa45921b6c0(0000) GS:ffff8881256f5000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007fa4591f9ff8 CR3: 0000000081df2000 CR4: 00000000003526f0
+ Call Trace:
+ <TASK>
+ br_mdb_flush_pgs net/bridge/br_mdb.c:1525 [inline]
+ br_mdb_flush net/bridge/br_mdb.c:1544 [inline]
+ br_mdb_del_bulk+0x5e2/0xb20 net/bridge/br_mdb.c:1561
+ rtnl_mdb_del+0x48a/0x640 net/core/rtnetlink.c:-1
+ rtnetlink_rcv_msg+0x77e/0xbe0 net/core/rtnetlink.c:6967
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ RIP: 0033:0x7fa45839aeb9
+ Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48
+ RSP: 002b:00007fa45921b028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+ RAX: ffffffffffffffda RBX: 00007fa458615fa0 RCX: 00007fa45839aeb9
+ RDX: 0000000000000000 RSI: 00002000000000c0 RDI: 0000000000000004
+ RBP: 00007fa458408c1f R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+ R13: 00007fa458616038 R14: 00007fa458615fa0 R15: 00007fff0b59fae8
+ </TASK>
+
+Fixes: b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port")
+Reported-by: syzbot+d5d1b7343531d17bd3c5@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/aYrWbRp83MQR1ife@debil/T/#t
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Link: https://patch.msgid.link/20260213070031.1400003-2-nikolay@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_multicast.c | 45 ++++++++++++++++-----------------------
+ 1 file changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index 22d12e5459668..5855eb0502085 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -244,14 +244,11 @@ br_multicast_port_vid_to_port_ctx(struct net_bridge_port *port, u16 vid)
+
+ lockdep_assert_held_once(&port->br->multicast_lock);
+
+- if (!br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED))
+- return NULL;
+-
+ /* Take RCU to access the vlan. */
+ rcu_read_lock();
+
+ vlan = br_vlan_find(nbp_vlan_group_rcu(port), vid);
+- if (vlan && !br_multicast_port_ctx_vlan_disabled(&vlan->port_mcast_ctx))
++ if (vlan)
+ pmctx = &vlan->port_mcast_ctx;
+
+ rcu_read_unlock();
+@@ -701,7 +698,10 @@ br_multicast_port_ngroups_inc_one(struct net_bridge_mcast_port *pmctx,
+ u32 max = READ_ONCE(pmctx->mdb_max_entries);
+ u32 n = READ_ONCE(pmctx->mdb_n_entries);
+
+- if (max && n >= max) {
++ /* enforce the max limit when it's a port pmctx or a port-vlan pmctx
++ * with snooping enabled
++ */
++ if (!br_multicast_port_ctx_vlan_disabled(pmctx) && max && n >= max) {
+ NL_SET_ERR_MSG_FMT_MOD(extack, "%s is already in %u groups, and mcast_max_groups=%u",
+ what, n, max);
+ return -E2BIG;
+@@ -736,9 +736,7 @@ static int br_multicast_port_ngroups_inc(struct net_bridge_port *port,
+ return err;
+ }
+
+- /* Only count on the VLAN context if VID is given, and if snooping on
+- * that VLAN is enabled.
+- */
++ /* Only count on the VLAN context if VID is given */
+ if (!group->vid)
+ return 0;
+
+@@ -2011,6 +2009,18 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port,
+ timer_setup(&pmctx->ip6_own_query.timer,
+ br_ip6_multicast_port_query_expired, 0);
+ #endif
++ /* initialize mdb_n_entries if a new port vlan is being created */
++ if (vlan) {
++ struct net_bridge_port_group *pg;
++ u32 n = 0;
++
++ spin_lock_bh(&port->br->multicast_lock);
++ hlist_for_each_entry(pg, &port->mglist, mglist)
++ if (pg->key.addr.vid == vlan->vid)
++ n++;
++ WRITE_ONCE(pmctx->mdb_n_entries, n);
++ spin_unlock_bh(&port->br->multicast_lock);
++ }
+ }
+
+ void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx)
+@@ -2094,25 +2104,6 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
+ br_ip4_multicast_add_router(brmctx, pmctx);
+ br_ip6_multicast_add_router(brmctx, pmctx);
+ }
+-
+- if (br_multicast_port_ctx_is_vlan(pmctx)) {
+- struct net_bridge_port_group *pg;
+- u32 n = 0;
+-
+- /* The mcast_n_groups counter might be wrong. First,
+- * BR_VLFLAG_MCAST_ENABLED is toggled before temporary entries
+- * are flushed, thus mcast_n_groups after the toggle does not
+- * reflect the true values. And second, permanent entries added
+- * while BR_VLFLAG_MCAST_ENABLED was disabled, are not reflected
+- * either. Thus we have to refresh the counter.
+- */
+-
+- hlist_for_each_entry(pg, &pmctx->port->mglist, mglist) {
+- if (pg->key.addr.vid == pmctx->vlan->vid)
+- n++;
+- }
+- WRITE_ONCE(pmctx->mdb_n_entries, n);
+- }
+ }
+
+ static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
+--
+2.51.0
+
--- /dev/null
+From 3f1a49935226ecaceb8405bcb2ca4ec6b2b581f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:29:01 +0200
+Subject: net/mlx5: Fix misidentification of write combining CQE during poll
+ loop
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit d451994ebc7d4392610bd4b2ab339b255deb4143 ]
+
+The write combining completion poll loop uses usleep_range() which can
+sleep much longer than requested due to scheduler latency. Under load,
+we witnessed a 20ms+ delay until the process was rescheduled, causing
+the jiffies based timeout to expire while the thread is sleeping.
+
+The original do-while loop structure (poll, sleep, check timeout) would
+exit without a final poll when waking after timeout, missing a CQE that
+arrived during sleep.
+
+Instead of the open-coded while loop, use the kernel's poll_timeout_us()
+which always performs an additional check after the sleep expiration,
+and is less error-prone.
+
+Note: poll_timeout_us() doesn't accept a sleep range, by passing 10
+sleep_us the sleep range effectively changes from 2-10 to 3-10 usecs.
+
+Fixes: d98995b4bf98 ("net/mlx5: Reimplement write combining test")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-4-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/wc.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wc.c b/drivers/net/ethernet/mellanox/mlx5/core/wc.c
+index 05e5fd777d4f4..8701b7b6a2d51 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/wc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/wc.c
+@@ -2,6 +2,7 @@
+ // Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/mlx5/transobj.h>
+ #include "lib/clock.h"
+ #include "mlx5_core.h"
+@@ -14,7 +15,7 @@
+ #define TEST_WC_NUM_WQES 255
+ #define TEST_WC_LOG_CQ_SZ (order_base_2(TEST_WC_NUM_WQES))
+ #define TEST_WC_SQ_LOG_WQ_SZ TEST_WC_LOG_CQ_SZ
+-#define TEST_WC_POLLING_MAX_TIME_JIFFIES msecs_to_jiffies(100)
++#define TEST_WC_POLLING_MAX_TIME_USEC (100 * USEC_PER_MSEC)
+
+ struct mlx5_wc_cq {
+ /* data path - accessed per cqe */
+@@ -358,7 +359,6 @@ static int mlx5_wc_poll_cq(struct mlx5_wc_sq *sq)
+ static void mlx5_core_test_wc(struct mlx5_core_dev *mdev)
+ {
+ unsigned int offset = 0;
+- unsigned long expires;
+ struct mlx5_wc_sq *sq;
+ int i, err;
+
+@@ -388,13 +388,9 @@ static void mlx5_core_test_wc(struct mlx5_core_dev *mdev)
+
+ mlx5_wc_post_nop(sq, &offset, true);
+
+- expires = jiffies + TEST_WC_POLLING_MAX_TIME_JIFFIES;
+- do {
+- err = mlx5_wc_poll_cq(sq);
+- if (err)
+- usleep_range(2, 10);
+- } while (mdev->wc_state == MLX5_WC_STATE_UNINITIALIZED &&
+- time_is_after_jiffies(expires));
++ poll_timeout_us(mlx5_wc_poll_cq(sq),
++ mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED, 10,
++ TEST_WC_POLLING_MAX_TIME_USEC, false);
+
+ mlx5_wc_destroy_sq(sq);
+
+--
+2.51.0
+
--- /dev/null
+From 24678e834373904435601621dedb34fba2ea8a8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:28:59 +0200
+Subject: net/mlx5: Fix multiport device check over light SFs
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 47bf2e813817159f4d195be83a9b5a640ee6baec ]
+
+Driver is using num_vhca_ports capability to distinguish between
+multiport master device and multiport slave device. num_vhca_ports is a
+capability the driver sets according to the MAX num_vhca_ports
+capability reported by FW. On the other hand, light SFs doesn't set the
+above capbility.
+
+This leads to wrong results whenever light SFs is checking whether he is
+a multiport master or slave.
+
+Therefore, use the MAX capability to distinguish between master and
+slave devices.
+
+Fixes: e71383fb9cd1 ("net/mlx5: Light probe local SFs")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-2-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mlx5/driver.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index 5405ca1038f9e..85c2b3d358ec1 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -1274,12 +1274,12 @@ static inline bool mlx5_rl_is_supported(struct mlx5_core_dev *dev)
+ static inline int mlx5_core_is_mp_slave(struct mlx5_core_dev *dev)
+ {
+ return MLX5_CAP_GEN(dev, affiliate_nic_vport_criteria) &&
+- MLX5_CAP_GEN(dev, num_vhca_ports) <= 1;
++ MLX5_CAP_GEN_MAX(dev, num_vhca_ports) <= 1;
+ }
+
+ static inline int mlx5_core_is_mp_master(struct mlx5_core_dev *dev)
+ {
+- return MLX5_CAP_GEN(dev, num_vhca_ports) > 1;
++ return MLX5_CAP_GEN_MAX(dev, num_vhca_ports) > 1;
+ }
+
+ static inline int mlx5_core_mp_enabled(struct mlx5_core_dev *dev)
+--
+2.51.0
+
--- /dev/null
+From 73287f7ddbadea3aaf637e2b8efa7a92d198402b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:29:03 +0200
+Subject: net/mlx5e: Fix deadlocks between devlink and netdev instance locks
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 83ac0304a2d77519dae1e54c9713cbe1aedf19c9 ]
+
+In the mentioned "Fixes" commit, various work tasks triggering devlink
+health reporter recovery were switched to use netdev_trylock to protect
+against concurrent tear down of the channels being recovered. But this
+had the side effect of introducing potential deadlocks because of
+incorrect lock ordering.
+
+The correct lock order is described by the init flow:
+probe_one -> mlx5_init_one (acquires devlink lock)
+-> mlx5_init_one_devl_locked -> mlx5_register_device
+-> mlx5_rescan_drivers_locked -...-> mlx5e_probe -> _mlx5e_probe
+-> register_netdev (acquires rtnl lock)
+-> register_netdevice (acquires netdev lock)
+=> devlink lock -> rtnl lock -> netdev lock.
+
+But in the current recovery flow, the order is wrong:
+mlx5e_tx_err_cqe_work (acquires netdev lock)
+-> mlx5e_reporter_tx_err_cqe -> mlx5e_health_report
+-> devlink_health_report (acquires devlink lock => boom!)
+-> devlink_health_reporter_recover
+-> mlx5e_tx_reporter_recover -> mlx5e_tx_reporter_recover_from_ctx
+-> mlx5e_tx_reporter_err_cqe_recover
+
+The same pattern exists in:
+mlx5e_reporter_rx_timeout
+mlx5e_reporter_tx_ptpsq_unhealthy
+mlx5e_reporter_tx_timeout
+
+Fix these by moving the netdev_trylock calls from the work handlers
+lower in the call stack, in the respective recovery functions, where
+they are actually necessary.
+
+Fixes: 8f7b00307bf1 ("net/mlx5e: Convert mlx5 netdevs to instance locking")
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-6-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en/ptp.c | 14 -----
+ .../mellanox/mlx5/core/en/reporter_rx.c | 13 +++++
+ .../mellanox/mlx5/core/en/reporter_tx.c | 52 +++++++++++++++++--
+ .../net/ethernet/mellanox/mlx5/core/en_main.c | 40 --------------
+ 4 files changed, 61 insertions(+), 58 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+index c93ee969ea647..ec715b158a342 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+@@ -448,22 +448,8 @@ static void mlx5e_ptpsq_unhealthy_work(struct work_struct *work)
+ {
+ struct mlx5e_ptpsq *ptpsq =
+ container_of(work, struct mlx5e_ptpsq, report_unhealthy_work);
+- struct mlx5e_txqsq *sq = &ptpsq->txqsq;
+-
+- /* Recovering the PTP SQ means re-enabling NAPI, which requires the
+- * netdev instance lock. However, SQ closing has to wait for this work
+- * task to finish while also holding the same lock. So either get the
+- * lock or find that the SQ is no longer enabled and thus this work is
+- * not relevant anymore.
+- */
+- while (!netdev_trylock(sq->netdev)) {
+- if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state))
+- return;
+- msleep(20);
+- }
+
+ mlx5e_reporter_tx_ptpsq_unhealthy(ptpsq);
+- netdev_unlock(sq->netdev);
+ }
+
+ static int mlx5e_ptp_open_txqsq(struct mlx5e_ptp *c, u32 tisn,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
+index b1415992ffa24..a09a7c05820d6 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
+@@ -1,6 +1,8 @@
+ // SPDX-License-Identifier: GPL-2.0
+ // Copyright (c) 2019 Mellanox Technologies.
+
++#include <net/netdev_lock.h>
++
+ #include "health.h"
+ #include "params.h"
+ #include "txrx.h"
+@@ -177,6 +179,16 @@ static int mlx5e_rx_reporter_timeout_recover(void *ctx)
+ rq = ctx;
+ priv = rq->priv;
+
++ /* Acquire netdev instance lock to synchronize with channel close and
++ * reopen flows. Either successfully obtain the lock, or detect that
++ * channels are closing for another reason, making this work no longer
++ * necessary.
++ */
++ while (!netdev_trylock(rq->netdev)) {
++ if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &rq->priv->state))
++ return 0;
++ msleep(20);
++ }
+ mutex_lock(&priv->state_lock);
+
+ eq = rq->cq.mcq.eq;
+@@ -186,6 +198,7 @@ static int mlx5e_rx_reporter_timeout_recover(void *ctx)
+ clear_bit(MLX5E_SQ_STATE_ENABLED, &rq->icosq->state);
+
+ mutex_unlock(&priv->state_lock);
++ netdev_unlock(rq->netdev);
+
+ return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+index 9e2cf191ed308..9f6454102cf79 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+@@ -1,6 +1,8 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+ /* Copyright (c) 2019 Mellanox Technologies. */
+
++#include <net/netdev_lock.h>
++
+ #include "health.h"
+ #include "en/ptp.h"
+ #include "en/devlink.h"
+@@ -78,6 +80,18 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx)
+ if (!test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state))
+ return 0;
+
++ /* Recovering queues means re-enabling NAPI, which requires the netdev
++ * instance lock. However, SQ closing flows have to wait for work tasks
++ * to finish while also holding the netdev instance lock. So either get
++ * the lock or find that the SQ is no longer enabled and thus this work
++ * is not relevant anymore.
++ */
++ while (!netdev_trylock(dev)) {
++ if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state))
++ return 0;
++ msleep(20);
++ }
++
+ err = mlx5_core_query_sq_state(mdev, sq->sqn, &state);
+ if (err) {
+ netdev_err(dev, "Failed to query SQ 0x%x state. err = %d\n",
+@@ -113,9 +127,11 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx)
+ else
+ mlx5e_trigger_napi_sched(sq->cq.napi);
+
++ netdev_unlock(dev);
+ return 0;
+ out:
+ clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state);
++ netdev_unlock(dev);
+ return err;
+ }
+
+@@ -136,10 +152,24 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx)
+ sq = to_ctx->sq;
+ eq = sq->cq.mcq.eq;
+ priv = sq->priv;
++
++ /* Recovering the TX queues implies re-enabling NAPI, which requires
++ * the netdev instance lock.
++ * However, channel closing flows have to wait for this work to finish
++ * while holding the same lock. So either get the lock or find that
++ * channels are being closed for other reason and this work is not
++ * relevant anymore.
++ */
++ while (!netdev_trylock(sq->netdev)) {
++ if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state))
++ return 0;
++ msleep(20);
++ }
++
+ err = mlx5e_health_channel_eq_recover(sq->netdev, eq, sq->cq.ch_stats);
+ if (!err) {
+ to_ctx->status = 0; /* this sq recovered */
+- return err;
++ goto out;
+ }
+
+ mutex_lock(&priv->state_lock);
+@@ -147,7 +177,7 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx)
+ mutex_unlock(&priv->state_lock);
+ if (!err) {
+ to_ctx->status = 1; /* all channels recovered */
+- return err;
++ goto out;
+ }
+
+ to_ctx->status = err;
+@@ -155,7 +185,8 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx)
+ netdev_err(priv->netdev,
+ "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n",
+ err);
+-
++out:
++ netdev_unlock(sq->netdev);
+ return err;
+ }
+
+@@ -172,10 +203,22 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx)
+ return 0;
+
+ priv = ptpsq->txqsq.priv;
++ netdev = priv->netdev;
++
++ /* Recovering the PTP SQ means re-enabling NAPI, which requires the
++ * netdev instance lock. However, SQ closing has to wait for this work
++ * task to finish while also holding the same lock. So either get the
++ * lock or find that the SQ is no longer enabled and thus this work is
++ * not relevant anymore.
++ */
++ while (!netdev_trylock(netdev)) {
++ if (!test_bit(MLX5E_SQ_STATE_ENABLED, &ptpsq->txqsq.state))
++ return 0;
++ msleep(20);
++ }
+
+ mutex_lock(&priv->state_lock);
+ chs = &priv->channels;
+- netdev = priv->netdev;
+
+ carrier_ok = netif_carrier_ok(netdev);
+ netif_carrier_off(netdev);
+@@ -192,6 +235,7 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx)
+ netif_carrier_on(netdev);
+
+ mutex_unlock(&priv->state_lock);
++ netdev_unlock(netdev);
+
+ return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 59e17b41c3a67..cb993ad2d9ad9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -688,19 +688,7 @@ static void mlx5e_rq_timeout_work(struct work_struct *timeout_work)
+ struct mlx5e_rq,
+ rx_timeout_work);
+
+- /* Acquire netdev instance lock to synchronize with channel close and
+- * reopen flows. Either successfully obtain the lock, or detect that
+- * channels are closing for another reason, making this work no longer
+- * necessary.
+- */
+- while (!netdev_trylock(rq->netdev)) {
+- if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &rq->priv->state))
+- return;
+- msleep(20);
+- }
+-
+ mlx5e_reporter_rx_timeout(rq);
+- netdev_unlock(rq->netdev);
+ }
+
+ static int mlx5e_alloc_mpwqe_rq_drop_page(struct mlx5e_rq *rq)
+@@ -1997,20 +1985,7 @@ void mlx5e_tx_err_cqe_work(struct work_struct *recover_work)
+ struct mlx5e_txqsq *sq = container_of(recover_work, struct mlx5e_txqsq,
+ recover_work);
+
+- /* Recovering queues means re-enabling NAPI, which requires the netdev
+- * instance lock. However, SQ closing flows have to wait for work tasks
+- * to finish while also holding the netdev instance lock. So either get
+- * the lock or find that the SQ is no longer enabled and thus this work
+- * is not relevant anymore.
+- */
+- while (!netdev_trylock(sq->netdev)) {
+- if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state))
+- return;
+- msleep(20);
+- }
+-
+ mlx5e_reporter_tx_err_cqe(sq);
+- netdev_unlock(sq->netdev);
+ }
+
+ static struct dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode)
+@@ -5102,19 +5077,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work)
+ struct net_device *netdev = priv->netdev;
+ int i;
+
+- /* Recovering the TX queues implies re-enabling NAPI, which requires
+- * the netdev instance lock.
+- * However, channel closing flows have to wait for this work to finish
+- * while holding the same lock. So either get the lock or find that
+- * channels are being closed for other reason and this work is not
+- * relevant anymore.
+- */
+- while (!netdev_trylock(netdev)) {
+- if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state))
+- return;
+- msleep(20);
+- }
+-
+ for (i = 0; i < netdev->real_num_tx_queues; i++) {
+ struct netdev_queue *dev_queue =
+ netdev_get_tx_queue(netdev, i);
+@@ -5127,8 +5089,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work)
+ /* break if tried to reopened channels */
+ break;
+ }
+-
+- netdev_unlock(netdev);
+ }
+
+ static void mlx5e_tx_timeout(struct net_device *dev, unsigned int txqueue)
+--
+2.51.0
+
--- /dev/null
+From 9a24c77a520472de671e9b5eaf6fe9f66dc0ce8f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:29:04 +0200
+Subject: net/mlx5e: Use unsigned for mlx5e_get_max_num_channels
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 57a94d4b22b0c6cc5d601e6b6238d78fb923d991 ]
+
+The max number of channels is always an unsigned int, use the correct
+type to fix compilation errors done with strict type checking, e.g.:
+
+error: call to ‘__compiletime_assert_1110’ declared with attribute
+ error: min(mlx5e_get_devlink_param_num_doorbells(mdev),
+ mlx5e_get_max_num_channels(mdev)) signedness error
+
+Fixes: 74a8dadac17e ("net/mlx5e: Preparations for supporting larger number of channels")
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-7-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index b34b85539f3b1..5bced924a24fb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -179,7 +179,8 @@ static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size)
+ }
+
+ /* Use this function to get max num channels (rxqs/txqs) only to create netdev */
+-static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
++static inline unsigned int
++mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
+ {
+ return is_kdump_kernel() ?
+ MLX5E_MIN_NUM_CHANNELS :
+--
+2.51.0
+
--- /dev/null
+From 453eef1864f47a3c47532d19c1f48a9c17a3487d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:02 +0000
+Subject: net: mscc: ocelot: add missing lock protection in
+ ocelot_port_xmit_inj()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 026f6513c5880c2c89e38ad66bbec2868f978605 ]
+
+ocelot_port_xmit_inj() calls ocelot_can_inject() and
+ocelot_port_inject_frame() without holding the injection group lock.
+Both functions contain lockdep_assert_held() for the injection lock,
+and the correct caller felix_port_deferred_xmit() properly acquires
+the lock using ocelot_lock_inj_grp() before calling these functions.
+
+Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register
+injection path to fix the missing lock protection. The FDMA path is not
+affected as it uses its own locking mechanism.
+
+Fixes: c5e12ac3beb0 ("net: mscc: ocelot: serialize access to the injection/extraction groups")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-4-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index a7966c174b2e2..1b82693204640 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb,
+ int port = priv->port.index;
+ u32 rew_op = 0;
+
+- if (!ocelot_can_inject(ocelot, 0))
++ ocelot_lock_inj_grp(ocelot, 0);
++
++ if (!ocelot_can_inject(ocelot, 0)) {
++ ocelot_unlock_inj_grp(ocelot, 0);
+ return NETDEV_TX_BUSY;
++ }
+
+- if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) {
++ ocelot_unlock_inj_grp(ocelot, 0);
+ return NETDEV_TX_OK;
++ }
+
+ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
++ ocelot_unlock_inj_grp(ocelot, 0);
++
+ consume_skb(skb);
+
+ return NETDEV_TX_OK;
+--
+2.51.0
+
--- /dev/null
+From d55e2f93e6fb62286d58941cb26d79a16ffe4593 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:00 +0000
+Subject: net: mscc: ocelot: extract ocelot_xmit_timestamp() helper
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 29372f07f7969a2f0490793226ecf6c8c6bde0fa ]
+
+Extract the PTP timestamp handling logic from ocelot_port_xmit() into a
+separate ocelot_xmit_timestamp() helper function. This is a pure
+refactor with no behavioral change.
+
+The helper returns false if the skb was consumed (freed) due to a
+timestamp request failure, and true if the caller should continue with
+frame injection. The rew_op value is returned via pointer.
+
+This prepares for splitting ocelot_port_xmit() into separate FDMA and
+register injection paths in a subsequent patch.
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-2-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 36 ++++++++++++++++----------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index 469784d3a1a67..ef4a6c768de9b 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -551,33 +551,41 @@ static int ocelot_port_stop(struct net_device *dev)
+ return 0;
+ }
+
+-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port,
++ struct sk_buff *skb, u32 *rew_op)
+ {
+- struct ocelot_port_private *priv = netdev_priv(dev);
+- struct ocelot_port *ocelot_port = &priv->port;
+- struct ocelot *ocelot = ocelot_port->ocelot;
+- int port = priv->port.index;
+- u32 rew_op = 0;
+-
+- if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
+- !ocelot_can_inject(ocelot, 0))
+- return NETDEV_TX_BUSY;
+-
+- /* Check if timestamping is needed */
+ if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ struct sk_buff *clone = NULL;
+
+ if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) {
+ kfree_skb(skb);
+- return NETDEV_TX_OK;
++ return false;
+ }
+
+ if (clone)
+ OCELOT_SKB_CB(skb)->clone = clone;
+
+- rew_op = ocelot_ptp_rew_op(skb);
++ *rew_op = ocelot_ptp_rew_op(skb);
+ }
+
++ return true;
++}
++
++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ struct ocelot_port_private *priv = netdev_priv(dev);
++ struct ocelot_port *ocelot_port = &priv->port;
++ struct ocelot *ocelot = ocelot_port->ocelot;
++ int port = priv->port.index;
++ u32 rew_op = 0;
++
++ if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
++ !ocelot_can_inject(ocelot, 0))
++ return NETDEV_TX_BUSY;
++
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ return NETDEV_TX_OK;
++
+ if (static_branch_unlikely(&ocelot_fdma_enabled)) {
+ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
+ } else {
+--
+2.51.0
+
--- /dev/null
+From b0e63116d9f10b8c0030d11085e4f9ba15df0adb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:01 +0000
+Subject: net: mscc: ocelot: split xmit into FDMA and register injection paths
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 47f79b20e7fb885aa1623b759a68e8e27401ec4d ]
+
+Split ocelot_port_xmit() into two separate functions:
+- ocelot_port_xmit_fdma(): handles the FDMA injection path
+- ocelot_port_xmit_inj(): handles the register-based injection path
+
+The top-level ocelot_port_xmit() now dispatches to the appropriate
+function based on the ocelot_fdma_enabled static key.
+
+This is a pure refactor with no behavioral change. Separating the two
+code paths makes each one simpler and prepares for adding proper locking
+to the register injection path without affecting the FDMA path.
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-3-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 39 ++++++++++++++++++++------
+ 1 file changed, 30 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index ef4a6c768de9b..a7966c174b2e2 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -571,7 +571,25 @@ static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port,
+ return true;
+ }
+
+-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb,
++ struct net_device *dev)
++{
++ struct ocelot_port_private *priv = netdev_priv(dev);
++ struct ocelot_port *ocelot_port = &priv->port;
++ struct ocelot *ocelot = ocelot_port->ocelot;
++ int port = priv->port.index;
++ u32 rew_op = 0;
++
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ return NETDEV_TX_OK;
++
++ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
++
++ return NETDEV_TX_OK;
++}
++
++static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb,
++ struct net_device *dev)
+ {
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+@@ -579,24 +597,27 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
+ int port = priv->port.index;
+ u32 rew_op = 0;
+
+- if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
+- !ocelot_can_inject(ocelot, 0))
++ if (!ocelot_can_inject(ocelot, 0))
+ return NETDEV_TX_BUSY;
+
+ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
+ return NETDEV_TX_OK;
+
+- if (static_branch_unlikely(&ocelot_fdma_enabled)) {
+- ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
+- } else {
+- ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
++ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
+- consume_skb(skb);
+- }
++ consume_skb(skb);
+
+ return NETDEV_TX_OK;
+ }
+
++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ if (static_branch_unlikely(&ocelot_fdma_enabled))
++ return ocelot_port_xmit_fdma(skb, dev);
++
++ return ocelot_port_xmit_inj(skb, dev);
++}
++
+ enum ocelot_action_type {
+ OCELOT_MACT_LEARN,
+ OCELOT_MACT_FORGET,
+--
+2.51.0
+
--- /dev/null
+From 65bdeecbcc5aa9d6ae751323d9f81e7de3819c22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 11:54:54 +0100
+Subject: net: psp: select CONFIG_SKB_EXTENSIONS
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 6e980df452169f82674f2e650079c1fe0aee343d ]
+
+psp now uses skb extensions, failing to build when that is disabled:
+
+In file included from include/net/psp.h:7,
+ from net/psp/psp_sock.c:9:
+include/net/psp/functions.h: In function '__psp_skb_coalesce_diff':
+include/net/psp/functions.h:60:13: error: implicit declaration of function 'skb_ext_find'; did you mean 'skb_ext_copy'? [-Wimplicit-function-declaration]
+ 60 | a = skb_ext_find(one, SKB_EXT_PSP);
+ | ^~~~~~~~~~~~
+ | skb_ext_copy
+include/net/psp/functions.h:60:31: error: 'SKB_EXT_PSP' undeclared (first use in this function)
+ 60 | a = skb_ext_find(one, SKB_EXT_PSP);
+ | ^~~~~~~~~~~
+include/net/psp/functions.h:60:31: note: each undeclared identifier is reported only once for each function it appears in
+include/net/psp/functions.h: In function '__psp_sk_rx_policy_check':
+include/net/psp/functions.h:94:53: error: 'SKB_EXT_PSP' undeclared (first use in this function)
+ 94 | struct psp_skb_ext *pse = skb_ext_find(skb, SKB_EXT_PSP);
+ | ^~~~~~~~~~~
+net/psp/psp_sock.c: In function 'psp_sock_recv_queue_check':
+net/psp/psp_sock.c:164:41: error: 'SKB_EXT_PSP' undeclared (first use in this function)
+ 164 | pse = skb_ext_find(skb, SKB_EXT_PSP);
+ | ^~~~~~~~~~~
+
+Select the Kconfig symbol as we do from its other users.
+
+Fixes: 6b46ca260e22 ("net: psp: add socket security association code")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Daniel Zahka <daniel.zahka@gmail.com>
+Link: https://patch.msgid.link/20260216105500.2382181-1-arnd@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/psp/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/psp/Kconfig b/net/psp/Kconfig
+index 371e8771f3bd3..84d6b0f254606 100644
+--- a/net/psp/Kconfig
++++ b/net/psp/Kconfig
+@@ -6,6 +6,7 @@ config INET_PSP
+ bool "PSP Security Protocol support"
+ depends on INET
+ select SKB_DECRYPTED
++ select SKB_EXTENSIONS
+ select SOCK_VALIDATE_XMIT
+ help
+ Enable kernel support for the PSP Security Protocol (PSP).
+--
+2.51.0
+
--- /dev/null
+From 0e4f5ddcbfffd9a7ead29ab6108e49c00e780b56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:54:09 -0700
+Subject: net/rds: rds_sendmsg should not discard payload_len
+
+From: Allison Henderson <achender@kernel.org>
+
+[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ]
+
+Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with
+connection teardown") modifies rds_sendmsg to avoid enqueueing work
+while a tear down is in progress. However, it also changed the return
+value of rds_sendmsg to that of rds_send_xmit instead of the
+payload_len. This means the user may incorrectly receive errno values
+when it should have simply received a payload of 0 while the peer
+attempts a reconnections. So this patch corrects the teardown handling
+code to only use the out error path in that case, thus restoring the
+original payload_len return value.
+
+Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/send.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/rds/send.c b/net/rds/send.c
+index 0b3d0ef2f008b..071c5dca969a2 100644
+--- a/net/rds/send.c
++++ b/net/rds/send.c
+@@ -1382,9 +1382,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
+ else
+ queue_delayed_work(rds_wq, &cpath->cp_send_w, 1);
+ rcu_read_unlock();
++
++ if (ret)
++ goto out;
+ }
+- if (ret)
+- goto out;
++
+ rds_message_put(rm);
+
+ for (ind = 0; ind < vct.indx; ind++)
+--
+2.51.0
+
--- /dev/null
+From 5cd4b939e7fe7e93e85a45cf39130aef3b12cb94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 12:56:39 +0100
+Subject: net: remove WARN_ON_ONCE when accessing forward path array
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ]
+
+Although unlikely, recent support for IPIP tunnels increases chances of
+reaching this WARN_ON_ONCE if userspace manages to build a sufficiently
+long forward path.
+
+Remove it.
+
+Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 5b536860138d1..ff70c902a4196 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -738,7 +738,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack)
+ {
+ int k = stack->num_paths++;
+
+- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX))
++ if (k >= NET_DEVICE_PATH_STACK_MAX)
+ return NULL;
+
+ return &stack->path[k];
+--
+2.51.0
+
--- /dev/null
+From c32577e898ced8ffd9cc183f2d4006c5903cfc8c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 14:44:01 +0100
+Subject: net: sparx5/lan969x: fix DWRR cost max to match hardware register
+ width
+
+From: Daniel Machon <daniel.machon@microchip.com>
+
+[ Upstream commit 6c28aa8dfdf24f554d4c5d4ff7d723a95360d94a ]
+
+DWRR (Deficit Weighted Round Robin) scheduling distributes bandwidth
+across traffic classes based on per-queue cost values, where lower cost
+means higher bandwidth share.
+
+The SPX5_DWRR_COST_MAX constant is 63 (6 bits) but the hardware
+register field HSCH_DWRR_ENTRY_DWRR_COST is GENMASK(24, 20), only
+5 bits wide (max 31). This causes sparx5_weight_to_hw_cost() to
+compute cost values that silently overflow via FIELD_PREP, resulting
+in incorrect scheduling weights.
+
+Set SPX5_DWRR_COST_MAX to 31 to match the hardware register width.
+
+Fixes: 211225428d65 ("net: microchip: sparx5: add support for offloading ets qdisc")
+Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260210-sparx5-fix-dwrr-cost-max-v1-1-58fbdbc25652@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
+index 1231a80335d7b..04f76f1e23f60 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
+@@ -35,7 +35,7 @@
+ #define SPX5_SE_BURST_UNIT 4096
+
+ /* Dwrr */
+-#define SPX5_DWRR_COST_MAX 63
++#define SPX5_DWRR_COST_MAX 31
+
+ struct sparx5_shaper {
+ u32 mode;
+--
+2.51.0
+
--- /dev/null
+From 0db44c82970f7a71683e80d4424f1bdd1f82e0f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 12:02:30 +0100
+Subject: net: sparx5/lan969x: fix PTP clock max_adj value
+
+From: Daniel Machon <daniel.machon@microchip.com>
+
+[ Upstream commit a49d2a2c37a6252c41cbdd505f9d1c58d5a3817a ]
+
+The max_adj field in ptp_clock_info tells userspace how much the PHC
+clock frequency can be adjusted. ptp4l reads this and will never request
+a correction larger than max_adj.
+
+On both sparx5 and lan969x the clock offset may never converge because
+the servo needs a frequency correction larger than the current max_adj
+of 200000 (200 ppm) allows. The servo rails at the max and the offset
+stays in the tens of microseconds.
+
+The hardware has no inherent max adjustment limit; frequency correction
+is done by writing a 64-bit clock period increment to CLK_PER_CFG, and
+the register has plenty of range. The 200000 value was just an overly
+conservative software limit. The max_adj is shared between sparx5 and
+lan969x, and the increased value is safe for both.
+
+Fix this by increasing max_adj to 10000000 (10000 ppm), giving the
+servo sufficient headroom.
+
+Fixes: 0933bd04047c ("net: sparx5: Add support for ptp clocks")
+Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260212-sparx5-ptp-max-adj-v2-v1-1-06b200e50ce3@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+index 2f168700f63c1..8b2e07821a950 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+@@ -576,7 +576,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+ static struct ptp_clock_info sparx5_ptp_clock_info = {
+ .owner = THIS_MODULE,
+ .name = "sparx5 ptp",
+- .max_adj = 200000,
++ .max_adj = 10000000,
+ .gettime64 = sparx5_ptp_gettime64,
+ .settime64 = sparx5_ptp_settime64,
+ .adjtime = sparx5_ptp_adjtime,
+--
+2.51.0
+
--- /dev/null
+From 6755394ddd4c927dba8e0e244486721da4d3b8b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 17:50:32 -0500
+Subject: net: stmmac: fix oops when split header is enabled
+
+From: Jie Zhang <jzhang918@gmail.com>
+
+[ Upstream commit babab1b42ed68877ef669a08384becf281ad2582 ]
+
+For GMAC4, when split header is enabled, in some rare cases, the
+hardware does not fill buf2 of the first descriptor with payload.
+Thus we cannot assume buf2 is always fully filled if it is not
+the last descriptor. Otherwise, the length of buf2 of the second
+descriptor will be calculated wrong and cause an oops:
+
+Unable to handle kernel paging request at virtual address ffff00019246bfc0
+...
+x2 : 0000000000000040 x1 : ffff00019246bfc0 x0 : ffff00009246c000
+Call trace:
+ dcache_inval_poc+0x28/0x58 (P)
+ dma_direct_sync_single_for_cpu+0x38/0x6c
+ __dma_sync_single_for_cpu+0x34/0x6c
+ stmmac_napi_poll_rx+0x8f0/0xb60
+ __napi_poll.constprop.0+0x30/0x144
+ net_rx_action+0x160/0x274
+ handle_softirqs+0x1b8/0x1fc
+...
+
+To fix this, the PL bit-field in RDES3 register is used for all
+descriptors, whether it is the last descriptor or not.
+
+Fixes: ec222003bd94 ("net: stmmac: Prepare to add Split Header support")
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jie Zhang <jie.zhang@analog.com>
+Link: https://patch.msgid.link/20260209225037.589130-1-jie.zhang@analog.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 ++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index a38976c65149c..46299b7925b44 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -4880,13 +4880,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
+ if (!priv->sph)
+ return 0;
+
+- /* Not last descriptor */
+- if (status & rx_not_ls)
++ /* For GMAC4, when split header is enabled, in some rare cases, the
++ * hardware does not fill buf2 of the first descriptor with payload.
++ * Thus we cannot assume buf2 is always fully filled if it is not
++ * the last descriptor. Otherwise, the length of buf2 of the second
++ * descriptor will be calculated wrong and cause an oops.
++ *
++ * If this is the last descriptor, 'plen' is the length of the
++ * received packet that was transferred to system memory.
++ * Otherwise, it is the accumulated number of bytes that have been
++ * transferred for the current packet.
++ *
++ * Thus 'plen - len' always gives the correct length of buf2.
++ */
++
++ /* Not GMAC4 and not last descriptor */
++ if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls))
+ return priv->dma_conf.dma_buf_sz;
+
++ /* GMAC4 or last descriptor */
+ plen = stmmac_get_rx_frame_len(priv, p, coe);
+
+- /* Last descriptor */
+ return plen - len;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 6ab31bf74b22ee9ace5cfdb9dd826d7ad0feb025 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Oct 2025 15:36:46 +0100
+Subject: net: stmmac: remove broken PCS code
+
+From: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit 813882ae22756bcf9645d405e045c60e5aab0a93 ]
+
+Changing the netif_carrier_*() state behind phylink's back has always
+been prohibited because it messes up with phylinks state tracking, and
+means that phylink no longer guarantees to call the mac_link_down()
+and mac_link_up() methods at the appropriate times. This was later
+documented in the sfp-phylink network driver conversion guide.
+
+stmmac was converted to phylink in 2019, but nothing was done with the
+"PCS" code. Since then, apart from the updates as part of phylink
+development, nothing has happened with stmmac to improve its use of
+phylink, or even to address this point.
+
+A couple of years ago, a has_integrated_pcs boolean was added by Bart,
+which later became the STMMAC_FLAG_HAS_INTEGRATED_PCS flag, to avoid
+manipulating the netif_carrier_*() state. This flag is mis-named,
+because whenever the stmmac is synthesized for its native SGMII, TBI
+or RTBI interfaces, it has an "integrated PCS". This boolean/flag
+actually means "ignore the status from the integrated PCS".
+
+Discussing with Bart, the reasons for this are lost to the winds of
+time (which is why we should always document the reasons in the commit
+message.)
+
+RGMII also has in-band status, and the dwmac cores and stmmac code
+supports this but with one bug that saves the day.
+
+When dwmac cores are synthesised for RGMII only, they do not contain
+an integrated PCS, and so priv->dma_cap.pcs is clear, which prevents
+(incorrectly) the "RGMII PCS" being used, meaning we don't read the
+in-band status. However, a core synthesised for RGMII and also SGMII,
+TBI or RTBI will have this capability bit set, thus making these
+code paths reachable.
+
+The Jetson Xavier NX uses RGMII mode to talk to its PHY, and removing
+the incorrect check for priv->dma_cap.pcs reveals the theortical issue
+with netif_carrier_*() manipulation is real:
+
+dwc-eth-dwmac 2490000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
+dwc-eth-dwmac 2490000.ethernet eth0: PHY [stmmac-0:00] driver [RTL8211F Gigabit Ethernet] (irq=141)
+dwc-eth-dwmac 2490000.ethernet eth0: No Safety Features support found
+dwc-eth-dwmac 2490000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported
+dwc-eth-dwmac 2490000.ethernet eth0: registered PTP clock
+dwc-eth-dwmac 2490000.ethernet eth0: configuring for phy/rgmii-id link mode
+8021q: adding VLAN 0 to HW filter on device eth0
+dwc-eth-dwmac 2490000.ethernet eth0: Adding VLAN ID 0 is not supported
+Link is Up - 1000/Full
+Link is Down
+Link is Up - 1000/Full
+
+This looks good until one realises that the phylink "Link" status
+messages are missing, even when the RJ45 cable is reconnected. Nothing
+one can do results in the interface working. The interrupt handler
+(which prints those "Link is" messages) always wins over phylink's
+resolve worker, meaning phylink never calls the mac_link_up() nor
+mac_link_down() methods.
+
+eth0 also sees no traffic received, and is unable to obtain a DHCP
+address:
+
+3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group defa
+ult qlen 1000
+ link/ether e6:d3:6a:e6:92:de brd ff:ff:ff:ff:ff:ff
+ RX: bytes packets errors dropped overrun mcast
+ 0 0 0 0 0 0
+ TX: bytes packets errors dropped carrier collsns
+ 27686 149 0 0 0 0
+
+With the STMMAC_FLAG_HAS_INTEGRATED_PCS flag set, which disables the
+netif_carrier_*() manipulation then stmmac works normally:
+
+dwc-eth-dwmac 2490000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
+dwc-eth-dwmac 2490000.ethernet eth0: PHY [stmmac-0:00] driver [RTL8211F Gigabit Ethernet] (irq=141)
+dwc-eth-dwmac 2490000.ethernet eth0: No Safety Features support found
+dwc-eth-dwmac 2490000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported
+dwc-eth-dwmac 2490000.ethernet eth0: registered PTP clock
+dwc-eth-dwmac 2490000.ethernet eth0: configuring for phy/rgmii-id link mode
+8021q: adding VLAN 0 to HW filter on device eth0
+dwc-eth-dwmac 2490000.ethernet eth0: Adding VLAN ID 0 is not supported
+Link is Up - 1000/Full
+dwc-eth-dwmac 2490000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx
+
+and packets can be transferred.
+
+This clearly shows that when priv->hw->pcs is set, but
+STMMAC_FLAG_HAS_INTEGRATED_PCS is clear, the driver reliably fails.
+
+Discovering whether a platform falls into this is impossible as
+parsing all the dtsi and dts files to find out which use the stmmac
+driver, whether any of them use RGMII or SGMII and also depends
+whether an external interface is being used. The kernel likely
+doesn't contain all dts files either.
+
+The only driver that sets this flag uses the qcom,sa8775p-ethqos
+compatible, and uses SGMII or 2500BASE-X.
+
+but these are saved from this problem by the incorrect check for
+priv->dma_cap.pcs.
+
+So, we have to assume that for every other platform that uses SGMII
+with stmmac is using an external PCS.
+
+Moreover, ethtool output can be incorrect. With the full-duplex link
+negotiated, ethtool reports:
+
+ Speed: 1000Mb/s
+ Duplex: Half
+
+because with dwmac4, the full-duplex bit is in bit 16 of the status,
+priv->xstats.pcs_duplex becomes BIT(16) for full duplex, but the
+ethtool ksettings duplex member is u8 - so becomes zero. Moreover,
+the supported, advertised and link partner modes are all "not
+reported".
+
+Finally, ksettings_set() won't be able to set the advertisement on
+a PHY if this PCS code is activated, which is incorrect when SGMII
+is used with a PHY.
+
+Thus, remove:
+1. the incorrect netif_carrier_*() manipulation.
+2. the broken ethtool ksettings code.
+
+Given that all uses of STMMAC_FLAG_HAS_INTEGRATED_PCS are now gone,
+remove the flag from stmmac.h and dwmac-qcom-ethqos.c.
+
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Tested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
+Link: https://patch.msgid.link/E1v9P5y-0000000AolC-1QWH@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: babab1b42ed6 ("net: stmmac: fix oops when split header is enabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../stmicro/stmmac/dwmac-qcom-ethqos.c | 4 --
+ .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 55 -------------------
+ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 9 ---
+ include/linux/stmmac.h | 1 -
+ 4 files changed, 69 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+index d8fd4d8f6ced7..f62825220cf70 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+@@ -96,7 +96,6 @@ struct ethqos_emac_driver_data {
+ bool rgmii_config_loopback_en;
+ bool has_emac_ge_3;
+ const char *link_clk_name;
+- bool has_integrated_pcs;
+ u32 dma_addr_width;
+ struct dwmac4_addrs dwmac4_addrs;
+ bool needs_sgmii_loopback;
+@@ -282,7 +281,6 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
+ .rgmii_config_loopback_en = false,
+ .has_emac_ge_3 = true,
+ .link_clk_name = "phyaux",
+- .has_integrated_pcs = true,
+ .needs_sgmii_loopback = true,
+ .dma_addr_width = 36,
+ .dwmac4_addrs = {
+@@ -856,8 +854,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
+ plat_dat->flags |= STMMAC_FLAG_TSO_EN;
+ if (of_device_is_compatible(np, "qcom,qcs404-ethqos"))
+ plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI;
+- if (data->has_integrated_pcs)
+- plat_dat->flags |= STMMAC_FLAG_HAS_INTEGRATED_PCS;
+ if (data->dma_addr_width)
+ plat_dat->host_dma_width = data->dma_addr_width;
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index 39fa1ec92f82f..d89662b48087e 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -322,47 +322,6 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev,
+ {
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+- if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) &&
+- (priv->hw->pcs & STMMAC_PCS_RGMII ||
+- priv->hw->pcs & STMMAC_PCS_SGMII)) {
+- u32 supported, advertising, lp_advertising;
+-
+- if (!priv->xstats.pcs_link) {
+- cmd->base.speed = SPEED_UNKNOWN;
+- cmd->base.duplex = DUPLEX_UNKNOWN;
+- return 0;
+- }
+- cmd->base.duplex = priv->xstats.pcs_duplex;
+-
+- cmd->base.speed = priv->xstats.pcs_speed;
+-
+- /* Encoding of PSE bits is defined in 802.3z, 37.2.1.4 */
+-
+- ethtool_convert_link_mode_to_legacy_u32(
+- &supported, cmd->link_modes.supported);
+- ethtool_convert_link_mode_to_legacy_u32(
+- &advertising, cmd->link_modes.advertising);
+- ethtool_convert_link_mode_to_legacy_u32(
+- &lp_advertising, cmd->link_modes.lp_advertising);
+-
+- /* Reg49[3] always set because ANE is always supported */
+- cmd->base.autoneg = ADVERTISED_Autoneg;
+- supported |= SUPPORTED_Autoneg;
+- advertising |= ADVERTISED_Autoneg;
+- lp_advertising |= ADVERTISED_Autoneg;
+-
+- cmd->base.port = PORT_OTHER;
+-
+- ethtool_convert_legacy_u32_to_link_mode(
+- cmd->link_modes.supported, supported);
+- ethtool_convert_legacy_u32_to_link_mode(
+- cmd->link_modes.advertising, advertising);
+- ethtool_convert_legacy_u32_to_link_mode(
+- cmd->link_modes.lp_advertising, lp_advertising);
+-
+- return 0;
+- }
+-
+ return phylink_ethtool_ksettings_get(priv->phylink, cmd);
+ }
+
+@@ -372,20 +331,6 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev,
+ {
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+- if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) &&
+- (priv->hw->pcs & STMMAC_PCS_RGMII ||
+- priv->hw->pcs & STMMAC_PCS_SGMII)) {
+- /* Only support ANE */
+- if (cmd->base.autoneg != AUTONEG_ENABLE)
+- return -EINVAL;
+-
+- mutex_lock(&priv->lock);
+- stmmac_pcs_ctrl_ane(priv, 1, priv->hw->ps, 0);
+- mutex_unlock(&priv->lock);
+-
+- return 0;
+- }
+-
+ return phylink_ethtool_ksettings_set(priv->phylink, cmd);
+ }
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 0dd17179c85d2..e707abc35e2de 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -6012,15 +6012,6 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv)
+ for (queue = 0; queue < queues_count; queue++)
+ stmmac_host_mtl_irq_status(priv, priv->hw, queue);
+
+- /* PCS link status */
+- if (priv->hw->pcs &&
+- !(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS)) {
+- if (priv->xstats.pcs_link)
+- netif_carrier_on(priv->dev);
+- else
+- netif_carrier_off(priv->dev);
+- }
+-
+ stmmac_timestamp_interrupt(priv, priv);
+ }
+ }
+diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
+index fa1318bac06c4..99022620457ac 100644
+--- a/include/linux/stmmac.h
++++ b/include/linux/stmmac.h
+@@ -171,7 +171,6 @@ struct dwmac4_addrs {
+ u32 mtl_low_cred_offset;
+ };
+
+-#define STMMAC_FLAG_HAS_INTEGRATED_PCS BIT(0)
+ #define STMMAC_FLAG_SPH_DISABLE BIT(1)
+ #define STMMAC_FLAG_USE_PHY_WOL BIT(2)
+ #define STMMAC_FLAG_HAS_SUN8I BIT(3)
+--
+2.51.0
+
--- /dev/null
+From 1a46e2ea67033834f4dab91215980f3221ab92fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Oct 2025 08:26:49 +0100
+Subject: net: stmmac: replace has_xxxx with core_type
+
+From: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit 26ab9830beabda863766be4a79dc590c7645f4d9 ]
+
+Replace the has_gmac, has_gmac4 and has_xgmac ints, of which only one
+can be set when matching a core to its driver backend, with an
+enumerated type carrying the DWMAC core type.
+
+Tested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Acked-by: Chen-Yu Tsai <wens@kernel.org>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Tested-by: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
+Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://patch.msgid.link/E1vB6ld-0000000BIPy-2Qi4@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: babab1b42ed6 ("net: stmmac: fix oops when split header is enabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/common.h | 5 ++
+ .../stmicro/stmmac/dwmac-dwc-qos-eth.c | 2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 5 +-
+ .../ethernet/stmicro/stmmac/dwmac-ipq806x.c | 2 +-
+ .../ethernet/stmicro/stmmac/dwmac-loongson.c | 2 +-
+ .../ethernet/stmicro/stmmac/dwmac-lpc18xx.c | 2 +-
+ .../stmicro/stmmac/dwmac-qcom-ethqos.c | 2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-rk.c | 4 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-s32.c | 2 +-
+ .../ethernet/stmicro/stmmac/dwmac-socfpga.c | 2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 2 +-
+ .../net/ethernet/stmicro/stmmac/dwmac-tegra.c | 2 +-
+ drivers/net/ethernet/stmicro/stmmac/hwif.c | 73 +++++++------------
+ .../net/ethernet/stmicro/stmmac/stmmac_est.c | 4 +-
+ .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 13 ++--
+ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 34 +++++----
+ .../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 14 ++--
+ .../net/ethernet/stmicro/stmmac/stmmac_pci.c | 4 +-
+ .../ethernet/stmicro/stmmac/stmmac_platform.c | 9 +--
+ .../net/ethernet/stmicro/stmmac/stmmac_ptp.c | 4 +-
+ include/linux/stmmac.h | 11 ++-
+ 21 files changed, 94 insertions(+), 104 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
+index 8f34c9ad457f0..23ec3a59ca8f1 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/common.h
++++ b/drivers/net/ethernet/stmicro/stmmac/common.h
+@@ -43,6 +43,11 @@
+ #define DWXGMAC_ID 0x76
+ #define DWXLGMAC_ID 0x27
+
++static inline bool dwmac_is_xmac(enum dwmac_core_type core_type)
++{
++ return core_type == DWMAC_CORE_GMAC4 || core_type == DWMAC_CORE_XGMAC;
++}
++
+ #define STMMAC_CHAN0 0 /* Always supported and default for all chips */
+
+ /* TX and RX Descriptor Length, these need to be power of two.
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+index e8539cad4602e..1d30f2fb984f1 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+@@ -109,7 +109,7 @@ static int dwc_eth_dwmac_config_dt(struct platform_device *pdev,
+ }
+
+ /* dwc-qos needs GMAC4, AAL, TSO and PMT */
+- plat_dat->has_gmac4 = 1;
++ plat_dat->core_type = DWMAC_CORE_GMAC4;
+ plat_dat->dma_cfg->aal = 1;
+ plat_dat->flags |= STMMAC_FLAG_TSO_EN;
+ plat_dat->pmt = 1;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+index e74d00984b889..b2194e414ec1f 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+@@ -565,7 +565,7 @@ static void common_default_data(struct plat_stmmacenet_data *plat)
+ {
+ /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
+ plat->clk_csr = STMMAC_CSR_20_35M;
+- plat->has_gmac = 1;
++ plat->core_type = DWMAC_CORE_GMAC;
+ plat->force_sf_dma_mode = 1;
+
+ plat->mdio_bus_data->needs_reset = true;
+@@ -612,8 +612,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
+ plat->pdev = pdev;
+ plat->phy_addr = -1;
+ plat->clk_csr = STMMAC_CSR_250_300M;
+- plat->has_gmac = 0;
+- plat->has_gmac4 = 1;
++ plat->core_type = DWMAC_CORE_GMAC4;
+ plat->force_sf_dma_mode = 0;
+ plat->flags |= (STMMAC_FLAG_TSO_EN | STMMAC_FLAG_SPH_DISABLE);
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+index ca4035cbb55b6..c05f85534f0ca 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+@@ -473,7 +473,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
+ return err;
+ }
+
+- plat_dat->has_gmac = true;
++ plat_dat->core_type = DWMAC_CORE_GMAC;
+ plat_dat->bsp_priv = gmac;
+ plat_dat->set_clk_tx_rate = ipq806x_gmac_set_clk_tx_rate;
+ plat_dat->multicast_filter_bins = 0;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+index 592aa9d636e50..2a3ac0136cdbc 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+@@ -92,7 +92,7 @@ static void loongson_default_data(struct pci_dev *pdev,
+
+ /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
+ plat->clk_csr = STMMAC_CSR_20_35M;
+- plat->has_gmac = 1;
++ plat->core_type = DWMAC_CORE_GMAC;
+ plat->force_sf_dma_mode = 1;
+
+ /* Set default value for multicast hash bins */
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
+index 2562a6d036a2a..6fffc9dfbae55 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
+@@ -41,7 +41,7 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev)
+ if (IS_ERR(plat_dat))
+ return PTR_ERR(plat_dat);
+
+- plat_dat->has_gmac = true;
++ plat_dat->core_type = DWMAC_CORE_GMAC;
+
+ reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg");
+ if (IS_ERR(reg)) {
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+index f62825220cf70..74c208dd86519 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+@@ -846,7 +846,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
+ plat_dat->fix_mac_speed = ethqos_fix_mac_speed;
+ plat_dat->dump_debug_regs = rgmii_dump;
+ plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config;
+- plat_dat->has_gmac4 = 1;
++ plat_dat->core_type = DWMAC_CORE_GMAC4;
+ if (ethqos->has_emac_ge_3)
+ plat_dat->dwmac4_addrs = &data->dwmac4_addrs;
+ plat_dat->pmt = 1;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+index 0786816e05f04..643578266dfca 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+@@ -1751,8 +1751,8 @@ static int rk_gmac_probe(struct platform_device *pdev)
+ /* If the stmmac is not already selected as gmac4,
+ * then make sure we fallback to gmac.
+ */
+- if (!plat_dat->has_gmac4) {
+- plat_dat->has_gmac = true;
++ if (plat_dat->core_type != DWMAC_CORE_GMAC4) {
++ plat_dat->core_type = DWMAC_CORE_GMAC;
+ plat_dat->rx_fifo_size = 4096;
+ plat_dat->tx_fifo_size = 2048;
+ }
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
+index 221539d760bc8..ee095ac132037 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
+@@ -146,7 +146,7 @@ static int s32_dwmac_probe(struct platform_device *pdev)
+ gmac->ioaddr = res.addr;
+
+ /* S32CC core feature set */
+- plat->has_gmac4 = true;
++ plat->core_type = DWMAC_CORE_GMAC4;
+ plat->pmt = 1;
+ plat->flags |= STMMAC_FLAG_SPH_DISABLE;
+ plat->rx_fifo_size = 20480;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+index 354f01184e6cc..2ff5db6d41ca0 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+@@ -497,7 +497,7 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
+ plat_dat->pcs_init = socfpga_dwmac_pcs_init;
+ plat_dat->pcs_exit = socfpga_dwmac_pcs_exit;
+ plat_dat->select_pcs = socfpga_dwmac_select_pcs;
+- plat_dat->has_gmac = true;
++ plat_dat->core_type = DWMAC_CORE_GMAC;
+
+ plat_dat->riwt_off = 1;
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+index 1eadcf5d1ad63..7f560d78209d1 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+@@ -136,7 +136,7 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
+ /* platform data specifying hardware features and callbacks.
+ * hardware features were copied from Allwinner drivers. */
+ plat_dat->tx_coe = 1;
+- plat_dat->has_gmac = true;
++ plat_dat->core_type = DWMAC_CORE_GMAC;
+ plat_dat->bsp_priv = gmac;
+ plat_dat->init = sun7i_gmac_init;
+ plat_dat->exit = sun7i_gmac_exit;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
+index dc903b846b1bf..d765acbe37548 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
+@@ -308,7 +308,7 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
+ goto disable_clks;
+ }
+
+- plat->has_xgmac = 1;
++ plat->core_type = DWMAC_CORE_XGMAC;
+ plat->flags |= STMMAC_FLAG_TSO_EN;
+ plat->pmt = 1;
+ plat->bsp_priv = mgbe;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
+index 3f7c765dcb797..00083ce525492 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
++++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
+@@ -106,9 +106,7 @@ int stmmac_reset(struct stmmac_priv *priv, void __iomem *ioaddr)
+ }
+
+ static const struct stmmac_hwif_entry {
+- bool gmac;
+- bool gmac4;
+- bool xgmac;
++ enum dwmac_core_type core_type;
+ u32 min_id;
+ u32 dev_id;
+ const struct stmmac_regs_off regs;
+@@ -127,9 +125,7 @@ static const struct stmmac_hwif_entry {
+ } stmmac_hw[] = {
+ /* NOTE: New HW versions shall go to the end of this table */
+ {
+- .gmac = false,
+- .gmac4 = false,
+- .xgmac = false,
++ .core_type = DWMAC_CORE_MAC100,
+ .min_id = 0,
+ .regs = {
+ .ptp_off = PTP_GMAC3_X_OFFSET,
+@@ -146,9 +142,7 @@ static const struct stmmac_hwif_entry {
+ .setup = dwmac100_setup,
+ .quirks = stmmac_dwmac1_quirks,
+ }, {
+- .gmac = true,
+- .gmac4 = false,
+- .xgmac = false,
++ .core_type = DWMAC_CORE_GMAC,
+ .min_id = 0,
+ .regs = {
+ .ptp_off = PTP_GMAC3_X_OFFSET,
+@@ -165,9 +159,7 @@ static const struct stmmac_hwif_entry {
+ .setup = dwmac1000_setup,
+ .quirks = stmmac_dwmac1_quirks,
+ }, {
+- .gmac = false,
+- .gmac4 = true,
+- .xgmac = false,
++ .core_type = DWMAC_CORE_GMAC4,
+ .min_id = 0,
+ .regs = {
+ .ptp_off = PTP_GMAC4_OFFSET,
+@@ -187,9 +179,7 @@ static const struct stmmac_hwif_entry {
+ .setup = dwmac4_setup,
+ .quirks = stmmac_dwmac4_quirks,
+ }, {
+- .gmac = false,
+- .gmac4 = true,
+- .xgmac = false,
++ .core_type = DWMAC_CORE_GMAC4,
+ .min_id = DWMAC_CORE_4_00,
+ .regs = {
+ .ptp_off = PTP_GMAC4_OFFSET,
+@@ -210,9 +200,7 @@ static const struct stmmac_hwif_entry {
+ .setup = dwmac4_setup,
+ .quirks = NULL,
+ }, {
+- .gmac = false,
+- .gmac4 = true,
+- .xgmac = false,
++ .core_type = DWMAC_CORE_GMAC4,
+ .min_id = DWMAC_CORE_4_10,
+ .regs = {
+ .ptp_off = PTP_GMAC4_OFFSET,
+@@ -233,9 +221,7 @@ static const struct stmmac_hwif_entry {
+ .setup = dwmac4_setup,
+ .quirks = NULL,
+ }, {
+- .gmac = false,
+- .gmac4 = true,
+- .xgmac = false,
++ .core_type = DWMAC_CORE_GMAC4,
+ .min_id = DWMAC_CORE_5_10,
+ .regs = {
+ .ptp_off = PTP_GMAC4_OFFSET,
+@@ -256,9 +242,7 @@ static const struct stmmac_hwif_entry {
+ .setup = dwmac4_setup,
+ .quirks = NULL,
+ }, {
+- .gmac = false,
+- .gmac4 = false,
+- .xgmac = true,
++ .core_type = DWMAC_CORE_XGMAC,
+ .min_id = DWXGMAC_CORE_2_10,
+ .dev_id = DWXGMAC_ID,
+ .regs = {
+@@ -280,9 +264,7 @@ static const struct stmmac_hwif_entry {
+ .setup = dwxgmac2_setup,
+ .quirks = NULL,
+ }, {
+- .gmac = false,
+- .gmac4 = false,
+- .xgmac = true,
++ .core_type = DWMAC_CORE_XGMAC,
+ .min_id = DWXLGMAC_CORE_2_00,
+ .dev_id = DWXLGMAC_ID,
+ .regs = {
+@@ -308,20 +290,18 @@ static const struct stmmac_hwif_entry {
+
+ int stmmac_hwif_init(struct stmmac_priv *priv)
+ {
+- bool needs_xgmac = priv->plat->has_xgmac;
+- bool needs_gmac4 = priv->plat->has_gmac4;
+- bool needs_gmac = priv->plat->has_gmac;
++ enum dwmac_core_type core_type = priv->plat->core_type;
+ const struct stmmac_hwif_entry *entry;
+ struct mac_device_info *mac;
+ bool needs_setup = true;
+ u32 id, dev_id = 0;
+ int i, ret;
+
+- if (needs_gmac) {
++ if (core_type == DWMAC_CORE_GMAC) {
+ id = stmmac_get_id(priv, GMAC_VERSION);
+- } else if (needs_gmac4 || needs_xgmac) {
++ } else if (dwmac_is_xmac(core_type)) {
+ id = stmmac_get_id(priv, GMAC4_VERSION);
+- if (needs_xgmac)
++ if (core_type == DWMAC_CORE_XGMAC)
+ dev_id = stmmac_get_dev_id(priv, GMAC4_VERSION);
+ } else {
+ id = 0;
+@@ -331,14 +311,16 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
+ priv->synopsys_id = id;
+
+ /* Lets assume some safe values first */
+- priv->ptpaddr = priv->ioaddr +
+- (needs_gmac4 ? PTP_GMAC4_OFFSET : PTP_GMAC3_X_OFFSET);
+- priv->mmcaddr = priv->ioaddr +
+- (needs_gmac4 ? MMC_GMAC4_OFFSET : MMC_GMAC3_X_OFFSET);
+- if (needs_gmac4)
++ if (core_type == DWMAC_CORE_GMAC4) {
++ priv->ptpaddr = priv->ioaddr + PTP_GMAC4_OFFSET;
++ priv->mmcaddr = priv->ioaddr + MMC_GMAC4_OFFSET;
+ priv->estaddr = priv->ioaddr + EST_GMAC4_OFFSET;
+- else if (needs_xgmac)
+- priv->estaddr = priv->ioaddr + EST_XGMAC_OFFSET;
++ } else {
++ priv->ptpaddr = priv->ioaddr + PTP_GMAC3_X_OFFSET;
++ priv->mmcaddr = priv->ioaddr + MMC_GMAC3_X_OFFSET;
++ if (core_type == DWMAC_CORE_XGMAC)
++ priv->estaddr = priv->ioaddr + EST_XGMAC_OFFSET;
++ }
+
+ /* Check for HW specific setup first */
+ if (priv->plat->setup) {
+@@ -355,16 +337,12 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
+ for (i = ARRAY_SIZE(stmmac_hw) - 1; i >= 0; i--) {
+ entry = &stmmac_hw[i];
+
+- if (needs_gmac ^ entry->gmac)
+- continue;
+- if (needs_gmac4 ^ entry->gmac4)
+- continue;
+- if (needs_xgmac ^ entry->xgmac)
++ if (core_type != entry->core_type)
+ continue;
+ /* Use synopsys_id var because some setups can override this */
+ if (priv->synopsys_id < entry->min_id)
+ continue;
+- if (needs_xgmac && (dev_id ^ entry->dev_id))
++ if (core_type == DWMAC_CORE_XGMAC && (dev_id ^ entry->dev_id))
+ continue;
+
+ /* Only use generic HW helpers if needed */
+@@ -400,6 +378,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
+ }
+
+ dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n",
+- id, needs_gmac, needs_gmac4);
++ id, core_type == DWMAC_CORE_GMAC,
++ core_type == DWMAC_CORE_GMAC4);
+ return -EINVAL;
+ }
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c
+index 4b513d27a9889..afc516059b897 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c
+@@ -53,7 +53,7 @@ static int est_configure(struct stmmac_priv *priv, struct stmmac_est *cfg,
+ }
+
+ ctrl = readl(est_addr + EST_CONTROL);
+- if (priv->plat->has_xgmac) {
++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) {
+ ctrl &= ~EST_XGMAC_PTOV;
+ ctrl |= ((NSEC_PER_SEC / ptp_rate) * EST_XGMAC_PTOV_MUL) <<
+ EST_XGMAC_PTOV_SHIFT;
+@@ -148,7 +148,7 @@ static void est_irq_status(struct stmmac_priv *priv, struct net_device *dev,
+ }
+
+ if (status & EST_BTRE) {
+- if (priv->plat->has_xgmac) {
++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) {
+ btrl = FIELD_GET(EST_XGMAC_BTRL, status);
+ btrl_max = FIELD_MAX(EST_XGMAC_BTRL);
+ } else {
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index d89662b48087e..81d4039e1c082 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -303,9 +303,10 @@ static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
+ {
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+- if (priv->plat->has_gmac || priv->plat->has_gmac4)
++ if (priv->plat->core_type == DWMAC_CORE_GMAC ||
++ priv->plat->core_type == DWMAC_CORE_GMAC4)
+ strscpy(info->driver, GMAC_ETHTOOL_NAME, sizeof(info->driver));
+- else if (priv->plat->has_xgmac)
++ else if (priv->plat->core_type == DWMAC_CORE_XGMAC)
+ strscpy(info->driver, XGMAC_ETHTOOL_NAME, sizeof(info->driver));
+ else
+ strscpy(info->driver, MAC100_ETHTOOL_NAME,
+@@ -351,9 +352,9 @@ static int stmmac_ethtool_get_regs_len(struct net_device *dev)
+ {
+ struct stmmac_priv *priv = netdev_priv(dev);
+
+- if (priv->plat->has_xgmac)
++ if (priv->plat->core_type == DWMAC_CORE_XGMAC)
+ return XGMAC_REGSIZE * 4;
+- else if (priv->plat->has_gmac4)
++ else if (priv->plat->core_type == DWMAC_CORE_GMAC4)
+ return GMAC4_REG_SPACE_SIZE;
+ return REG_SPACE_SIZE;
+ }
+@@ -368,12 +369,12 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
+ stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space);
+
+ /* Copy DMA registers to where ethtool expects them */
+- if (priv->plat->has_gmac4) {
++ if (priv->plat->core_type == DWMAC_CORE_GMAC4) {
+ /* GMAC4 dumps its DMA registers at its DMA_CHAN_BASE_ADDR */
+ memcpy(®_space[ETHTOOL_DMA_OFFSET],
+ ®_space[GMAC4_DMA_CHAN_BASE_ADDR / 4],
+ NUM_DWMAC4_DMA_REGS * 4);
+- } else if (!priv->plat->has_xgmac) {
++ } else if (priv->plat->core_type != DWMAC_CORE_XGMAC) {
+ memcpy(®_space[ETHTOOL_DMA_OFFSET],
+ ®_space[DMA_BUS_MODE / 4],
+ NUM_DWMAC1000_DMA_REGS * 4);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index e707abc35e2de..a38976c65149c 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -446,7 +446,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
+ if (!priv->hwts_rx_en)
+ return;
+ /* For GMAC4, the valid timestamp is from CTX next desc. */
+- if (priv->plat->has_gmac4 || priv->plat->has_xgmac)
++ if (dwmac_is_xmac(priv->plat->core_type))
+ desc = np;
+
+ /* Check if timestamp is available */
+@@ -697,7 +697,7 @@ static int stmmac_hwtstamp_get(struct net_device *dev,
+ static int stmmac_init_tstamp_counter(struct stmmac_priv *priv,
+ u32 systime_flags)
+ {
+- bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
++ bool xmac = dwmac_is_xmac(priv->plat->core_type);
+ struct timespec64 now;
+ u32 sec_inc = 0;
+ u64 temp = 0;
+@@ -746,7 +746,7 @@ static int stmmac_init_tstamp_counter(struct stmmac_priv *priv,
+ */
+ static int stmmac_init_timestamping(struct stmmac_priv *priv)
+ {
+- bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
++ bool xmac = dwmac_is_xmac(priv->plat->core_type);
+ int ret;
+
+ if (priv->plat->ptp_clk_freq_config)
+@@ -2398,7 +2398,7 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
+ txfifosz = priv->dma_cap.tx_fifo_size;
+
+ /* Split up the shared Tx/Rx FIFO memory on DW QoS Eth and DW XGMAC */
+- if (priv->plat->has_gmac4 || priv->plat->has_xgmac) {
++ if (dwmac_is_xmac(priv->plat->core_type)) {
+ rxfifosz /= rx_channels_count;
+ txfifosz /= tx_channels_count;
+ }
+@@ -4514,7 +4514,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
+ if (skb_is_gso(skb) && priv->tso) {
+ if (gso & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))
+ return stmmac_tso_xmit(skb, dev);
+- if (priv->plat->has_gmac4 && (gso & SKB_GSO_UDP_L4))
++ if (priv->plat->core_type == DWMAC_CORE_GMAC4 &&
++ (gso & SKB_GSO_UDP_L4))
+ return stmmac_tso_xmit(skb, dev);
+ }
+
+@@ -5984,7 +5985,7 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv)
+ u32 queue;
+ bool xmac;
+
+- xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
++ xmac = dwmac_is_xmac(priv->plat->core_type);
+ queues_count = (rx_cnt > tx_cnt) ? rx_cnt : tx_cnt;
+
+ if (priv->irq_wake)
+@@ -5998,7 +5999,7 @@ static void stmmac_common_interrupt(struct stmmac_priv *priv)
+ stmmac_fpe_irq_status(priv);
+
+ /* To handle GMAC own interrupts */
+- if ((priv->plat->has_gmac) || xmac) {
++ if (priv->plat->core_type == DWMAC_CORE_GMAC || xmac) {
+ int status = stmmac_host_irq_status(priv, priv->hw, &priv->xstats);
+
+ if (unlikely(status)) {
+@@ -6359,7 +6360,7 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v)
+ (priv->dma_cap.mbps_1000) ? "Y" : "N");
+ seq_printf(seq, "\tHalf duplex: %s\n",
+ (priv->dma_cap.half_duplex) ? "Y" : "N");
+- if (priv->plat->has_xgmac) {
++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) {
+ seq_printf(seq,
+ "\tNumber of Additional MAC address registers: %d\n",
+ priv->dma_cap.multi_addr);
+@@ -6383,7 +6384,7 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v)
+ (priv->dma_cap.time_stamp) ? "Y" : "N");
+ seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp: %s\n",
+ (priv->dma_cap.atime_stamp) ? "Y" : "N");
+- if (priv->plat->has_xgmac)
++ if (priv->plat->core_type == DWMAC_CORE_XGMAC)
+ seq_printf(seq, "\tTimestamp System Time Source: %s\n",
+ dwxgmac_timestamp_source[priv->dma_cap.tssrc]);
+ seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE): %s\n",
+@@ -6392,7 +6393,7 @@ static int stmmac_dma_cap_show(struct seq_file *seq, void *v)
+ seq_printf(seq, "\tChecksum Offload in TX: %s\n",
+ (priv->dma_cap.tx_coe) ? "Y" : "N");
+ if (priv->synopsys_id >= DWMAC_CORE_4_00 ||
+- priv->plat->has_xgmac) {
++ priv->plat->core_type == DWMAC_CORE_XGMAC) {
+ seq_printf(seq, "\tIP Checksum Offload in RX: %s\n",
+ (priv->dma_cap.rx_coe) ? "Y" : "N");
+ } else {
+@@ -7244,8 +7245,9 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
+ * has to be disable and this can be done by passing the
+ * riwt_off field from the platform.
+ */
+- if (((priv->synopsys_id >= DWMAC_CORE_3_50) ||
+- (priv->plat->has_xgmac)) && (!priv->plat->riwt_off)) {
++ if ((priv->synopsys_id >= DWMAC_CORE_3_50 ||
++ priv->plat->core_type == DWMAC_CORE_XGMAC) &&
++ !priv->plat->riwt_off) {
+ priv->use_riwt = 1;
+ dev_info(priv->device,
+ "Enable RX Mitigation via HW Watchdog Timer\n");
+@@ -7359,7 +7361,7 @@ static int stmmac_xdp_rx_timestamp(const struct xdp_md *_ctx, u64 *timestamp)
+ return -ENODATA;
+
+ /* For GMAC4, the valid timestamp is from CTX next desc. */
+- if (priv->plat->has_gmac4 || priv->plat->has_xgmac)
++ if (dwmac_is_xmac(priv->plat->core_type))
+ desc_contains_ts = ndesc;
+
+ /* Check if timestamp is available */
+@@ -7515,7 +7517,7 @@ int stmmac_dvr_probe(struct device *device,
+
+ if ((priv->plat->flags & STMMAC_FLAG_TSO_EN) && (priv->dma_cap.tsoen)) {
+ ndev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
+- if (priv->plat->has_gmac4)
++ if (priv->plat->core_type == DWMAC_CORE_GMAC4)
+ ndev->hw_features |= NETIF_F_GSO_UDP_L4;
+ priv->tso = true;
+ dev_info(priv->device, "TSO feature enabled\n");
+@@ -7568,7 +7570,7 @@ int stmmac_dvr_probe(struct device *device,
+ #ifdef STMMAC_VLAN_TAG_USED
+ /* Both mac100 and gmac support receive VLAN tag detection */
+ ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX;
+- if (priv->plat->has_gmac4 || priv->plat->has_xgmac) {
++ if (dwmac_is_xmac(priv->plat->core_type)) {
+ ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
+ priv->hw->hw_vlan_en = true;
+ }
+@@ -7596,7 +7598,7 @@ int stmmac_dvr_probe(struct device *device,
+
+ /* MTU range: 46 - hw-specific max */
+ ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
+- if (priv->plat->has_xgmac)
++ if (priv->plat->core_type == DWMAC_CORE_XGMAC)
+ ndev->max_mtu = XGMAC_JUMBO_LEN;
+ else if ((priv->plat->enh_desc) || (priv->synopsys_id >= DWMAC_CORE_4_00))
+ ndev->max_mtu = JUMBO_LEN;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+index f408737f6fc73..2b55b02de380d 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+@@ -301,7 +301,7 @@ static int stmmac_mdio_read_c22(struct mii_bus *bus, int phyaddr, int phyreg)
+ struct stmmac_priv *priv = netdev_priv(bus->priv);
+ u32 cmd;
+
+- if (priv->plat->has_gmac4)
++ if (priv->plat->core_type == DWMAC_CORE_GMAC4)
+ cmd = MII_GMAC4_READ;
+ else
+ cmd = 0;
+@@ -344,7 +344,7 @@ static int stmmac_mdio_write_c22(struct mii_bus *bus, int phyaddr, int phyreg,
+ struct stmmac_priv *priv = netdev_priv(bus->priv);
+ u32 cmd;
+
+- if (priv->plat->has_gmac4)
++ if (priv->plat->core_type == DWMAC_CORE_GMAC4)
+ cmd = MII_GMAC4_WRITE;
+ else
+ cmd = MII_ADDR_GWRITE;
+@@ -417,7 +417,7 @@ int stmmac_mdio_reset(struct mii_bus *bus)
+ * on MDC, so perform a dummy mdio read. To be updated for GMAC4
+ * if needed.
+ */
+- if (!priv->plat->has_gmac4)
++ if (priv->plat->core_type != DWMAC_CORE_GMAC4)
+ writel(0, priv->ioaddr + mii_address);
+ #endif
+ return 0;
+@@ -528,7 +528,7 @@ static u32 stmmac_clk_csr_set(struct stmmac_priv *priv)
+ value = 0;
+ }
+
+- if (priv->plat->has_xgmac) {
++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) {
+ if (clk_rate > 400000000)
+ value = 0x5;
+ else if (clk_rate > 350000000)
+@@ -600,7 +600,7 @@ int stmmac_mdio_register(struct net_device *ndev)
+
+ new_bus->name = "stmmac";
+
+- if (priv->plat->has_xgmac) {
++ if (priv->plat->core_type == DWMAC_CORE_XGMAC) {
+ new_bus->read = &stmmac_xgmac2_mdio_read_c22;
+ new_bus->write = &stmmac_xgmac2_mdio_write_c22;
+ new_bus->read_c45 = &stmmac_xgmac2_mdio_read_c45;
+@@ -621,7 +621,7 @@ int stmmac_mdio_register(struct net_device *ndev)
+ } else {
+ new_bus->read = &stmmac_mdio_read_c22;
+ new_bus->write = &stmmac_mdio_write_c22;
+- if (priv->plat->has_gmac4) {
++ if (priv->plat->core_type == DWMAC_CORE_GMAC4) {
+ new_bus->read_c45 = &stmmac_mdio_read_c45;
+ new_bus->write_c45 = &stmmac_mdio_write_c45;
+ }
+@@ -649,7 +649,7 @@ int stmmac_mdio_register(struct net_device *ndev)
+ }
+
+ /* Looks like we need a dummy read for XGMAC only and C45 PHYs */
+- if (priv->plat->has_xgmac)
++ if (priv->plat->core_type == DWMAC_CORE_XGMAC)
+ stmmac_xgmac2_mdio_read_c45(new_bus, 0, 0, 0);
+
+ /* If fixed-link is set, skip PHY scanning */
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+index 4e3aa611fda83..94b3a3b272706 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+@@ -23,7 +23,7 @@ static void common_default_data(struct plat_stmmacenet_data *plat)
+ {
+ /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
+ plat->clk_csr = STMMAC_CSR_20_35M;
+- plat->has_gmac = 1;
++ plat->core_type = DWMAC_CORE_GMAC;
+ plat->force_sf_dma_mode = 1;
+
+ plat->mdio_bus_data->needs_reset = true;
+@@ -76,7 +76,7 @@ static int snps_gmac5_default_data(struct pci_dev *pdev,
+ int i;
+
+ plat->clk_csr = STMMAC_CSR_250_300M;
+- plat->has_gmac4 = 1;
++ plat->core_type = DWMAC_CORE_GMAC4;
+ plat->force_sf_dma_mode = 1;
+ plat->flags |= STMMAC_FLAG_TSO_EN;
+ plat->pmt = 1;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+index 27bcaae07a7f2..fbb92cc6ab598 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -552,12 +552,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+ &pdev->dev, plat->unicast_filter_entries);
+ plat->multicast_filter_bins = dwmac1000_validate_mcast_bins(
+ &pdev->dev, plat->multicast_filter_bins);
+- plat->has_gmac = 1;
++ plat->core_type = DWMAC_CORE_GMAC;
+ plat->pmt = 1;
+ }
+
+ if (of_device_is_compatible(np, "snps,dwmac-3.40a")) {
+- plat->has_gmac = 1;
++ plat->core_type = DWMAC_CORE_GMAC;
+ plat->enh_desc = 1;
+ plat->tx_coe = 1;
+ plat->bugged_jumbo = 1;
+@@ -565,8 +565,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+ }
+
+ if (of_device_compatible_match(np, stmmac_gmac4_compats)) {
+- plat->has_gmac4 = 1;
+- plat->has_gmac = 0;
++ plat->core_type = DWMAC_CORE_GMAC4;
+ plat->pmt = 1;
+ if (of_property_read_bool(np, "snps,tso"))
+ plat->flags |= STMMAC_FLAG_TSO_EN;
+@@ -580,7 +579,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
+ }
+
+ if (of_device_is_compatible(np, "snps,dwxgmac")) {
+- plat->has_xgmac = 1;
++ plat->core_type = DWMAC_CORE_XGMAC;
+ plat->pmt = 1;
+ if (of_property_read_bool(np, "snps,tso"))
+ plat->flags |= STMMAC_FLAG_TSO_EN;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+index 993ff4e87e557..3e30172fa1294 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+@@ -57,7 +57,7 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
+ bool xmac, est_rst = false;
+ int ret;
+
+- xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
++ xmac = dwmac_is_xmac(priv->plat->core_type);
+
+ if (delta < 0) {
+ neg_adj = 1;
+@@ -344,7 +344,7 @@ void stmmac_ptp_register(struct stmmac_priv *priv)
+
+ /* Calculate the clock domain crossing (CDC) error if necessary */
+ priv->plat->cdc_error_adj = 0;
+- if (priv->plat->has_gmac4)
++ if (priv->plat->core_type == DWMAC_CORE_GMAC4)
+ priv->plat->cdc_error_adj = (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate;
+
+ /* Update the ptp clock parameters based on feature discovery, when
+diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
+index 99022620457ac..151c81c560c8c 100644
+--- a/include/linux/stmmac.h
++++ b/include/linux/stmmac.h
+@@ -171,6 +171,13 @@ struct dwmac4_addrs {
+ u32 mtl_low_cred_offset;
+ };
+
++enum dwmac_core_type {
++ DWMAC_CORE_MAC100,
++ DWMAC_CORE_GMAC,
++ DWMAC_CORE_GMAC4,
++ DWMAC_CORE_XGMAC,
++};
++
+ #define STMMAC_FLAG_SPH_DISABLE BIT(1)
+ #define STMMAC_FLAG_USE_PHY_WOL BIT(2)
+ #define STMMAC_FLAG_HAS_SUN8I BIT(3)
+@@ -186,6 +193,7 @@ struct dwmac4_addrs {
+ #define STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY BIT(13)
+
+ struct plat_stmmacenet_data {
++ enum dwmac_core_type core_type;
+ int bus_id;
+ int phy_addr;
+ /* MAC ----- optional PCS ----- SerDes ----- optional PHY ----- Media
+@@ -219,7 +227,6 @@ struct plat_stmmacenet_data {
+ struct stmmac_dma_cfg *dma_cfg;
+ struct stmmac_safety_feature_cfg *safety_feat_cfg;
+ int clk_csr;
+- int has_gmac;
+ int enh_desc;
+ int tx_coe;
+ int rx_coe;
+@@ -282,10 +289,8 @@ struct plat_stmmacenet_data {
+ struct reset_control *stmmac_rst;
+ struct reset_control *stmmac_ahb_rst;
+ struct stmmac_axi *axi;
+- int has_gmac4;
+ int rss_en;
+ int mac_port_sel_speed;
+- int has_xgmac;
+ u8 vlan_fail_q;
+ struct pci_dev *pdev;
+ int int_snapshot_num;
+--
+2.51.0
+
--- /dev/null
+From 1ff0dbf09861ba5f9b5ede95dec9d3ebc7f60541 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 21:41:54 +0000
+Subject: net: usb: catc: enable basic endpoint checking
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ]
+
+catc_probe() fills three URBs with hardcoded endpoint pipes without
+verifying the endpoint descriptors:
+
+ - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX
+ - usb_rcvintpipe(usbdev, 2) for interrupt status
+
+A malformed USB device can present these endpoints with transfer types
+that differ from what the driver assumes.
+
+Add a catc_usb_ep enum for endpoint numbers, replacing magic constants
+throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints()
+calls after usb_set_interface() to verify endpoint types before use,
+rejecting devices with mismatched descriptors at probe time.
+
+Similar to
+- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking")
+which fixed the issue in rtl8150.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Suggested-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------
+ 1 file changed, 31 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
+index 6759388692f8e..3c824340ffb06 100644
+--- a/drivers/net/usb/catc.c
++++ b/drivers/net/usb/catc.c
+@@ -64,6 +64,16 @@ static const char driver_name[] = "catc";
+ #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */
+ #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */
+
++/*
++ * USB endpoints.
++ */
++
++enum catc_usb_ep {
++ CATC_USB_EP_CONTROL = 0,
++ CATC_USB_EP_BULK = 1,
++ CATC_USB_EP_INT_IN = 2,
++};
++
+ /*
+ * Control requests.
+ */
+@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ u8 broadcast[ETH_ALEN];
+ u8 *macbuf;
+ int pktsz, ret = -ENOMEM;
++ static const u8 bulk_ep_addr[] = {
++ CATC_USB_EP_BULK | USB_DIR_OUT,
++ CATC_USB_EP_BULK | USB_DIR_IN,
++ 0};
++ static const u8 int_ep_addr[] = {
++ CATC_USB_EP_INT_IN | USB_DIR_IN,
++ 0};
+
+ macbuf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if (!macbuf)
+@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ goto fail_mem;
+ }
+
++ /* Verify that all required endpoints are present */
++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
++ !usb_check_int_endpoints(intf, int_ep_addr)) {
++ dev_err(dev, "Missing or invalid endpoints\n");
++ ret = -ENODEV;
++ goto fail_mem;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct catc));
+ if (!netdev)
+ goto fail_mem;
+@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0),
+ NULL, NULL, 0, catc_ctrl_done, catc);
+
+- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1),
+- NULL, 0, catc_tx_done, catc);
++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK),
++ NULL, 0, catc_tx_done, catc);
+
+- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1),
+- catc->rx_buf, pktsz, catc_rx_done, catc);
++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK),
++ catc->rx_buf, pktsz, catc_rx_done, catc);
+
+- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2),
+- catc->irq_buf, 2, catc_irq_done, catc, 1);
++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN),
++ catc->irq_buf, 2, catc_irq_done, catc, 1);
+
+ if (!catc->is_f5u011) {
+ u32 *buf;
+--
+2.51.0
+
--- /dev/null
+From 6035c395e63907428a3a6a901602a17ba44bfe72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 12:53:09 +0100
+Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ]
+
+Mihail Milev reports: Error: UNINIT (CWE-457):
+ net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl:
+ Declaring variable "tuple" without initializer.
+ net/netfilter/nf_conntrack_h323_main.c:1197:2:
+ uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find".
+ net/netfilter/nf_conntrack_expect.c:142:2:
+ read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash".
+
+ 1195| tuple.dst.protonum = IPPROTO_TCP;
+ 1196|
+ 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ 1198| if (exp && exp->master == ct)
+ 1199| return exp;
+
+Switch this to a C99 initialiser and set the l3num value.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_h323_main.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
+index 14f73872f6477..e35814d68ce30 100644
+--- a/net/netfilter/nf_conntrack_h323_main.c
++++ b/net/netfilter/nf_conntrack_h323_main.c
+@@ -1186,13 +1186,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
+ {
+ struct net *net = nf_ct_net(ct);
+ struct nf_conntrack_expect *exp;
+- struct nf_conntrack_tuple tuple;
++ struct nf_conntrack_tuple tuple = {
++ .src.l3num = nf_ct_l3num(ct),
++ .dst.protonum = IPPROTO_TCP,
++ .dst.u.tcp.port = port,
++ };
+
+- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3));
+- tuple.src.u.tcp.port = 0;
+ memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3));
+- tuple.dst.u.tcp.port = port;
+- tuple.dst.protonum = IPPROTO_TCP;
+
+ exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ if (exp && exp->master == ct)
+--
+2.51.0
+
--- /dev/null
+From da026db54ecd7e45e302425d19a34a6077b36af7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 21:14:40 +0900
+Subject: netfilter: nf_tables: fix use-after-free in nf_tables_addchain()
+
+From: Inseo An <y0un9sa@gmail.com>
+
+[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ]
+
+nf_tables_addchain() publishes the chain to table->chains via
+list_add_tail_rcu() (in nft_chain_add()) before registering hooks.
+If nf_tables_register_hook() then fails, the error path calls
+nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy()
+with no RCU grace period in between.
+
+This creates two use-after-free conditions:
+
+ 1) Control-plane: nf_tables_dump_chains() traverses table->chains
+ under rcu_read_lock(). A concurrent dump can still be walking
+ the chain when the error path frees it.
+
+ 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly
+ installs the IPv4 hook before IPv6 registration fails. Packets
+ entering nft_do_chain() via the transient IPv4 hook can still be
+ dereferencing chain->blob_gen_X when the error path frees the
+ chain.
+
+Add synchronize_rcu() between nft_chain_del() and the chain destroy
+so that all RCU readers -- both dump threads and in-flight packet
+evaluation -- have finished before the chain is freed.
+
+Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain")
+Signed-off-by: Inseo An <y0un9sa@gmail.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 9051f2c3595a2..df367638cdef0 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -2822,6 +2822,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 policy,
+
+ err_register_hook:
+ nft_chain_del(chain);
++ synchronize_rcu();
+ err_chain_add:
+ nft_trans_destroy(trans);
+ err_trans:
+--
+2.51.0
+
--- /dev/null
+From c1de1802550dbaf1966f350e694fc0bb3cb348dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 21:28:46 +0800
+Subject: objpool: fix the overestimation of object pooling metadata size
+
+From: zhouwenhao <zhouwenhao7600@gmail.com>
+
+[ Upstream commit 5ed4b6b37c647d168ae31035b3f61b705997e043 ]
+
+objpool uses struct objpool_head to store metadata information, and its
+cpu_slots member points to an array of pointers that store the addresses
+of the percpu ring arrays. However, the memory size allocated during the
+initialization of cpu_slots is nr_cpu_ids * sizeof(struct objpool_slot).
+On a 64-bit machine, the size of struct objpool_slot is 16 bytes, which is
+twice the size of the actual pointer required, and the extra memory is
+never be used, resulting in a waste of memory. Therefore, the memory size
+required for cpu_slots needs to be corrected.
+
+Link: https://lkml.kernel.org/r/20260202132846.68257-1-zhouwenhao7600@gmail.com
+Fixes: b4edb8d2d464 ("lib: objpool added: ring-array based lockless MPMC")
+Signed-off-by: zhouwenhao <zhouwenhao7600@gmail.com>
+Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
+Cc: Matt Wu <wuqiang.matt@bytedance.com>
+Cc: wuqiang.matt <wuqiang.matt@bytedance.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/objpool.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/objpool.c b/lib/objpool.c
+index b998b720c7329..d98fadf1de169 100644
+--- a/lib/objpool.c
++++ b/lib/objpool.c
+@@ -142,7 +142,7 @@ int objpool_init(struct objpool_head *pool, int nr_objs, int object_size,
+ pool->gfp = gfp & ~__GFP_ZERO;
+ pool->context = context;
+ pool->release = release;
+- slot_size = nr_cpu_ids * sizeof(struct objpool_slot);
++ slot_size = nr_cpu_ids * sizeof(struct objpool_slot *);
+ pool->cpu_slots = kzalloc(slot_size, pool->gfp);
+ if (!pool->cpu_slots)
+ return -ENOMEM;
+--
+2.51.0
+
--- /dev/null
+From 68ed5a1ccdb8944cab6efc830cb8b41526dfb21c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:33:38 +0530
+Subject: octeontx2-af: Fix default entries mcam entry action
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ]
+
+As per design, AF should update the default MCAM action only when
+mcam_index is -1. A bug in the previous patch caused default entries
+to be changed even when the request was not for them.
+
+Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++---------
+ 1 file changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+index c7c70429eb6c1..8658cb2143dfc 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+@@ -1042,32 +1042,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
+ rvu_write64(rvu, blkaddr,
+ NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action);
+
+- /* update the VF flow rule action with the VF default entry action */
+- if (mcam_index < 0)
+- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
+- *(u64 *)&action);
+-
+ /* update the action change in default rule */
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+ if (pfvf->def_ucast_rule)
+ pfvf->def_ucast_rule->rx_action = action;
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_PROMISC_ENTRY);
++ if (mcam_index < 0) {
++ /* update the VF flow rule action with the VF default
++ * entry action
++ */
++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
++ *(u64 *)&action);
+
+- /* If PF's promiscuous entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_PROMISC_ENTRY);
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_ALLMULTI_ENTRY);
+- /* If PF's allmulti entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ /* If PF's promiscuous entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_ALLMULTI_ENTRY);
++ /* If PF's allmulti entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++ }
+ }
+
+ void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc,
+--
+2.51.0
+
--- /dev/null
+From 170ab5b4b8b9112f76e818ab96ec7a9010149ef5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jan 2026 18:32:49 +0100
+Subject: ovpn: fix possible use-after-free in ovpn_net_xmit
+
+From: Ralf Lici <ralf@mandelbit.com>
+
+[ Upstream commit a5ec7baa44ea3a1d6aa0ca31c0ad82edf9affe41 ]
+
+When building the skb_list in ovpn_net_xmit, skb_share_check will free
+the original skb if it is shared. The current implementation continues
+to use the stale skb pointer for subsequent operations:
+- peer lookup,
+- skb_dst_drop (even though all segments produced by skb_gso_segment
+ will have a dst attached),
+- ovpn_peer_stats_increment_tx.
+
+Fix this by moving the peer lookup and skb_dst_drop before segmentation
+so that the original skb is still valid when used. Return early if all
+segments fail skb_share_check and the list ends up empty.
+Also switch ovpn_peer_stats_increment_tx to use skb_list.next; the next
+patch fixes the stats logic.
+
+Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)")
+Signed-off-by: Ralf Lici <ralf@mandelbit.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ovpn/io.c | 52 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 31 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c
+index 3e9e7f8444b34..f70c58b10599b 100644
+--- a/drivers/net/ovpn/io.c
++++ b/drivers/net/ovpn/io.c
+@@ -365,7 +365,27 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
+ /* verify IP header size in network packet */
+ proto = ovpn_ip_check_protocol(skb);
+ if (unlikely(!proto || skb->protocol != proto))
+- goto drop;
++ goto drop_no_peer;
++
++ /* retrieve peer serving the destination IP of this packet */
++ peer = ovpn_peer_get_by_dst(ovpn, skb);
++ if (unlikely(!peer)) {
++ switch (skb->protocol) {
++ case htons(ETH_P_IP):
++ net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n",
++ netdev_name(ovpn->dev),
++ &ip_hdr(skb)->daddr);
++ break;
++ case htons(ETH_P_IPV6):
++ net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n",
++ netdev_name(ovpn->dev),
++ &ipv6_hdr(skb)->daddr);
++ break;
++ }
++ goto drop_no_peer;
++ }
++ /* dst was needed for peer selection - it can now be dropped */
++ skb_dst_drop(skb);
+
+ if (skb_is_gso(skb)) {
+ segments = skb_gso_segment(skb, 0);
+@@ -396,34 +416,24 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
+
+ __skb_queue_tail(&skb_list, curr);
+ }
+- skb_list.prev->next = NULL;
+
+- /* retrieve peer serving the destination IP of this packet */
+- peer = ovpn_peer_get_by_dst(ovpn, skb);
+- if (unlikely(!peer)) {
+- switch (skb->protocol) {
+- case htons(ETH_P_IP):
+- net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n",
+- netdev_name(ovpn->dev),
+- &ip_hdr(skb)->daddr);
+- break;
+- case htons(ETH_P_IPV6):
+- net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n",
+- netdev_name(ovpn->dev),
+- &ipv6_hdr(skb)->daddr);
+- break;
+- }
+- goto drop;
++ /* no segments survived: don't jump to 'drop' because we already
++ * incremented the counter for each failure in the loop
++ */
++ if (unlikely(skb_queue_empty(&skb_list))) {
++ ovpn_peer_put(peer);
++ return NETDEV_TX_OK;
+ }
+- /* dst was needed for peer selection - it can now be dropped */
+- skb_dst_drop(skb);
++ skb_list.prev->next = NULL;
+
+- ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb->len);
++ ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb_list.next->len);
+ ovpn_send(ovpn, skb_list.next, peer);
+
+ return NETDEV_TX_OK;
+
+ drop:
++ ovpn_peer_put(peer);
++drop_no_peer:
+ dev_dstats_tx_dropped(ovpn->dev);
+ skb_tx_error(skb);
+ kfree_skb_list(skb);
+--
+2.51.0
+
--- /dev/null
+From ccbfc6efc487bd25baadc9f0cbb5732c39b6266a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jan 2026 18:32:50 +0100
+Subject: ovpn: fix VPN TX bytes counting
+
+From: Ralf Lici <ralf@mandelbit.com>
+
+[ Upstream commit b660b13d4c6379ca6360f24aaef8c5807fefd237 ]
+
+In ovpn_net_xmit, after GSO segmentation and segment processing, the
+first segment on the list is used to increment VPN TX statistics, which
+fails to account for any subsequent segments in the chain.
+
+Fix this by accumulating the length of every segment that successfully
+passes skb_share_check into a tx_bytes variable. This ensures the peer
+statistics accurately reflect the total data volume sent, regardless of
+whether the original packet was segmented.
+
+Fixes: 04ca14955f9a ("ovpn: store tunnel and transport statistics")
+Signed-off-by: Ralf Lici <ralf@mandelbit.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ovpn/io.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c
+index f70c58b10599b..955c9a37e1f8d 100644
+--- a/drivers/net/ovpn/io.c
++++ b/drivers/net/ovpn/io.c
+@@ -355,6 +355,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
+ struct ovpn_priv *ovpn = netdev_priv(dev);
+ struct sk_buff *segments, *curr, *next;
+ struct sk_buff_head skb_list;
++ unsigned int tx_bytes = 0;
+ struct ovpn_peer *peer;
+ __be16 proto;
+ int ret;
+@@ -414,6 +415,8 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
+ continue;
+ }
+
++ /* only count what we actually send */
++ tx_bytes += curr->len;
+ __skb_queue_tail(&skb_list, curr);
+ }
+
+@@ -426,7 +429,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
+ }
+ skb_list.prev->next = NULL;
+
+- ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb_list.next->len);
++ ovpn_peer_stats_increment_tx(&peer->vpn_stats, tx_bytes);
+ ovpn_send(ovpn, skb_list.next, peer);
+
+ return NETDEV_TX_OK;
+--
+2.51.0
+
--- /dev/null
+From a5c2a220108f7ec8169e1e6d562c5a3d1bc7b175 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jan 2026 18:32:48 +0100
+Subject: ovpn: set sk_user_data before overriding callbacks
+
+From: Ralf Lici <ralf@mandelbit.com>
+
+[ Upstream commit 93686c472eb7b09a51b97a096449e7092fefcd1f ]
+
+During initialization, we override socket callbacks and set sk_user_data
+to an ovpn_socket instance. Currently, these two operations are
+decoupled: callbacks are overridden before sk_user_data is set. While
+existing callbacks perform safety checks for NULL or non-ovpn
+sk_user_data, this condition causes a "half-formed" state where valid
+packets arriving during attachment trigger error logs (e.g., "invoked on
+non ovpn socket").
+
+Set sk_user_data before overriding the callbacks so that it can be
+accessed safely from them. Since we already check that the socket has no
+sk_user_data before setting it, this remains safe even if an interrupt
+accesses the socket after sk_user_data is set but before the callbacks
+are overridden.
+
+This also requires initializing all protocol-specific fields (such as
+tcp_tx_work and peer links) before calling ovpn_socket_attach, ensuring
+the ovpn_socket is fully formed before it becomes visible to any
+callback.
+
+Fixes: f6226ae7a0cd ("ovpn: introduce the ovpn_socket object")
+Signed-off-by: Ralf Lici <ralf@mandelbit.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ovpn/socket.c | 39 +++++++++++++++++++++------------------
+ drivers/net/ovpn/tcp.c | 9 +++++++--
+ drivers/net/ovpn/udp.c | 1 +
+ 3 files changed, 29 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/net/ovpn/socket.c b/drivers/net/ovpn/socket.c
+index 9750871ab65ce..448cee3b3f9fa 100644
+--- a/drivers/net/ovpn/socket.c
++++ b/drivers/net/ovpn/socket.c
+@@ -200,6 +200,22 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
+ ovpn_sock->sk = sk;
+ kref_init(&ovpn_sock->refcount);
+
++ /* TCP sockets are per-peer, therefore they are linked to their unique
++ * peer
++ */
++ if (sk->sk_protocol == IPPROTO_TCP) {
++ INIT_WORK(&ovpn_sock->tcp_tx_work, ovpn_tcp_tx_work);
++ ovpn_sock->peer = peer;
++ ovpn_peer_hold(peer);
++ } else if (sk->sk_protocol == IPPROTO_UDP) {
++ /* in UDP we only link the ovpn instance since the socket is
++ * shared among multiple peers
++ */
++ ovpn_sock->ovpn = peer->ovpn;
++ netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker,
++ GFP_KERNEL);
++ }
++
+ /* the newly created ovpn_socket is holding reference to sk,
+ * therefore we increase its refcounter.
+ *
+@@ -212,29 +228,16 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
+
+ ret = ovpn_socket_attach(ovpn_sock, sock, peer);
+ if (ret < 0) {
++ if (sk->sk_protocol == IPPROTO_TCP)
++ ovpn_peer_put(peer);
++ else if (sk->sk_protocol == IPPROTO_UDP)
++ netdev_put(peer->ovpn->dev, &ovpn_sock->dev_tracker);
++
+ sock_put(sk);
+ kfree(ovpn_sock);
+ ovpn_sock = ERR_PTR(ret);
+- goto sock_release;
+- }
+-
+- /* TCP sockets are per-peer, therefore they are linked to their unique
+- * peer
+- */
+- if (sk->sk_protocol == IPPROTO_TCP) {
+- INIT_WORK(&ovpn_sock->tcp_tx_work, ovpn_tcp_tx_work);
+- ovpn_sock->peer = peer;
+- ovpn_peer_hold(peer);
+- } else if (sk->sk_protocol == IPPROTO_UDP) {
+- /* in UDP we only link the ovpn instance since the socket is
+- * shared among multiple peers
+- */
+- ovpn_sock->ovpn = peer->ovpn;
+- netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker,
+- GFP_KERNEL);
+ }
+
+- rcu_assign_sk_user_data(sk, ovpn_sock);
+ sock_release:
+ release_sock(sk);
+ return ovpn_sock;
+diff --git a/drivers/net/ovpn/tcp.c b/drivers/net/ovpn/tcp.c
+index 0d7f30360d874..f0b4e07ba9245 100644
+--- a/drivers/net/ovpn/tcp.c
++++ b/drivers/net/ovpn/tcp.c
+@@ -487,6 +487,7 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock,
+ /* make sure no pre-existing encapsulation handler exists */
+ if (ovpn_sock->sk->sk_user_data)
+ return -EBUSY;
++ rcu_assign_sk_user_data(ovpn_sock->sk, ovpn_sock);
+
+ /* only a fully connected socket is expected. Connection should be
+ * handled in userspace
+@@ -495,13 +496,14 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock,
+ net_err_ratelimited("%s: provided TCP socket is not in ESTABLISHED state: %d\n",
+ netdev_name(peer->ovpn->dev),
+ ovpn_sock->sk->sk_state);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto err;
+ }
+
+ ret = strp_init(&peer->tcp.strp, ovpn_sock->sk, &cb);
+ if (ret < 0) {
+ DEBUG_NET_WARN_ON_ONCE(1);
+- return ret;
++ goto err;
+ }
+
+ INIT_WORK(&peer->tcp.defer_del_work, ovpn_tcp_peer_del_work);
+@@ -536,6 +538,9 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock,
+ strp_check_rcv(&peer->tcp.strp);
+
+ return 0;
++err:
++ rcu_assign_sk_user_data(ovpn_sock->sk, NULL);
++ return ret;
+ }
+
+ static void ovpn_tcp_close(struct sock *sk, long timeout)
+diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c
+index d6a0f7a0b75d7..272b535ecaad4 100644
+--- a/drivers/net/ovpn/udp.c
++++ b/drivers/net/ovpn/udp.c
+@@ -386,6 +386,7 @@ int ovpn_udp_socket_attach(struct ovpn_socket *ovpn_sock, struct socket *sock,
+ struct ovpn_priv *ovpn)
+ {
+ struct udp_tunnel_sock_cfg cfg = {
++ .sk_user_data = ovpn_sock,
+ .encap_type = UDP_ENCAP_OVPNINUDP,
+ .encap_rcv = ovpn_udp_encap_recv,
+ .encap_destroy = ovpn_udp_encap_destroy,
+--
+2.51.0
+
--- /dev/null
+From 367fa4b931d0362f2a7cd70f62136d4e39a3d04f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 22:31:19 +0100
+Subject: ovpn: tcp - don't deref NULL sk_socket member after tcp_close()
+
+From: Antonio Quartulli <antonio@openvpn.net>
+
+[ Upstream commit 94560267d6c41b1ff3fafbab726e3f8a55a6af34 ]
+
+When deleting a peer in case of keepalive expiration, the peer is
+removed from the OpenVPN hashtable and is temporary inserted in a
+"release list" for further processing.
+
+This happens in:
+ovpn_peer_keepalive_work()
+ unlock_ovpn(release_list)
+
+This processing includes detaching from the socket being used to
+talk to this peer, by restoring its original proto and socket
+ops/callbacks.
+
+In case of TCP it may happen that, while the peer is sitting in
+the release list, userspace decides to close the socket.
+This will result in a concurrent execution of:
+
+tcp_close(sk)
+ __tcp_close(sk)
+ sock_orphan(sk)
+ sk_set_socket(sk, NULL)
+
+The last function call will set sk->sk_socket to NULL.
+
+When the releasing routine is resumed, ovpn_tcp_socket_detach()
+will attempt to dereference sk->sk_socket to restore its original
+ops member. This operation will crash due to sk->sk_socket being NULL.
+
+Fix this race condition by testing-and-accessing
+sk->sk_socket atomically under sk->sk_callback_lock.
+
+Link: https://lore.kernel.org/netdev/176996279620.3109699.15382994681575380467@eldamar.lan/
+Link: https://github.com/OpenVPN/ovpn-net-next/issues/29
+Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
+Fixes: 11851cbd60ea ("ovpn: implement TCP transport")
+Link: https://patch.msgid.link/20260212213130.11497-1-antonio@openvpn.net
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ovpn/tcp.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ovpn/tcp.c b/drivers/net/ovpn/tcp.c
+index f0b4e07ba9245..ec2bbc28c1966 100644
+--- a/drivers/net/ovpn/tcp.c
++++ b/drivers/net/ovpn/tcp.c
+@@ -199,7 +199,19 @@ void ovpn_tcp_socket_detach(struct ovpn_socket *ovpn_sock)
+ sk->sk_data_ready = peer->tcp.sk_cb.sk_data_ready;
+ sk->sk_write_space = peer->tcp.sk_cb.sk_write_space;
+ sk->sk_prot = peer->tcp.sk_cb.prot;
+- sk->sk_socket->ops = peer->tcp.sk_cb.ops;
++
++ /* tcp_close() may race this function and could set
++ * sk->sk_socket to NULL. It does so by invoking
++ * sock_orphan(), which holds sk_callback_lock before
++ * doing the assignment.
++ *
++ * For this reason we acquire the same lock to avoid
++ * sk_socket to disappear under our feet
++ */
++ write_lock_bh(&sk->sk_callback_lock);
++ if (sk->sk_socket)
++ sk->sk_socket->ops = peer->tcp.sk_cb.ops;
++ write_unlock_bh(&sk->sk_callback_lock);
+
+ rcu_assign_sk_user_data(sk, NULL);
+ }
+--
+2.51.0
+
--- /dev/null
+From 11e8f743df3ee52818f3cc9670a55990ae596d8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 22:20:57 +0800
+Subject: PCI: Validate window resource type in pbus_select_window_for_type()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kai-Heng Feng <kaihengf@nvidia.com>
+
+[ Upstream commit e5f72cb9cea599dc9f5a9b80a33560a1d06f01cc ]
+
+After ebe091ad81e1 ("PCI: Use pbus_select_window_for_type() during IO
+window sizing") and ae88d0b9c57f ("PCI: Use pbus_select_window_for_type()
+during mem window sizing"), many bridge windows can't get resources
+assigned:
+
+ pci 0006:05:00.0: bridge window [??? 0x00001000-0x00001fff flags 0x20080000]: can't assign; no space
+ pci 0006:05:00.0: bridge window [??? 0x00001000-0x00001fff flags 0x20080000]: failed to assign
+
+Those commits replace find_bus_resource_of_type() with
+pbus_select_window_for_type(), and the latter lacks resource type
+validation.
+
+Add the resource type validation back to pbus_select_window_for_type() to
+match the original behavior.
+
+Fixes: 74afce3dfcba ("PCI: Add bridge window selection functions")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=221072
+Signed-off-by: Kai-Heng Feng <kaihengf@nvidia.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://patch.msgid.link/20260210142058.82701-1-kaihengf@nvidia.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/setup-bus.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
+index 4f4890196e63e..cc592ccff5424 100644
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -221,14 +221,21 @@ static struct resource *pbus_select_window_for_type(struct pci_bus *bus,
+
+ switch (iores_type) {
+ case IORESOURCE_IO:
+- return pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW);
++ win = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW);
++ if (win && (win->flags & IORESOURCE_IO))
++ return win;
++ return NULL;
+
+ case IORESOURCE_MEM:
+ mmio = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_MEM_WINDOW);
+ mmio_pref = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_PREF_MEM_WINDOW);
+
+- if (!(type & IORESOURCE_PREFETCH) ||
+- !(mmio_pref->flags & IORESOURCE_MEM))
++ if (mmio && !(mmio->flags & IORESOURCE_MEM))
++ mmio = NULL;
++ if (mmio_pref && !(mmio_pref->flags & IORESOURCE_MEM))
++ mmio_pref = NULL;
++
++ if (!(type & IORESOURCE_PREFETCH) || !mmio_pref)
+ return mmio;
+
+ if ((type & IORESOURCE_MEM_64) ||
+--
+2.51.0
+
--- /dev/null
+From a91ca9f2f24ea8373f4e3e95983db73fcc9e7458 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:01:49 +0000
+Subject: ping: annotate data-races in ping_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit ad5dfde2a5733aaf652ea3e40c8c5e071e935901 ]
+
+isk->inet_num, isk->inet_rcv_saddr and sk->sk_bound_dev_if
+are read locklessly in ping_lookup().
+
+Add READ_ONCE()/WRITE_ONCE() annotations.
+
+The race on isk->inet_rcv_saddr is probably coming from IPv6 support,
+but does not deserve a specific backport.
+
+Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216100149.3319315-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ping.c | 31 +++++++++++++++++++------------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index a5227d23bb0b5..690f486173e01 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -148,7 +148,7 @@ void ping_unhash(struct sock *sk)
+ pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+ spin_lock(&ping_table.lock);
+ if (sk_del_node_init_rcu(sk)) {
+- isk->inet_num = 0;
++ WRITE_ONCE(isk->inet_num, 0);
+ isk->inet_sport = 0;
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+ }
+@@ -181,31 +181,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ }
+
+ sk_for_each_rcu(sk, hslot) {
++ int bound_dev_if;
++
+ if (!net_eq(sock_net(sk), net))
+ continue;
+ isk = inet_sk(sk);
+
+ pr_debug("iterate\n");
+- if (isk->inet_num != ident)
++ if (READ_ONCE(isk->inet_num) != ident)
+ continue;
+
++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+ if (skb->protocol == htons(ETH_P_IP) &&
+ sk->sk_family == AF_INET) {
++ __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr);
++
+ pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk,
+- (int) isk->inet_num, &isk->inet_rcv_saddr,
+- sk->sk_bound_dev_if);
++ ident, &rcv_saddr,
++ bound_dev_if);
+
+- if (isk->inet_rcv_saddr &&
+- isk->inet_rcv_saddr != ip_hdr(skb)->daddr)
++ if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr)
+ continue;
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (skb->protocol == htons(ETH_P_IPV6) &&
+ sk->sk_family == AF_INET6) {
+
+ pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk,
+- (int) isk->inet_num,
++ ident,
+ &sk->sk_v6_rcv_saddr,
+- sk->sk_bound_dev_if);
++ bound_dev_if);
+
+ if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) &&
+ !ipv6_addr_equal(&sk->sk_v6_rcv_saddr,
+@@ -216,8 +220,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ continue;
+ }
+
+- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
+- sk->sk_bound_dev_if != sdif)
++ if (bound_dev_if && bound_dev_if != dif &&
++ bound_dev_if != sdif)
+ continue;
+
+ goto exit;
+@@ -392,7 +396,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr *saddr)
+ if (saddr->sa_family == AF_INET) {
+ struct inet_sock *isk = inet_sk(sk);
+ struct sockaddr_in *addr = (struct sockaddr_in *) saddr;
+- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
++
++ isk->inet_saddr = addr->sin_addr.s_addr;
++ WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr);
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (saddr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr;
+@@ -849,7 +855,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
+ struct sk_buff *skb;
+ int copied, err;
+
+- pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
++ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk,
++ READ_ONCE(isk->inet_num));
+
+ err = -EOPNOTSUPP;
+ if (flags & MSG_OOB)
+--
+2.51.0
+
--- /dev/null
+From c185b1a211879406ec5072b8824b677cbfa5c4d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 14:34:01 -0800
+Subject: powercap: intel_rapl_tpmi: Remove FW_BUG from invalid version check
+
+From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+
+[ Upstream commit c7d54dafa042cf379859dba265fe5afef6fa8770 ]
+
+On partitioned systems, multiple TPMI instances may exist per package,
+but RAPL registers are only valid on one instance since RAPL has
+package-scope control. Other instances return invalid versions during
+domain parsing, which is expected behavior on such systems.
+
+Currently this generates a firmware bug warning:
+
+ intel_rapl_tpmi: [Firmware Bug]: Invalid version
+
+Remove the FW_BUG tag, downgrade to pr_debug(), and update the message
+to clarify that invalid versions are expected on partitioned systems
+where only one instance can be valid.
+
+Fixes: 9eef7f9da928 ("powercap: intel_rapl: Introduce RAPL TPMI interface driver")
+Reported-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Reviewed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Link: https://patch.msgid.link/20260211223401.1575776-1-sathyanarayanan.kuppuswamy@linux.intel.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/powercap/intel_rapl_tpmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/powercap/intel_rapl_tpmi.c b/drivers/powercap/intel_rapl_tpmi.c
+index 82201bf4685d4..34c0bd1edd61a 100644
+--- a/drivers/powercap/intel_rapl_tpmi.c
++++ b/drivers/powercap/intel_rapl_tpmi.c
+@@ -157,7 +157,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
+ tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff;
+
+ if (tpmi_domain_version == TPMI_VERSION_INVALID) {
+- pr_warn(FW_BUG "Invalid version\n");
++ pr_debug("Invalid version, other instances may be valid\n");
+ return -ENODEV;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 87452ab1651d971a3ea83941cd78fd7774af9130 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 07:29:16 +0100
+Subject: s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n
+
+From: Alexander Egorenkov <egorenar@linux.ibm.com>
+
+[ Upstream commit dd3411959b57df6e05a3ccbac67b0a836871c0c4 ]
+
+The commit c8424e776b09 ("MODSIGN: Export module signature definitions")
+replaced the dependency of KEXEC_SIG on SYSTEM_DATA_VERIFICATION with the
+dependency on MODULE_SIG_FORMAT. This change disables KEXEC_SIG in s390
+kernels built with MODULES=n if nothing else selects MODULE_SIG_FORMAT.
+
+Furthermore, the signature verification in s390 kexec does not require
+MODULE_SIG_FORMAT because it requires only the struct module_signature and,
+therefore, does not depend on code in kernel/module_signature.c.
+
+But making ARCH_SUPPORTS_KEXEC_SIG depend on SYSTEM_DATA_VERIFICATION is
+also incorrect because it makes KEXEC_SIG available on s390 only if some
+other arbitrary option (for instance a file system or device driver)
+selects it directly or indirectly.
+
+To properly make KEXEC_SIG available for s390 kernels built with MODULES=y
+as well as MODULES=n _and_ also not depend on arbitrary options selecting
+SYSTEM_DATA_VERIFICATION, set ARCH_SUPPORTS_KEXEC_SIG=y for s390 and select
+SYSTEM_DATA_VERIFICATION when KEXEC_SIG=y.
+
+Fixes: c8424e776b09 ("MODSIGN: Export module signature definitions")
+Suggested-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index df22b10d91415..e60d2b823e091 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -270,6 +270,7 @@ config S390
+ select SPARSE_IRQ
+ select SWIOTLB
+ select SYSCTL_EXCEPTION_TRACE
++ select SYSTEM_DATA_VERIFICATION if KEXEC_SIG
+ select THREAD_INFO_IN_TASK
+ select TRACE_IRQFLAGS_SUPPORT
+ select TTY
+@@ -296,7 +297,7 @@ config ARCH_SUPPORTS_KEXEC_FILE
+ def_bool y
+
+ config ARCH_SUPPORTS_KEXEC_SIG
+- def_bool MODULE_SIG_FORMAT
++ def_bool y
+
+ config ARCH_SUPPORTS_KEXEC_PURGATORY
+ def_bool y
+--
+2.51.0
+
--- /dev/null
+From ece8a789c000199523e04fb21979b6810c337c82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:05 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with
+ br_netfilter enabled
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv4 packet contains a zero IP header checksum. After VXLAN
+decapsulation, such packets do not pass sanity checks in br_netfilter
+and are dropped, which causes the test to fail.
+
+Fix this by calculating and setting a valid IPv4 header checksum for the
+encapsulated packet generated by mausezahn, so that the packet is accepted
+by br_netfilter. Fixed by using the payload_template_calc_checksum() /
+payload_template_expand_checksum() helpers that are only available
+in v6.3 and newer kernels.
+
+Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++-------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+index b43816dd998ca..457f41d5e584b 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+@@ -567,6 +567,21 @@ vxlan_encapped_ping_do()
+ local inner_tos=$1; shift
+ local outer_tos=$1; shift
+
++ local ipv4hdr=$(:
++ )"45:"$( : IP version + IHL
++ )"$inner_tos:"$( : IP TOS
++ )"00:54:"$( : IP total length
++ )"99:83:"$( : IP identification
++ )"40:00:"$( : IP flags + frag off
++ )"40:"$( : IP TTL
++ )"01:"$( : IP proto
++ )"CHECKSUM:"$( : IP header csum
++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1
++ )
++ local checksum=$(payload_template_calc_checksum "$ipv4hdr")
++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum)
++
+ $MZ $dev -c $count -d 100msec -q \
+ -b $next_hop_mac -B $dest_ip \
+ -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(:
+@@ -577,16 +592,7 @@ vxlan_encapped_ping_do()
+ )"$dest_mac:"$( : ETH daddr
+ )"$(mac_get w2):"$( : ETH saddr
+ )"08:00:"$( : ETH type
+- )"45:"$( : IP version + IHL
+- )"$inner_tos:"$( : IP TOS
+- )"00:54:"$( : IP total length
+- )"99:83:"$( : IP identification
+- )"40:00:"$( : IP flags + frag off
+- )"40:"$( : IP TTL
+- )"01:"$( : IP proto
+- )"00:00:"$( : IP header csum
+- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
+- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1
++ )"$ipv4hdr:"$( : IPv4 header
+ )"08:"$( : ICMP type
+ )"00:"$( : ICMP code
+ )"8b:f2:"$( : ICMP csum
+--
+2.51.0
+
--- /dev/null
+From c822a675bd483e61c9f3f94350845629fad1f7ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:06 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with
+ br_netfilter enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit ce9f6aec0fb780dafc1dfc5f47c688422aff464a ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv6 packet has an incorrect payload length set in the IPv6 header.
+After VXLAN decapsulation, such packets do not pass sanity checks in
+br_netfilter and are dropped, which causes the test to fail.
+
+Fix this by setting the correct IPv6 payload length for the encapsulated
+packet generated by mausezahn, so that the packet is accepted
+by br_netfilter.
+
+tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+lines 698-706
+
+ )"00:03:"$( : Payload length
+ )"3a:"$( : Next header
+ )"04:"$( : Hop limit
+ )"$saddr:"$( : IP saddr
+ )"$daddr:"$( : IP daddr
+ )"80:"$( : ICMPv6.type
+ )"00:"$( : ICMPv6.code
+ )"00:"$( : ICMPv6.checksum
+ )
+
+Data after IPv6 header:
+• 80: — 1 byte (ICMPv6 type)
+• 00: — 1 byte (ICMPv6 code)
+• 00: — 1 byte (ICMPv6 checksum, truncated)
+
+Total: 3 bytes → 00:03 is correct. The old value 00:08 did not match
+the actual payload size.
+
+Fixes: b07e9957f220 ("selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for IPv6")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-3-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+index a603f7b0a08f0..e642feeada0e7 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+@@ -695,7 +695,7 @@ vxlan_encapped_ping_do()
+ )"6"$( : IP version
+ )"$inner_tos"$( : Traffic class
+ )"0:00:00:"$( : Flow label
+- )"00:08:"$( : Payload length
++ )"00:03:"$( : Payload length
+ )"3a:"$( : Next header
+ )"04:"$( : Hop limit
+ )"$saddr:"$( : IP saddr
+--
+2.51.0
+
--- /dev/null
+From 61bf23070fa5852a9c7290f269bba687462bc520 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 09:38:05 -0500
+Subject: selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT
+
+From: Aristeu Rozanski <aris@redhat.com>
+
+[ Upstream commit b24335521de92fd2ee22460072b75367ca8860b0 ]
+
+selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT
+
+In order to synchronize new processes to test inheritance of memfd_noexec
+sysctl, memfd_test sets up the sysctl with a value before creating the new
+process. The new process then sends itself a SIGSTOP in order to wait for
+the parent to flip the sysctl value and send a SIGCONT signal.
+
+This would work as intended if it wasn't the fact that the new process is
+being created with CLONE_NEWPID, which creates a new PID namespace and the
+new process has PID 1 in this namespace. There're restrictions on sending
+signals to PID 1 and, although it's relaxed for other than root PID
+namespace, it's biting us here. In this specific case the SIGSTOP sent by
+the new process is ignored (no error to kill() is returned) and it never
+stops its execution. This is usually not noticiable as the parent usually
+manages to set the new sysctl value before the child has a chance to run
+and the test succeeds. But if you run the test in a loop, it eventually
+reproduces:
+
+ while [ 1 ]; do ./memfd_test >log 2>&1 || break; done; cat log
+
+So this patch replaces the SIGSTOP/SIGCONT synchronization with IPC
+semaphore.
+
+Link: https://lkml.kernel.org/r/a7776389-b3d6-4b18-b438-0b0e3ed1fd3b@work
+Fixes: 6469b66e3f5a ("selftests: improve vm.memfd_noexec sysctl tests")
+Signed-off-by: Aristeu Rozanski <aris@redhat.com>
+Cc: Aleksa Sarai <cyphar@cyphar.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: liuye <liuye@kylinos.cn>
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/memfd/memfd_test.c | 113 +++++++++++++++++++--
+ 1 file changed, 105 insertions(+), 8 deletions(-)
+
+diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c
+index 5b993924cc3f5..2ca07ea7202a5 100644
+--- a/tools/testing/selftests/memfd/memfd_test.c
++++ b/tools/testing/selftests/memfd/memfd_test.c
+@@ -18,6 +18,9 @@
+ #include <sys/stat.h>
+ #include <sys/syscall.h>
+ #include <sys/wait.h>
++#include <sys/types.h>
++#include <sys/ipc.h>
++#include <sys/sem.h>
+ #include <unistd.h>
+ #include <ctype.h>
+
+@@ -39,6 +42,20 @@
+ F_SEAL_EXEC)
+
+ #define MFD_NOEXEC_SEAL 0x0008U
++union semun {
++ int val;
++ struct semid_ds *buf;
++ unsigned short int *array;
++ struct seminfo *__buf;
++};
++
++/*
++ * we use semaphores on nested wait tasks due the use of CLONE_NEWPID: the
++ * child will be PID 1 and can't send SIGSTOP to themselves due special
++ * treatment of the init task, so the SIGSTOP/SIGCONT synchronization
++ * approach can't be used here.
++ */
++#define SEM_KEY 0xdeadbeef
+
+ /*
+ * Default is not to test hugetlbfs
+@@ -1333,8 +1350,22 @@ static int sysctl_nested(void *arg)
+
+ static int sysctl_nested_wait(void *arg)
+ {
+- /* Wait for a SIGCONT. */
+- kill(getpid(), SIGSTOP);
++ int sem = semget(SEM_KEY, 1, 0600);
++ struct sembuf sembuf;
++
++ if (sem < 0) {
++ perror("semget:");
++ abort();
++ }
++ sembuf.sem_num = 0;
++ sembuf.sem_flg = 0;
++ sembuf.sem_op = 0;
++
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ abort();
++ }
++
+ return sysctl_nested(arg);
+ }
+
+@@ -1355,7 +1386,9 @@ static void test_sysctl_sysctl2_failset(void)
+
+ static int sysctl_nested_child(void *arg)
+ {
+- int pid;
++ int pid, sem;
++ union semun semun;
++ struct sembuf sembuf;
+
+ printf("%s nested sysctl 0\n", memfd_str);
+ sysctl_assert_write("0");
+@@ -1389,23 +1422,53 @@ static int sysctl_nested_child(void *arg)
+ test_sysctl_sysctl2_failset);
+ join_thread(pid);
+
++ sem = semget(SEM_KEY, 1, IPC_CREAT | 0600);
++ if (sem < 0) {
++ perror("semget:");
++ return 1;
++ }
++ semun.val = 1;
++ sembuf.sem_op = -1;
++ sembuf.sem_flg = 0;
++ sembuf.sem_num = 0;
++
+ /* Verify that the rules are actually inherited after fork. */
+ printf("%s nested sysctl 0 -> 1 after fork\n", memfd_str);
+ sysctl_assert_write("0");
+
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl1_failset);
+ sysctl_assert_write("1");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 0 -> 2 after fork\n", memfd_str);
+ sysctl_assert_write("0");
+
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2_failset);
+ sysctl_assert_write("2");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ /*
+@@ -1415,28 +1478,62 @@ static int sysctl_nested_child(void *arg)
+ */
+ printf("%s nested sysctl 2 -> 1 after fork\n", memfd_str);
+ sysctl_assert_write("2");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2);
+ sysctl_assert_write("1");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 2 -> 0 after fork\n", memfd_str);
+ sysctl_assert_write("2");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2);
+ sysctl_assert_write("0");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 1 -> 0 after fork\n", memfd_str);
+ sysctl_assert_write("1");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl1);
+ sysctl_assert_write("0");
+- kill(pid, SIGCONT);
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
++ semctl(sem, 0, IPC_RMID);
++
+ return 0;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From bce12126b66fc80ef6456edb905659b9b2b4754b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 14:53:53 +0100
+Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ]
+
+As explained in [1], iproute2 started rejecting tc-police burst sizes
+that result in an overflow. This can happen when the burst size is high
+enough and the rate is low enough.
+
+A couple of test cases specify such configurations, resulting in
+iproute2 errors and test failure.
+
+Fix by reducing the burst size so that the test will pass with both new
+and old iproute2 versions.
+
+[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/
+
+Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+index 0441a18f098b1..aac8ef490feb8 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+@@ -317,7 +317,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 0.5kbit burst 1m conform-exceed drop/ok
++ action police rate 0.5kbit burst 2k conform-exceed drop/ok
+ check_fail $? "Incorrect success to add police action with too low rate"
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+@@ -327,7 +327,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 1.5kbit burst 1m conform-exceed drop/ok
++ action police rate 1.5kbit burst 2k conform-exceed drop/ok
+ check_err $? "Failed to add police action with low rate"
+
+ tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
+--
+2.51.0
+
--- /dev/null
+From 168265ad3d36fecb38483b8266213b1f635be6da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 10:21:46 +0800
+Subject: selftests: net: lib: Fix jq parsing error
+
+From: Yue Haibing <yuehaibing@huawei.com>
+
+[ Upstream commit 10ec0fc0ccc525abc807b0ca8ad5a26a0bd56361 ]
+
+The testcase failed as below:
+$./vlan_bridge_binding.sh
+...
++ adf_ip_link_set_up d1
++ local name=d1
++ shift
++ ip_link_is_up d1
++ ip_link_has_flag d1 UP
++ local name=d1
++ shift
++ local flag=UP
++ shift
+++ ip -j link show d1
+++ jq --arg flag UP 'any(.[].flags.[]; . == $flag)'
+jq: error: syntax error, unexpected '[', expecting FORMAT or QQSTRING_START
+ (Unix shell quoting issues?) at <top-level>, line 1:
+any(.[].flags.[]; . == $flag)
+jq: 1 compile error
+
+Remove the extra dot (.) after flags array to fix this.
+
+Fixes: 4baa1d3a5080 ("selftests: net: lib: Add ip_link_has_flag()")
+Signed-off-by: Yue Haibing <yuehaibing@huawei.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/20260211022146.190948-1-yuehaibing@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/lib.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh
+index f448bafb3f208..d0306b27fe95e 100644
+--- a/tools/testing/selftests/net/lib.sh
++++ b/tools/testing/selftests/net/lib.sh
+@@ -576,7 +576,7 @@ ip_link_has_flag()
+ local flag=$1; shift
+
+ local state=$(ip -j link show "$name" |
+- jq --arg flag "$flag" 'any(.[].flags.[]; . == $flag)')
++ jq --arg flag "$flag" 'any(.[].flags[]; . == $flag)')
+ [[ $state == true ]]
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 98793afd45c712d524a87c236f24e4f88bc71c59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 16:59:36 -0800
+Subject: selftests: netconsole: Increase port listening timeout
+
+From: Pin-yen Lin <treapking@google.com>
+
+[ Upstream commit a68a9bd086c2822d0c629443bd16ad1317afe501 ]
+
+wait_for_port() can wait up to 2 seconds with the sleep and the polling
+in wait_local_port_listen() combined. So, in netcons_basic.sh, the socat
+process could die before the test writes to the netconsole.
+
+Increase the timeout to 3 seconds to make netcons_basic.sh pass
+consistently.
+
+Fixes: 3dc6c76391cb ("selftests: net: Add IPv6 support to netconsole basic tests")
+Signed-off-by: Pin-yen Lin <treapking@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260210005939.3230550-1-treapking@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
+index ae8abff4be409..64d3941576d5d 100644
+--- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
++++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
+@@ -247,8 +247,8 @@ function listen_port_and_save_to() {
+ SOCAT_MODE="UDP6-LISTEN"
+ fi
+
+- # Just wait for 2 seconds
+- timeout 2 ip netns exec "${NAMESPACE}" \
++ # Just wait for 3 seconds
++ timeout 3 ip netns exec "${NAMESPACE}" \
+ socat "${SOCAT_MODE}":"${PORT}",fork "${OUTPUT}" 2> /dev/null
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 3d542821716708d86fd2315a60286fdb4d930f3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Nov 2025 12:24:19 +0000
+Subject: selftests: netconsole: remove log noise due to socat exit
+
+From: Andre Carvalho <asantostc@gmail.com>
+
+[ Upstream commit e3b8cbf40c6e60a7a935bd8980884d5741a7a77b ]
+
+This removes some noise that can be distracting while looking at
+selftests by redirecting socat stderr to /dev/null.
+
+Before this commit, netcons_basic would output:
+
+Running with target mode: basic (ipv6)
+2025/11/29 12:08:03 socat[259] W exiting on signal 15
+2025/11/29 12:08:03 socat[271] W exiting on signal 15
+basic : ipv6 : Test passed
+Running with target mode: basic (ipv4)
+2025/11/29 12:08:05 socat[329] W exiting on signal 15
+2025/11/29 12:08:05 socat[322] W exiting on signal 15
+basic : ipv4 : Test passed
+Running with target mode: extended (ipv6)
+2025/11/29 12:08:08 socat[386] W exiting on signal 15
+2025/11/29 12:08:08 socat[386] W exiting on signal 15
+2025/11/29 12:08:08 socat[380] W exiting on signal 15
+extended : ipv6 : Test passed
+Running with target mode: extended (ipv4)
+2025/11/29 12:08:10 socat[440] W exiting on signal 15
+2025/11/29 12:08:10 socat[435] W exiting on signal 15
+2025/11/29 12:08:10 socat[435] W exiting on signal 15
+extended : ipv4 : Test passed
+
+After these changes, output looks like:
+
+Running with target mode: basic (ipv6)
+basic : ipv6 : Test passed
+Running with target mode: basic (ipv4)
+basic : ipv4 : Test passed
+Running with target mode: extended (ipv6)
+extended : ipv6 : Test passed
+Running with target mode: extended (ipv4)
+extended : ipv4 : Test passed
+
+Signed-off-by: Andre Carvalho <asantostc@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20251129-netcons-socat-noise-v1-1-605a0cea8fca@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: a68a9bd086c2 ("selftests: netconsole: Increase port listening timeout")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
+index 87f89fd92f8c1..ae8abff4be409 100644
+--- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
++++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
+@@ -249,7 +249,7 @@ function listen_port_and_save_to() {
+
+ # Just wait for 2 seconds
+ timeout 2 ip netns exec "${NAMESPACE}" \
+- socat "${SOCAT_MODE}":"${PORT}",fork "${OUTPUT}"
++ socat "${SOCAT_MODE}":"${PORT}",fork "${OUTPUT}" 2> /dev/null
+ }
+
+ # Only validate that the message arrived properly
+--
+2.51.0
+
--- /dev/null
+From fa08d10ee1af96c1b8e5ecea3d3dc040f40e8331 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 19:51:59 -0800
+Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ]
+
+Since we started running selftests in NIPA we have been seeing
+tc_actions.sh generate a soft lockup warning on ~20% of the runs.
+On the pre-netdev foundation setup it was actually a missed irq
+splat from the console. Now it's either that or a lockup.
+
+I initially suspected a socket locking issue since the test
+is exercising local loopback with act_mirred.
+After hours of staring at this I noticed in strace that ncat
+when -o $file is specified _both_ saves the output to the file
+and still prints it to stdout. Because the file being sent
+is constructed with:
+
+ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred
+ ^^^^^^^^^
+
+the data printed is all \0. Most terminals don't display nul
+characters (and neither does vng output capture save them).
+But QEMU's serial console still has to poke them thru which
+is very slow and causes the lockup (if the file is >600kB).
+
+Replace the '-o $file' with '> $file'. This speeds the test up
+from 2m20s to 18s on debug kernels, and prevents the warnings.
+
+Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index ea89e558672db..86edbc7e2489b 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -223,7 +223,7 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 &
+ local rpid=$!
+ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+--
+2.51.0
+
drbd-always-set-blk_feat_stable_writes.patch
io_uring-delay-sqarray-static-branch-disablement.patch
io_uring-cancel-de-unionize-file-and-user_data-in-st.patch
+fs-ntfs3-initialize-new-folios-before-use.patch
+fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch
+fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch
+acpi-button-adjust-event-notification-routines.patch
+acpi-button-convert-the-driver-to-a-platform-one.patch
+acpi-button-call-device_init_wakeup-earlier-during-p.patch
+acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch
+powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch
+kbuild-add-objtool-to-top-level-clean-target.patch
+selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch
+objpool-fix-the-overestimation-of-object-pooling-met.patch
+acpi-pm-add-unused-power-resource-quirk-for-thundero.patch
+cpuidle-skip-governor-when-only-one-idle-state-is-av.patch
+ovpn-set-sk_user_data-before-overriding-callbacks.patch
+ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch
+ovpn-fix-vpn-tx-bytes-counting.patch
+selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch
+selftests-net-lib-fix-jq-parsing-error.patch
+net-stmmac-remove-broken-pcs-code.patch
+net-stmmac-replace-has_xxxx-with-core_type.patch
+net-stmmac-fix-oops-when-split-header-is-enabled.patch
+net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch
+net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch
+net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch
+net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch
+selftests-netconsole-remove-log-noise-due-to-socat-e.patch
+selftests-netconsole-increase-port-listening-timeout.patch
+ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch
+net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch
+fbnic-close-fw_log-race-between-users-and-teardown.patch
+libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch
+bpf-fix-a-potential-use-after-free-of-btf-object.patch
+bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch
+eth-fbnic-configure-rde-settings-for-pause-frame.patch
+eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch
+eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch
+eth-fbnic-set-dma_hint_l4-for-all-flows.patch
+ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch
+net-usb-catc-enable-basic-endpoint-checking.patch
+xen-netback-reject-zero-queue-configuration-from-gue.patch
+net-rds-rds_sendmsg-should-not-discard-payload_len.patch
+net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch
+selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch
+selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch
+netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch
+ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch
+net-remove-warn_on_once-when-accessing-forward-path-.patch
+netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch
+ipv6-fix-a-race-in-ip6_sock_set_v6only.patch
+bpftool-fix-truncated-netlink-dumps.patch
+net-psp-select-config_skb_extensions.patch
+ping-annotate-data-races-in-ping_lookup.patch
+selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch
+macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch
+eth-fbnic-add-validation-for-mtu-changes.patch
+icmp-prevent-possible-overflow-in-icmp_global_allow.patch
+inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch
+ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch
+octeontx2-af-fix-default-entries-mcam-entry-action.patch
+eth-fbnic-advertise-supported-xdp-features.patch
+bnge-fix-reserving-resources-from-fw.patch
+bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch
+net-mlx5-fix-multiport-device-check-over-light-sfs.patch
+net-mlx5-fix-misidentification-of-write-combining-cq.patch
+net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch
+net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch
+apparmor-fix-null-pointer-dereference-in-__unix_need.patch
+apparmor-fix-null-sock-in-aa_sock_file_perm.patch
+apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch
+apparmor-fix-optimize-table-creation-from-possibly-u.patch
+apparmor-return-enomem-in-unpack_perms_table-upon-al.patch
+apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch
+apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch
+apparmor-account-for-in_atomic-removal-in-common_fil.patch
+apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch
+apparmor-fix-rlimit-for-posix-cpu-timers.patch
+apparmor-remove-apply_modes_to_perms-from-label_matc.patch
+apparmor-make-label_match-return-a-consistent-value.patch
+apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch
+apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch
+apparmor-fix-aa_label-to-return-state-from-compount-.patch
+drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch
+drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch
+drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch
+drm-amdgpu-move-reset-debug-disable-handling.patch
+drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch
+drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch
+drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch
+mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch
+asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch
+drm-i915-acpi-free-_dsm-package-when-no-connectors.patch
+asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch
+pci-validate-window-resource-type-in-pbus_select_win.patch
+drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch
+drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch
+drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch
+spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch
+s390-kexec-make-kexec_sig-available-when-config_modu.patch
+drm-xe-configfs-fix-parameter-name-omitted-errors.patch
+drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch
+drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch
+drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch
+drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch
+gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch
+efi-fix-reservation-of-unaccepted-memory-table.patch
+btrfs-remove-fs_info-argument-from-btrfs_try_grantin.patch
+btrfs-reduce-block-group-critical-section-in-btrfs_f.patch
+btrfs-reset-block-group-size-class-when-it-becomes-e.patch
+btrfs-use-the-correct-type-to-initialize-block-reser.patch
+btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch
+x86-hyperv-fix-error-pointer-dereference.patch
+asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch
+drm-amd-display-use-same-max-plane-scaling-limits-fo.patch
--- /dev/null
+From 6fb8cccdfa2759526efeab6c7e01e846d08df482 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:41:40 +0800
+Subject: spi: wpcm-fiu: Fix potential NULL pointer dereference in
+ wpcm_fiu_probe()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Felix Gu <ustc.gu@gmail.com>
+
+[ Upstream commit 888a0a802c467bbe34a42167bdf9d7331333440a ]
+
+platform_get_resource_byname() can return NULL, which would cause a crash
+when passed the pointer to resource_size().
+
+Move the fiu->memory_size assignment after the error check for
+devm_ioremap_resource() to prevent the potential NULL pointer dereference.
+
+Fixes: 9838c182471e ("spi: wpcm-fiu: Add direct map support")
+Signed-off-by: Felix Gu <ustc.gu@gmail.com>
+Reviewed-by: J. Neuschäfer <j.ne@posteo.net>
+Link: https://patch.msgid.link/20260212-wpcm-v1-1-5b7c4f526aac@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-wpcm-fiu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c
+index a9aee2a6c7dcb..c47b56f0933f1 100644
+--- a/drivers/spi/spi-wpcm-fiu.c
++++ b/drivers/spi/spi-wpcm-fiu.c
+@@ -459,11 +459,11 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
+ fiu->memory = devm_ioremap_resource(dev, res);
+- fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+ if (IS_ERR(fiu->memory))
+ return dev_err_probe(dev, PTR_ERR(fiu->memory),
+ "Failed to map flash memory window\n");
+
++ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+ fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm");
+
+ wpcm_fiu_hw_init(fiu);
+--
+2.51.0
+
--- /dev/null
+From 6de635b0d2ba01deff2d11ae976441c64bb1788a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 13:09:03 -0600
+Subject: x86/hyperv: Fix error pointer dereference
+
+From: Ethan Tidmore <ethantidmore06@gmail.com>
+
+[ Upstream commit 705d01c8d78121ee1634bfc602ac4b0ad1438fab ]
+
+The function idle_thread_get() can return an error pointer and is not
+checked for it. Add check for error pointer.
+
+Detected by Smatch:
+arch/x86/hyperv/hv_vtl.c:126 hv_vtl_bringup_vcpu() error:
+'idle' dereferencing possible ERR_PTR()
+
+Fixes: 2b4b90e053a29 ("x86/hyperv: Use per cpu initial stack for vtl context")
+Signed-off-by: Ethan Tidmore <ethantidmore06@gmail.com>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/hyperv/hv_vtl.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c
+index 042e8712d8dea..8aafccf7a52c7 100644
+--- a/arch/x86/hyperv/hv_vtl.c
++++ b/arch/x86/hyperv/hv_vtl.c
+@@ -105,7 +105,7 @@ static void hv_vtl_ap_entry(void)
+
+ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
+ {
+- u64 status;
++ u64 status, rsp, rip;
+ int ret = 0;
+ struct hv_enable_vp_vtl *input;
+ unsigned long irq_flags;
+@@ -118,9 +118,11 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
+ struct desc_struct *gdt;
+
+ struct task_struct *idle = idle_thread_get(cpu);
+- u64 rsp = (unsigned long)idle->thread.sp;
++ if (IS_ERR(idle))
++ return PTR_ERR(idle);
+
+- u64 rip = (u64)&hv_vtl_ap_entry;
++ rsp = (unsigned long)idle->thread.sp;
++ rip = (u64)&hv_vtl_ap_entry;
+
+ native_store_gdt(&gdt_ptr);
+ store_idt(&idt_ptr);
+--
+2.51.0
+
--- /dev/null
+From e5dcdb00001b2b357b4ec6de985d9646e8b2eb6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 22:40:40 +0000
+Subject: xen-netback: reject zero-queue configuration from guest
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ]
+
+A malicious or buggy Xen guest can write "0" to the xenbus key
+"multi-queue-num-queues". The connect() function in the backend only
+validates the upper bound (requested_num_queues > xenvif_max_queues)
+but not zero, allowing requested_num_queues=0 to reach
+vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers
+WARN_ON_ONCE(!size) in __vmalloc_node_range().
+
+On systems with panic_on_warn=1, this allows a guest-to-host denial
+of service.
+
+The Xen network interface specification requires
+the queue count to be "greater than zero".
+
+Add a zero check to match the validation already present
+in xen-blkback, which has included this
+guard since its multi-queue support was added.
+
+Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/xen-netback/xenbus.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
+index a78a25b872409..61b547aab286a 100644
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -735,10 +735,11 @@ static void connect(struct backend_info *be)
+ */
+ requested_num_queues = xenbus_read_unsigned(dev->otherend,
+ "multi-queue-num-queues", 1);
+- if (requested_num_queues > xenvif_max_queues) {
++ if (requested_num_queues > xenvif_max_queues ||
++ requested_num_queues == 0) {
+ /* buggy or malicious guest */
+ xenbus_dev_fatal(dev, -EINVAL,
+- "guest requested %u queues, exceeding the maximum of %u.",
++ "guest requested %u queues, but valid range is 1 - %u.",
+ requested_num_queues, xenvif_max_queues);
+ return;
+ }
+--
+2.51.0
+
--- /dev/null
+From 3cf8856fd1a42acdd11e46712f0c261ba34d50ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Dec 2025 14:55:09 +0100
+Subject: ACPI: button: Adjust event notification routines
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 93dc5db6d47aaa3b4b458ddfddfa3369c24e22f4 ]
+
+Adjust the event notification routines in the ACPI button driver to
+take a struct acpi_button pointer as an argument istead of a struct
+acpi_device one where applicable, which allows the use of
+acpi_driver_data() to be limited and will facilitate subsequent
+changes.
+
+No intentional functional impact.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://patch.msgid.link/2260995.Icojqenx9y@rafael.j.wysocki
+Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 67 +++++++++++++++++++++----------------------
+ 1 file changed, 33 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 3c6dd9b4ba0ad..09a6e4ffe9f20 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -169,6 +169,7 @@ static struct acpi_driver acpi_button_driver = {
+ };
+
+ struct acpi_button {
++ struct acpi_device *adev;
+ unsigned int type;
+ struct input_dev *input;
+ char phys[32]; /* for input device */
+@@ -202,9 +203,9 @@ static int acpi_lid_evaluate_state(struct acpi_device *device)
+ return lid_state ? 1 : 0;
+ }
+
+-static int acpi_lid_notify_state(struct acpi_device *device, int state)
++static int acpi_lid_notify_state(struct acpi_button *button, int state)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = button->adev;
+ ktime_t next_report;
+ bool do_update;
+
+@@ -287,18 +288,18 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state)
+ static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq,
+ void *offset)
+ {
+- struct acpi_device *device = seq->private;
++ struct acpi_button *button = seq->private;
+ int state;
+
+- state = acpi_lid_evaluate_state(device);
++ state = acpi_lid_evaluate_state(button->adev);
+ seq_printf(seq, "state: %s\n",
+ state < 0 ? "unsupported" : (state ? "open" : "closed"));
+ return 0;
+ }
+
+-static int acpi_button_add_fs(struct acpi_device *device)
++static int acpi_button_add_fs(struct acpi_button *button)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = button->adev;
+ struct proc_dir_entry *entry = NULL;
+ int ret = 0;
+
+@@ -333,7 +334,7 @@ static int acpi_button_add_fs(struct acpi_device *device)
+ /* create /proc/acpi/button/lid/LID/state */
+ entry = proc_create_single_data(ACPI_BUTTON_FILE_STATE, S_IRUGO,
+ acpi_device_dir(device), acpi_button_state_seq_show,
+- device);
++ button);
+ if (!entry) {
+ ret = -ENODEV;
+ goto remove_dev_dir;
+@@ -355,9 +356,9 @@ static int acpi_button_add_fs(struct acpi_device *device)
+ goto done;
+ }
+
+-static int acpi_button_remove_fs(struct acpi_device *device)
++static int acpi_button_remove_fs(struct acpi_button *button)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = button->adev;
+
+ if (button->type != ACPI_BUTTON_TYPE_LID)
+ return 0;
+@@ -385,9 +386,10 @@ int acpi_lid_open(void)
+ }
+ EXPORT_SYMBOL(acpi_lid_open);
+
+-static int acpi_lid_update_state(struct acpi_device *device,
++static int acpi_lid_update_state(struct acpi_button *button,
+ bool signal_wakeup)
+ {
++ struct acpi_device *device = button->adev;
+ int state;
+
+ state = acpi_lid_evaluate_state(device);
+@@ -397,19 +399,17 @@ static int acpi_lid_update_state(struct acpi_device *device,
+ if (state && signal_wakeup)
+ acpi_pm_wakeup_event(&device->dev);
+
+- return acpi_lid_notify_state(device, state);
++ return acpi_lid_notify_state(button, state);
+ }
+
+-static void acpi_lid_initialize_state(struct acpi_device *device)
++static void acpi_lid_initialize_state(struct acpi_button *button)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
+-
+ switch (lid_init_state) {
+ case ACPI_BUTTON_LID_INIT_OPEN:
+- (void)acpi_lid_notify_state(device, 1);
++ (void)acpi_lid_notify_state(button, 1);
+ break;
+ case ACPI_BUTTON_LID_INIT_METHOD:
+- (void)acpi_lid_update_state(device, false);
++ (void)acpi_lid_update_state(button, false);
+ break;
+ case ACPI_BUTTON_LID_INIT_IGNORE:
+ default:
+@@ -421,8 +421,8 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
+
+ static void acpi_lid_notify(acpi_handle handle, u32 event, void *data)
+ {
+- struct acpi_device *device = data;
+- struct acpi_button *button;
++ struct acpi_button *button = data;
++ struct acpi_device *device = button->adev;
+
+ if (event != ACPI_BUTTON_NOTIFY_STATUS) {
+ acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
+@@ -430,17 +430,16 @@ static void acpi_lid_notify(acpi_handle handle, u32 event, void *data)
+ return;
+ }
+
+- button = acpi_driver_data(device);
+ if (!button->lid_state_initialized)
+ return;
+
+- acpi_lid_update_state(device, true);
++ acpi_lid_update_state(button, true);
+ }
+
+ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+ {
+- struct acpi_device *device = data;
+- struct acpi_button *button;
++ struct acpi_button *button = data;
++ struct acpi_device *device = button->adev;
+ struct input_dev *input;
+ int keycode;
+
+@@ -457,7 +456,6 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+
+ acpi_pm_wakeup_event(&device->dev);
+
+- button = acpi_driver_data(device);
+ if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE)
+ return;
+
+@@ -505,7 +503,7 @@ static int acpi_button_resume(struct device *dev)
+ if (button->type == ACPI_BUTTON_TYPE_LID) {
+ button->last_state = !!acpi_lid_evaluate_state(device);
+ button->last_time = ktime_get();
+- acpi_lid_initialize_state(device);
++ acpi_lid_initialize_state(button);
+ }
+
+ if (button->type == ACPI_BUTTON_TYPE_POWER) {
+@@ -521,12 +519,12 @@ static int acpi_button_resume(struct device *dev)
+
+ static int acpi_lid_input_open(struct input_dev *input)
+ {
+- struct acpi_device *device = input_get_drvdata(input);
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_button *button = input_get_drvdata(input);
++ struct acpi_device *device = button->adev;
+
+ button->last_state = !!acpi_lid_evaluate_state(device);
+ button->last_time = ktime_get();
+- acpi_lid_initialize_state(device);
++ acpi_lid_initialize_state(button);
+
+ return 0;
+ }
+@@ -551,6 +549,7 @@ static int acpi_button_add(struct acpi_device *device)
+
+ device->driver_data = button;
+
++ button->adev = device;
+ button->input = input = input_allocate_device();
+ if (!input) {
+ error = -ENOMEM;
+@@ -587,7 +586,7 @@ static int acpi_button_add(struct acpi_device *device)
+ }
+
+ if (!error)
+- error = acpi_button_add_fs(device);
++ error = acpi_button_add_fs(button);
+
+ if (error) {
+ input_free_device(input);
+@@ -617,7 +616,7 @@ static int acpi_button_add(struct acpi_device *device)
+ break;
+ }
+
+- input_set_drvdata(input, device);
++ input_set_drvdata(input, button);
+ error = input_register_device(input);
+ if (error) {
+ input_free_device(input);
+@@ -628,17 +627,17 @@ static int acpi_button_add(struct acpi_device *device)
+ case ACPI_BUS_TYPE_POWER_BUTTON:
+ status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_button_event,
+- device);
++ button);
+ break;
+ case ACPI_BUS_TYPE_SLEEP_BUTTON:
+ status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_button_event,
+- device);
++ button);
+ break;
+ default:
+ status = acpi_install_notify_handler(device->handle,
+ ACPI_ALL_NOTIFY, handler,
+- device);
++ button);
+ break;
+ }
+ if (ACPI_FAILURE(status)) {
+@@ -661,7 +660,7 @@ static int acpi_button_add(struct acpi_device *device)
+ err_input_unregister:
+ input_unregister_device(input);
+ err_remove_fs:
+- acpi_button_remove_fs(device);
++ acpi_button_remove_fs(button);
+ err_free_button:
+ kfree(button);
+ return error;
+@@ -689,7 +688,7 @@ static void acpi_button_remove(struct acpi_device *device)
+ }
+ acpi_os_wait_events_complete();
+
+- acpi_button_remove_fs(device);
++ acpi_button_remove_fs(button);
+ input_unregister_device(button->input);
+ kfree(button);
+ }
+--
+2.51.0
+
--- /dev/null
+From 83d9fbf06e5510e15fe000aceb8a2e52dbf4a1ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 15:13:26 +0100
+Subject: ACPI: button: Call device_init_wakeup() earlier during probe
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit e91f8c5305b92b63c8bac315f95c535d5c1e8fec ]
+
+Calling device_init_wakeup() after installing a notify handler in which
+wakeup events are signaled may cause a wakeup event to be missed if the
+device is probed right before a system suspend.
+
+To avoid this, move the device_init_wakeup() call in acpi_button_probe()
+before the notify handler installation and add a corresponding cleanup
+to the error path.
+
+Also carry out wakeup cleanup for the button in acpi_button_remove()
+because after that point the notify handler will not run for it and
+wakeup events coming from it will not be signaled.
+
+Fixes: 0d51157dfaac ("ACPI: button: Eliminate the driver notify callback")
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://patch.msgid.link/12854922.O9o76ZdvQC@rafael.j.wysocki
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index b899b8745fedd..38bc64d6bdaf3 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -625,6 +625,8 @@ static int acpi_button_probe(struct platform_device *pdev)
+ goto err_remove_fs;
+ }
+
++ device_init_wakeup(&pdev->dev, true);
++
+ switch (device->device_type) {
+ case ACPI_BUS_TYPE_POWER_BUTTON:
+ status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+@@ -655,11 +657,11 @@ static int acpi_button_probe(struct platform_device *pdev)
+ lid_device = device;
+ }
+
+- device_init_wakeup(&pdev->dev, true);
+ pr_info("%s [%s]\n", name, acpi_device_bid(device));
+ return 0;
+
+ err_input_unregister:
++ device_init_wakeup(&pdev->dev, false);
+ input_unregister_device(input);
+ err_remove_fs:
+ acpi_button_remove_fs(button);
+@@ -691,6 +693,8 @@ static void acpi_button_remove(struct platform_device *pdev)
+ }
+ acpi_os_wait_events_complete();
+
++ device_init_wakeup(&pdev->dev, false);
++
+ acpi_button_remove_fs(button);
+ input_unregister_device(button->input);
+ kfree(button);
+--
+2.51.0
+
--- /dev/null
+From dd0277042a50c38fee804c39f50c9200163693b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Dec 2025 14:57:57 +0100
+Subject: ACPI: button: Convert the driver to a platform one
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 52d86401963666423cb9a56d117136c846093db0 ]
+
+While binding drivers directly to struct acpi_device objects allows
+basic functionality to be provided, at least in the majority of cases,
+there are some problems with it, related to general consistency, sysfs
+layout, power management operation ordering, and code cleanliness.
+
+Overall, it is better to bind drivers to platform devices than to their
+ACPI companions, so convert the ACPI button driver to a platform one.
+
+While this is not expected to alter functionality, it changes sysfs
+layout and so it will be visible to user space.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://patch.msgid.link/2461734.NG923GbCHz@rafael.j.wysocki
+Stable-dep-of: e91f8c5305b9 ("ACPI: button: Call device_init_wakeup() earlier during probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/button.c | 61 +++++++++++++++++++++++--------------------
+ 1 file changed, 32 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
+index 09a6e4ffe9f20..b899b8745fedd 100644
+--- a/drivers/acpi/button.c
++++ b/drivers/acpi/button.c
+@@ -19,6 +19,7 @@
+ #include <linux/slab.h>
+ #include <linux/acpi.h>
+ #include <linux/dmi.h>
++#include <linux/platform_device.h>
+ #include <acpi/button.h>
+
+ #define ACPI_BUTTON_CLASS "button"
+@@ -145,8 +146,8 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
+ {}
+ };
+
+-static int acpi_button_add(struct acpi_device *device);
+-static void acpi_button_remove(struct acpi_device *device);
++static int acpi_button_probe(struct platform_device *pdev);
++static void acpi_button_remove(struct platform_device *pdev);
+
+ #ifdef CONFIG_PM_SLEEP
+ static int acpi_button_suspend(struct device *dev);
+@@ -157,19 +158,19 @@ static int acpi_button_resume(struct device *dev);
+ #endif
+ static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
+
+-static struct acpi_driver acpi_button_driver = {
+- .name = "button",
+- .class = ACPI_BUTTON_CLASS,
+- .ids = button_device_ids,
+- .ops = {
+- .add = acpi_button_add,
+- .remove = acpi_button_remove,
++static struct platform_driver acpi_button_driver = {
++ .probe = acpi_button_probe,
++ .remove = acpi_button_remove,
++ .driver = {
++ .name = "acpi-button",
++ .acpi_match_table = button_device_ids,
++ .pm = &acpi_button_pm,
+ },
+- .drv.pm = &acpi_button_pm,
+ };
+
+ struct acpi_button {
+ struct acpi_device *adev;
++ struct platform_device *pdev;
+ unsigned int type;
+ struct input_dev *input;
+ char phys[32]; /* for input device */
+@@ -397,7 +398,7 @@ static int acpi_lid_update_state(struct acpi_button *button,
+ return state;
+
+ if (state && signal_wakeup)
+- acpi_pm_wakeup_event(&device->dev);
++ acpi_pm_wakeup_event(&button->pdev->dev);
+
+ return acpi_lid_notify_state(button, state);
+ }
+@@ -454,7 +455,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+ return;
+ }
+
+- acpi_pm_wakeup_event(&device->dev);
++ acpi_pm_wakeup_event(&button->pdev->dev);
+
+ if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE)
+ return;
+@@ -486,8 +487,7 @@ static u32 acpi_button_event(void *data)
+ #ifdef CONFIG_PM_SLEEP
+ static int acpi_button_suspend(struct device *dev)
+ {
+- struct acpi_device *device = to_acpi_device(dev);
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_button *button = dev_get_drvdata(dev);
+
+ button->suspended = true;
+ return 0;
+@@ -495,9 +495,9 @@ static int acpi_button_suspend(struct device *dev)
+
+ static int acpi_button_resume(struct device *dev)
+ {
++ struct acpi_button *button = dev_get_drvdata(dev);
++ struct acpi_device *device = ACPI_COMPANION(dev);
+ struct input_dev *input;
+- struct acpi_device *device = to_acpi_device(dev);
+- struct acpi_button *button = acpi_driver_data(device);
+
+ button->suspended = false;
+ if (button->type == ACPI_BUTTON_TYPE_LID) {
+@@ -529,8 +529,9 @@ static int acpi_lid_input_open(struct input_dev *input)
+ return 0;
+ }
+
+-static int acpi_button_add(struct acpi_device *device)
++static int acpi_button_probe(struct platform_device *pdev)
+ {
++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+ acpi_notify_handler handler;
+ struct acpi_button *button;
+ struct input_dev *input;
+@@ -547,8 +548,9 @@ static int acpi_button_add(struct acpi_device *device)
+ if (!button)
+ return -ENOMEM;
+
+- device->driver_data = button;
++ platform_set_drvdata(pdev, button);
+
++ button->pdev = pdev;
+ button->adev = device;
+ button->input = input = input_allocate_device();
+ if (!input) {
+@@ -599,7 +601,7 @@ static int acpi_button_add(struct acpi_device *device)
+ input->phys = button->phys;
+ input->id.bustype = BUS_HOST;
+ input->id.product = button->type;
+- input->dev.parent = &device->dev;
++ input->dev.parent = &pdev->dev;
+
+ switch (button->type) {
+ case ACPI_BUTTON_TYPE_POWER:
+@@ -653,7 +655,7 @@ static int acpi_button_add(struct acpi_device *device)
+ lid_device = device;
+ }
+
+- device_init_wakeup(&device->dev, true);
++ device_init_wakeup(&pdev->dev, true);
+ pr_info("%s [%s]\n", name, acpi_device_bid(device));
+ return 0;
+
+@@ -666,9 +668,10 @@ static int acpi_button_add(struct acpi_device *device)
+ return error;
+ }
+
+-static void acpi_button_remove(struct acpi_device *device)
++static void acpi_button_remove(struct platform_device *pdev)
+ {
+- struct acpi_button *button = acpi_driver_data(device);
++ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
++ struct acpi_button *button = platform_get_drvdata(pdev);
+
+ switch (device->device_type) {
+ case ACPI_BUS_TYPE_POWER_BUTTON:
+@@ -727,7 +730,7 @@ module_param_call(lid_init_state,
+ NULL, 0644);
+ MODULE_PARM_DESC(lid_init_state, "Behavior for reporting LID initial state");
+
+-static int acpi_button_register_driver(struct acpi_driver *driver)
++static int __init acpi_button_init(void)
+ {
+ const struct dmi_system_id *dmi_id;
+
+@@ -743,20 +746,20 @@ static int acpi_button_register_driver(struct acpi_driver *driver)
+ * Modules such as nouveau.ko and i915.ko have a link time dependency
+ * on acpi_lid_open(), and would therefore not be loadable on ACPI
+ * capable kernels booted in non-ACPI mode if the return value of
+- * acpi_bus_register_driver() is returned from here with ACPI disabled
++ * platform_driver_register() is returned from here with ACPI disabled
+ * when this driver is built as a module.
+ */
+ if (acpi_disabled)
+ return 0;
+
+- return acpi_bus_register_driver(driver);
++ return platform_driver_register(&acpi_button_driver);
+ }
+
+-static void acpi_button_unregister_driver(struct acpi_driver *driver)
++static void __exit acpi_button_exit(void)
+ {
+ if (!acpi_disabled)
+- acpi_bus_unregister_driver(driver);
++ platform_driver_unregister(&acpi_button_driver);
+ }
+
+-module_driver(acpi_button_driver, acpi_button_register_driver,
+- acpi_button_unregister_driver);
++module_init(acpi_button_init);
++module_exit(acpi_button_exit);
+--
+2.51.0
+
--- /dev/null
+From 830dbf7eac6d0fef5e8ffbb65b2c383f340a377c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 21:22:54 +0000
+Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs
+
+From: Sean V Kelley <skelley@nvidia.com>
+
+[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all
+possible CPUs. In acpi_get_psd_map(), encountering an offline CPU
+returns -EFAULT, causing cppc_cpufreq initialization to fail.
+
+This breaks systems booted with "nosmt" or "nosmt=force".
+
+Fix by using for_each_online_cpu() in both functions.
+
+Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests")
+Signed-off-by: Sean V Kelley <skelley@nvidia.com>
+Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index e66e20d1f31b7..b59b0100d03c5 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -362,7 +362,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
+ end:
+ if (cmd == CMD_WRITE) {
+ if (unlikely(ret)) {
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i);
+
+ if (!desc)
+@@ -524,7 +524,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data)
+ else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
+ cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ if (i == cpu)
+ continue;
+
+--
+2.51.0
+
--- /dev/null
+From 02b5a6a096df33c81d5f404e281ce8c17e5f4a5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Feb 2026 00:14:52 +0800
+Subject: ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO
+
+From: Zhai Can <bczhc0@126.com>
+
+[ Upstream commit cd7ef20ba8c6e936dba133b4136537a8ada22976 ]
+
+On the THUNDEROBOT ZERO laptop, the second NVMe slot and the discrete
+NVIDIA GPU are both controlled by power-resource PXP. Due to the SSDT table
+bug (lack of reference), PXP will be shut dow as an "unused" power resource
+during initialization, making the NVMe slot #2 + NVIDIA both inaccessible.
+
+This issue was introduced by commit a1224f34d72a ("ACPI: PM: Check
+states of power resources during initialization"). Here are test
+results on the three consecutive commits:
+
+(bad again!) a1224f34d72a ACPI: PM: Check states of power resources during initialization
+(good) bc2836859643 ACPI: PM: Do not turn off power resources in unknown state
+(bad) 519d81956ee2 Linux 5.15-rc6
+
+On commit bc2836859643 ("ACPI: PM: Do not turn off power resources in
+unknown state") this was not an issue because the power resource state
+left UNKNOWN thus being ignored.
+
+See also commit 9b04d99788cf ("ACPI: PM: Do not turn of unused power
+resources on the Toshiba Click Mini") which is another almost identical
+case to this one.
+
+Fixes: a1224f34d72a ("ACPI: PM: Check states of power resources during initialization")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221087
+Signed-off-by: Zhai Can <bczhc0@126.com>
+Link: https://patch.msgid.link/20260214161452.2849346-1-bczhc0@126.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/power.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
+index 361a7721a6a87..7da5ae5594a72 100644
+--- a/drivers/acpi/power.c
++++ b/drivers/acpi/power.c
+@@ -1113,6 +1113,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
+ },
+ },
++ {
++ /*
++ * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power
++ * resource 'PXP' will be shut down on initialization, making
++ * the NVMe #2 and the NVIDIA dGPU both unavailable (they're
++ * both controlled by 'PXP').
++ */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"),
++ }
++
++ },
+ {}
+ };
+
+--
+2.51.0
+
--- /dev/null
+From dde4a2b45799fb219342200012ee174df93e65f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jan 2026 11:47:02 -0800
+Subject: apparmor: account for in_atomic removal in common_file_perm
+
+From: Ryan Lee <ryan.lee@canonical.com>
+
+[ Upstream commit 9b829c0aa96e9385b1e9a308d3eb054b95fbeda2 ]
+
+If we are not in an atomic context in common_file_perm, then we don't have
+to use the atomic versions, resulting in improved performance outside of
+atomic contexts.
+
+Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index e59e9bc7250bf..f47d60d8c40a2 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -524,15 +524,14 @@ static int common_file_perm(const char *op, struct file *file, u32 mask)
+ {
+ struct aa_label *label;
+ int error = 0;
+- bool needput;
+
+ /* don't reaudit files closed during inheritance */
+ if (unlikely(file->f_path.dentry == aa_null.dentry))
+ return -EACCES;
+
+- label = __begin_current_label_crit_section(&needput);
++ label = begin_current_label_crit_section();
+ error = aa_file_perm(op, current_cred(), label, file, mask, false);
+- __end_current_label_crit_section(label, needput);
++ end_current_label_crit_section(label);
+
+ return error;
+ }
+--
+2.51.0
+
--- /dev/null
+From 1c58ed4ed387c6826da6ec38ff4b6234d568024f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Nov 2025 16:11:07 +0100
+Subject: AppArmor: Allow apparmor to handle unaligned dfa tables
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Helge Deller <deller@kernel.org>
+
+[ Upstream commit 64802f731214a51dfe3c6c27636b3ddafd003eb0 ]
+
+The dfa tables can originate from kernel or userspace and 8-byte alignment
+isn't always guaranteed and as such may trigger unaligned memory accesses
+on various architectures. Resulting in the following
+
+[Â Â 73.901376] WARNING: CPU: 0 PID: 341 at security/apparmor/match.c:316 aa_dfa_unpack+0x6cc/0x720
+[Â Â 74.015867] Modules linked in: binfmt_misc evdev flash sg drm drm_panel_orientation_quirks backlight i2c_core configfs nfnetlink autofs4 ext4 crc16 mbcache jbd2 hid_generic usbhid sr_mod hid cdrom
+sd_mod ata_generic ohci_pci ehci_pci ehci_hcd ohci_hcd pata_ali libata sym53c8xx scsi_transport_spi tg3 scsi_mod usbcore libphy scsi_common mdio_bus usb_common
+[Â Â 74.428977] CPU: 0 UID: 0 PID: 341 Comm: apparmor_parser Not tainted 6.18.0-rc6+ #9 NONE
+[Â Â 74.536543] Call Trace:
+[Â Â 74.568561] [<0000000000434c24>] dump_stack+0x8/0x18
+[Â Â 74.633757] [<0000000000476438>] __warn+0xd8/0x100
+[Â Â 74.696664] [<00000000004296d4>] warn_slowpath_fmt+0x34/0x74
+[Â Â 74.771006] [<00000000008db28c>] aa_dfa_unpack+0x6cc/0x720
+[Â Â 74.843062] [<00000000008e643c>] unpack_pdb+0xbc/0x7e0
+[Â Â 74.910545] [<00000000008e7740>] unpack_profile+0xbe0/0x1300
+[Â Â 74.984888] [<00000000008e82e0>] aa_unpack+0xe0/0x6a0
+[Â Â 75.051226] [<00000000008e3ec4>] aa_replace_profiles+0x64/0x1160
+[Â Â 75.130144] [<00000000008d4d90>] policy_update+0xf0/0x280
+[Â Â 75.201057] [<00000000008d4fc8>] profile_replace+0xa8/0x100
+[Â Â 75.274258] [<0000000000766bd0>] vfs_write+0x90/0x420
+[Â Â 75.340594] [<00000000007670cc>] ksys_write+0x4c/0xe0
+[Â Â 75.406932] [<0000000000767174>] sys_write+0x14/0x40
+[Â Â 75.472126] [<0000000000406174>] linux_sparc_syscall+0x34/0x44
+[Â Â 75.548802] ---[ end trace 0000000000000000 ]---
+[Â Â 75.609503] dfa blob stream 0xfff0000008926b96 not aligned.
+[Â Â 75.682695] Kernel unaligned access at TPC[8db2a8] aa_dfa_unpack+0x6e8/0x720
+
+Work around it by using the get_unaligned_xx() helpers.
+
+Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack")
+Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+Closes: https://github.com/sparclinux/issues/issues/30
+Signed-off-by: Helge Deller <deller@gmx.de>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/match.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/security/apparmor/match.c b/security/apparmor/match.c
+index c5a91600842a1..26e82ba879d44 100644
+--- a/security/apparmor/match.c
++++ b/security/apparmor/match.c
+@@ -15,6 +15,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/err.h>
+ #include <linux/kref.h>
++#include <linux/unaligned.h>
+
+ #include "include/lib.h"
+ #include "include/match.h"
+@@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
+ /* loaded td_id's start at 1, subtract 1 now to avoid doing
+ * it every time we use td_id as an index
+ */
+- th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
++ th.td_id = get_unaligned_be16(blob) - 1;
+ if (th.td_id > YYTD_ID_MAX)
+ goto out;
+- th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
+- th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
++ th.td_flags = get_unaligned_be16(blob + 2);
++ th.td_lolen = get_unaligned_be32(blob + 8);
+ blob += sizeof(struct table_header);
+
+ if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
+@@ -313,14 +314,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
+ if (size < sizeof(struct table_set_header))
+ goto fail;
+
+- if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
++ if (get_unaligned_be32(data) != YYTH_MAGIC)
+ goto fail;
+
+- hsize = ntohl(*(__be32 *) (data + 4));
++ hsize = get_unaligned_be32(data + 4);
+ if (size < hsize)
+ goto fail;
+
+- dfa->flags = ntohs(*(__be16 *) (data + 12));
++ dfa->flags = get_unaligned_be16(data + 12);
+ if (dfa->flags & ~(YYTH_FLAGS))
+ goto fail;
+
+@@ -329,7 +330,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
+ * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
+ * if (hsize < 16 + 4)
+ * goto fail;
+- * dfa->max_oob = ntol(*(__be32 *) (data + 16));
++ * dfa->max_oob = get_unaligned_be32(data + 16);
+ * if (dfa->max <= MAX_OOB_SUPPORTED) {
+ * pr_err("AppArmor DFA OOB greater than supported\n");
+ * goto fail;
+--
+2.51.0
+
--- /dev/null
+From 2a404714d96d85754bad4573a562486719f48958 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Jan 2026 19:03:07 -0500
+Subject: apparmor: avoid per-cpu hold underflow in aa_get_buffer
+
+From: Zhengmian Hu <huzhengmian@gmail.com>
+
+[ Upstream commit 640cf2f09575c9dc344b3f7be2498d31e3923ead ]
+
+When aa_get_buffer() pulls from the per-cpu list it unconditionally
+decrements cache->hold. If hold reaches 0 while count is still non-zero,
+the unsigned decrement wraps to UINT_MAX. This keeps hold non-zero for a
+very long time, so aa_put_buffer() never returns buffers to the global
+list, which can starve other CPUs and force repeated kmalloc(aa_g_path_max)
+allocations.
+
+Guard the decrement so hold never underflows.
+Fixes: ea9bae12d028 ("apparmor: cache buffers on percpu list if there is lock contention")
+
+Signed-off-by: Zhengmian Hu <huzhengmian@gmail.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index 8d5d9a966b719..9175fd677ef3d 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -2137,7 +2137,8 @@ char *aa_get_buffer(bool in_atomic)
+ if (!list_empty(&cache->head)) {
+ aa_buf = list_first_entry(&cache->head, union aa_buffer, list);
+ list_del(&aa_buf->list);
+- cache->hold--;
++ if (cache->hold)
++ cache->hold--;
+ cache->count--;
+ put_cpu_ptr(&aa_local_buffers);
+ return &aa_buf->buffer[0];
+--
+2.51.0
+
--- /dev/null
+From ef3d963f20fb8acb77ca84b275eec4d4e69b1b6e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jan 2026 23:40:03 -0800
+Subject: apparmor: drop in_atomic flag in common_mmap, and common_file_perm
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit c3f27ccdb2dce3f0f2814574d06017f46c11fa29 ]
+
+with the previous changes to mmap the in_atomic flag is now always
+false, so drop it.
+
+Suggested-by: Tyler Hicks <code@tyhicks.com>
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 21 +++++++++------------
+ 1 file changed, 9 insertions(+), 12 deletions(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index acca3d6efdbc8..e59e9bc7250bf 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -520,8 +520,7 @@ static void apparmor_file_free_security(struct file *file)
+ aa_put_label(rcu_access_pointer(ctx->label));
+ }
+
+-static int common_file_perm(const char *op, struct file *file, u32 mask,
+- bool in_atomic)
++static int common_file_perm(const char *op, struct file *file, u32 mask)
+ {
+ struct aa_label *label;
+ int error = 0;
+@@ -532,7 +531,7 @@ static int common_file_perm(const char *op, struct file *file, u32 mask,
+ return -EACCES;
+
+ label = __begin_current_label_crit_section(&needput);
+- error = aa_file_perm(op, current_cred(), label, file, mask, in_atomic);
++ error = aa_file_perm(op, current_cred(), label, file, mask, false);
+ __end_current_label_crit_section(label, needput);
+
+ return error;
+@@ -540,13 +539,12 @@ static int common_file_perm(const char *op, struct file *file, u32 mask,
+
+ static int apparmor_file_receive(struct file *file)
+ {
+- return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file),
+- false);
++ return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file));
+ }
+
+ static int apparmor_file_permission(struct file *file, int mask)
+ {
+- return common_file_perm(OP_FPERM, file, mask, false);
++ return common_file_perm(OP_FPERM, file, mask);
+ }
+
+ static int apparmor_file_lock(struct file *file, unsigned int cmd)
+@@ -556,11 +554,11 @@ static int apparmor_file_lock(struct file *file, unsigned int cmd)
+ if (cmd == F_WRLCK)
+ mask |= MAY_WRITE;
+
+- return common_file_perm(OP_FLOCK, file, mask, false);
++ return common_file_perm(OP_FLOCK, file, mask);
+ }
+
+ static int common_mmap(const char *op, struct file *file, unsigned long prot,
+- unsigned long flags, bool in_atomic)
++ unsigned long flags)
+ {
+ int mask = 0;
+
+@@ -578,21 +576,20 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot,
+ if (prot & PROT_EXEC)
+ mask |= AA_EXEC_MMAP;
+
+- return common_file_perm(op, file, mask, in_atomic);
++ return common_file_perm(op, file, mask);
+ }
+
+ static int apparmor_mmap_file(struct file *file, unsigned long reqprot,
+ unsigned long prot, unsigned long flags)
+ {
+- return common_mmap(OP_FMMAP, file, prot, flags, false);
++ return common_mmap(OP_FMMAP, file, prot, flags);
+ }
+
+ static int apparmor_file_mprotect(struct vm_area_struct *vma,
+ unsigned long reqprot, unsigned long prot)
+ {
+ return common_mmap(OP_FMPROT, vma->vm_file, prot,
+- !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0,
+- false);
++ !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
+ }
+
+ #ifdef CONFIG_IO_URING
+--
+2.51.0
+
--- /dev/null
+From c9e954da7a926569883b7d807b078863d6aaad38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 04:12:02 -0800
+Subject: apparmor: fix aa_label to return state from compount and component
+ match
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 9058798652c8bc0584ed1fb0766a1015046c06e8 ]
+
+aa-label_match is not correctly returning the state in all cases.
+The only reason this didn't cause a error is that all callers currently
+ignore the return value.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202602020631.wXgZosyU-lkp@intel.com/
+Fixes: a4c9efa4dbad6 ("apparmor: make label_match return a consistent value")
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 1d3fa5c28d97f..dd6c58f595ba8 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1334,7 +1334,7 @@ static int label_compound_match(struct aa_profile *profile,
+ * @request: permissions to request
+ * @perms: an initialized perms struct to add accumulation to
+ *
+- * Returns: 0 on success else ERROR
++ * Returns: the state the match finished in, may be the none matching state
+ *
+ * For the label A//&B//&C this does the perm match for each of A and B and C
+ * @perms should be preinitialized with allperms OR a previous permission
+@@ -1362,7 +1362,7 @@ static int label_components_match(struct aa_profile *profile,
+ }
+
+ /* no subcomponents visible - no change in perms */
+- return 0;
++ return state;
+
+ next:
+ tmp = *aa_lookup_perms(rules->policy, state);
+@@ -1378,13 +1378,13 @@ static int label_components_match(struct aa_profile *profile,
+ }
+
+ if ((perms->allow & request) != request)
+- return -EACCES;
++ return DFA_NOMATCH;
+
+- return 0;
++ return state;
+
+ fail:
+ *perms = nullperms;
+- return -EACCES;
++ return DFA_NOMATCH;
+ }
+
+ /**
+@@ -1406,7 +1406,7 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns,
+ request, perms);
+ if ((perms->allow & request) == request)
+- return 0;
++ return tmp;
+
+ /* failed compound_match try component matches */
+ *perms = allperms;
+--
+2.51.0
+
--- /dev/null
+From 6775582be816bb7a873e9b20dcf53cb830308caf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jan 2026 11:48:54 -0800
+Subject: apparmor: fix boolean argument in apparmor_mmap_file
+
+From: Ryan Lee <ryan.lee@canonical.com>
+
+[ Upstream commit 48d5268e911abcf7674ec33c9b0b3e952be1175e ]
+
+The previous value of GFP_ATOMIC is an int and not a bool, potentially
+resulting in UB when being assigned to a bool. In addition, the mmap hook
+is called outside of locks (i.e. in a non-atomic context), so we can pass
+a fixed constant value of false instead to common_mmap.
+
+Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index a87cd60ed2069..acca3d6efdbc8 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -584,7 +584,7 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot,
+ static int apparmor_mmap_file(struct file *file, unsigned long reqprot,
+ unsigned long prot, unsigned long flags)
+ {
+- return common_mmap(OP_FMMAP, file, prot, flags, GFP_ATOMIC);
++ return common_mmap(OP_FMMAP, file, prot, flags, false);
+ }
+
+ static int apparmor_file_mprotect(struct vm_area_struct *vma,
+--
+2.51.0
+
--- /dev/null
+From 4e9afbc90218e04ef8ad4c407b8dfb1dccd0b8cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 15:58:45 -0300
+Subject: apparmor: fix invalid deref of rawdata when export_binary is unset
+
+From: Georgia Garcia <georgia.garcia@canonical.com>
+
+[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ]
+
+If the export_binary parameter is disabled on runtime, profiles that
+were loaded before that will still have their rawdata stored in
+apparmorfs, with a symbolic link to the rawdata on the policy
+directory. When one of those profiles are replaced, the rawdata is set
+to NULL, but when trying to resolve the symbolic links to rawdata for
+that profile, it will try to dereference profile->rawdata->name when
+profile->rawdata is now NULL causing an oops. Fix it by checking if
+rawdata is set.
+
+[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088
+[ 168.657420] #PF: supervisor read access in kernel mode
+[ 168.660619] #PF: error_code(0x0000) - not-present page
+[ 168.663613] PGD 0 P4D 0
+[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI
+[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary)
+[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330
+[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8
+[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282
+[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158
+[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80
+[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000
+[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80
+[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0
+[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000
+[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0
+[ 168.701696] Call Trace:
+[ 168.702325] <TASK>
+[ 168.702995] rawdata_get_link_data+0x1c/0x30
+[ 168.704145] vfs_readlink+0xd4/0x160
+[ 168.705152] do_readlinkat+0x114/0x180
+[ 168.706214] __x64_sys_readlink+0x1e/0x30
+[ 168.708653] x64_sys_call+0x1d77/0x26b0
+[ 168.709525] do_syscall_64+0x81/0x500
+[ 168.710348] ? do_statx+0x72/0xb0
+[ 168.711109] ? putname+0x3e/0x80
+[ 168.711845] ? __x64_sys_statx+0xb7/0x100
+[ 168.712711] ? x64_sys_call+0x10fc/0x26b0
+[ 168.713577] ? do_syscall_64+0xbf/0x500
+[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0
+[ 168.715404] ? irqentry_exit+0xb2/0x740
+[ 168.716359] ? exc_page_fault+0x90/0x1b0
+[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement")
+Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/apparmorfs.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index 907bd2667e28c..9252172d50682 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -1644,6 +1644,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry,
+
+ label = aa_get_label_rcu(&proxy->label);
+ profile = labels_profile(label);
++
++ /* rawdata can be null when aa_g_export_binary is unset during
++ * runtime and a profile is replaced
++ */
++ if (!profile->rawdata) {
++ aa_put_label(label);
++ return ERR_PTR(-ENOENT);
++ }
++
+ depth = profile_depth(profile);
+ target = gen_symlink_name(depth, profile->rawdata->name, name);
+ aa_put_label(label);
+--
+2.51.0
+
--- /dev/null
+From 2de19b1fa24e27280c1518f90380ef5d8798e5a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Oct 2025 16:35:00 +0000
+Subject: apparmor: fix NULL pointer dereference in __unix_needs_revalidation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: System Administrator <root@localhost>
+
+[ Upstream commit e2938ad00b21340c0362562dfedd7cfec0554d67 ]
+
+When receiving file descriptors via SCM_RIGHTS, both the socket pointer
+and the socket's sk pointer can be NULL during socket setup or teardown,
+causing NULL pointer dereferences in __unix_needs_revalidation().
+
+This is a regression in AppArmor 5.0.0 (kernel 6.17+) where the new
+__unix_needs_revalidation() function was added without proper NULL checks.
+
+The crash manifests as:
+ BUG: kernel NULL pointer dereference, address: 0x0000000000000018
+ RIP: aa_file_perm+0xb7/0x3b0 (or +0xbe/0x3b0, +0xc0/0x3e0)
+ Call Trace:
+ apparmor_file_receive+0x42/0x80
+ security_file_receive+0x2e/0x50
+ receive_fd+0x1d/0xf0
+ scm_detach_fds+0xad/0x1c0
+
+The function dereferences sock->sk->sk_family without checking if either
+sock or sock->sk is NULL first.
+
+Add NULL checks for both sock and sock->sk before accessing sk_family.
+
+Fixes: 88fec3526e841 ("apparmor: make sure unix socket labeling is correctly updated.")
+Reported-by: Jamin Mc <jaminmc@gmail.com>
+Closes: https://bugzilla.proxmox.com/show_bug.cgi?id=7083
+Closes: https://gitlab.com/apparmor/apparmor/-/issues/568
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+Signed-off-by: System Administrator <root@localhost>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/file.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
+index c758204028780..919dbbbc87ab6 100644
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -578,6 +578,9 @@ static bool __unix_needs_revalidation(struct file *file, struct aa_label *label,
+ return false;
+ if (request & NET_PEER_MASK)
+ return false;
++ /* sock and sock->sk can be NULL for sockets being set up or torn down */
++ if (!sock || !sock->sk)
++ return false;
+ if (sock->sk->sk_family == PF_UNIX) {
+ struct aa_sk_ctx *ctx = aa_sock(sock->sk);
+
+--
+2.51.0
+
--- /dev/null
+From 1ff82b6dd23e85350eddd80a3012f0c06174007d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 15:07:42 -0800
+Subject: apparmor: fix NULL sock in aa_sock_file_perm
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ]
+
+Deal with the potential that sock and sock-sk can be NULL during
+socket setup or teardown. This could lead to an oops. The fix for NULL
+pointer dereference in __unix_needs_revalidation shows this is at
+least possible for af_unix sockets. While the fix for af_unix sockets
+applies for newer mediation this is still the fall back path for older
+af_unix mediation and other sockets, so ensure it is covered.
+
+Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/net.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index 45cf25605c345..44c04102062f3 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -326,8 +326,10 @@ int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label,
+ struct socket *sock = (struct socket *) file->private_data;
+
+ AA_BUG(!label);
+- AA_BUG(!sock);
+- AA_BUG(!sock->sk);
++
++ /* sock && sock->sk can be NULL for sockets being set up or torn down */
++ if (!sock || !sock->sk)
++ return 0;
+
+ if (sock->sk->sk_family == PF_UNIX)
+ return aa_unix_file_perm(subj_cred, label, op, request, file);
+--
+2.51.0
+
--- /dev/null
+From 12e6db0161cccdf915b75e6250423e1686295a63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 21:15:04 +0100
+Subject: apparmor: Fix & Optimize table creation from possibly unaligned
+ memory
+
+From: Helge Deller <deller@kernel.org>
+
+[ Upstream commit 6fc367bfd4c8886e6b1742aabbd1c0bdc310db3a ]
+
+Source blob may come from userspace and might be unaligned.
+Try to optize the copying process by avoiding unaligned memory accesses.
+
+- Added Fixes tag
+- Added "Fix &" to description as this doesn't just optimize but fixes
+ a potential unaligned memory access
+Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack")
+Signed-off-by: Helge Deller <deller@gmx.de>
+[jj: remove duplicate word "convert" in comment trigger checkpatch warning]
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/include/match.h | 12 +++++++-----
+ security/apparmor/match.c | 7 +++----
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
+index 1fbe82f5021b1..0dde8eda3d1a5 100644
+--- a/security/apparmor/include/match.h
++++ b/security/apparmor/include/match.h
+@@ -104,16 +104,18 @@ struct aa_dfa {
+ struct table_header *tables[YYTD_ID_TSIZE];
+ };
+
+-#define byte_to_byte(X) (X)
+-
+ #define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX) \
+ do { \
+ typeof(LEN) __i; \
+ TTYPE *__t = (TTYPE *) TABLE; \
+ BTYPE *__b = (BTYPE *) BLOB; \
+- for (__i = 0; __i < LEN; __i++) { \
+- __t[__i] = NTOHX(__b[__i]); \
+- } \
++ BUILD_BUG_ON(sizeof(TTYPE) != sizeof(BTYPE)); \
++ if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) \
++ memcpy(__t, __b, (LEN) * sizeof(BTYPE)); \
++ else /* copy & convert from big-endian */ \
++ for (__i = 0; __i < LEN; __i++) { \
++ __t[__i] = NTOHX(&__b[__i]); \
++ } \
+ } while (0)
+
+ static inline size_t table_size(size_t len, size_t el_size)
+diff --git a/security/apparmor/match.c b/security/apparmor/match.c
+index 26e82ba879d44..bbeb3be68572f 100644
+--- a/security/apparmor/match.c
++++ b/security/apparmor/match.c
+@@ -67,14 +67,13 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
+ table->td_flags = th.td_flags;
+ table->td_lolen = th.td_lolen;
+ if (th.td_flags == YYTD_DATA8)
+- UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+- u8, u8, byte_to_byte);
++ memcpy(table->td_data, blob, th.td_lolen);
+ else if (th.td_flags == YYTD_DATA16)
+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+- u16, __be16, be16_to_cpu);
++ u16, __be16, get_unaligned_be16);
+ else if (th.td_flags == YYTD_DATA32)
+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+- u32, __be32, be32_to_cpu);
++ u32, __be32, get_unaligned_be32);
+ else
+ goto fail;
+ /* if table was vmalloced make sure the page tables are synced
+--
+2.51.0
+
--- /dev/null
+From 89238679ab4113d134e3de283943bad8a1e26864 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:16:54 -0800
+Subject: apparmor: fix rlimit for posix cpu timers
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ]
+
+Posix cpu timers requires an additional step beyond setting the rlimit.
+Refactor the code so its clear when what code is setting the
+limit and conditionally update the posix cpu timers when appropriate.
+
+Fixes: baa73d9e478ff ("posix-timers: Make them configurable")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/resource.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index 8e80db3ae21c0..64212b39ba4bb 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -196,6 +196,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
+ rules->rlimits.limits[j].rlim_max);
+ /* soft limit should not exceed hard limit */
+ rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
++ if (j == RLIMIT_CPU &&
++ rlim->rlim_cur != RLIM_INFINITY &&
++ IS_ENABLED(CONFIG_POSIX_TIMERS))
++ (void) update_rlimit_cpu(current->group_leader,
++ rlim->rlim_cur);
+ }
+ }
+ }
+--
+2.51.0
+
--- /dev/null
+From d364a6442dfa54fc090702a086d068278b1ae39b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Nov 2025 23:59:38 -0800
+Subject: apparmor: make label_match return a consistent value
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit a4c9efa4dbad6dacad6e8b274e30e814c8353097 ]
+
+compound match is inconsistent in returning a state or an integer error
+this is problemati if the error is ever used as a state in the state
+machine
+
+Fixes: f1bd904175e81 ("apparmor: add the base fns() for domain labels")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 02ee128f53d13..1d3fa5c28d97f 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1278,7 +1278,7 @@ static inline aa_state_t match_component(struct aa_profile *profile,
+ * @request: permissions to request
+ * @perms: perms struct to set
+ *
+- * Returns: 0 on success else ERROR
++ * Returns: state match stopped at or DFA_NOMATCH if aborted early
+ *
+ * For the label A//&B//&C this does the perm match for A//&B//&C
+ * @perms should be preinitialized with allperms OR a previous permission
+@@ -1305,7 +1305,7 @@ static int label_compound_match(struct aa_profile *profile,
+
+ /* no component visible */
+ *perms = allperms;
+- return 0;
++ return state;
+
+ next:
+ label_for_each_cont(i, label, tp) {
+@@ -1317,14 +1317,11 @@ static int label_compound_match(struct aa_profile *profile,
+ goto fail;
+ }
+ *perms = *aa_lookup_perms(rules->policy, state);
+- if ((perms->allow & request) != request)
+- return -EACCES;
+-
+- return 0;
++ return state;
+
+ fail:
+ *perms = nullperms;
+- return state;
++ return DFA_NOMATCH;
+ }
+
+ /**
+@@ -1406,11 +1403,12 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+ struct aa_label *label, aa_state_t state, bool subns,
+ u32 request, struct aa_perms *perms)
+ {
+- int error = label_compound_match(profile, rules, label, state, subns,
+- request, perms);
+- if (!error)
+- return error;
++ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns,
++ request, perms);
++ if ((perms->allow & request) == request)
++ return 0;
+
++ /* failed compound_match try component matches */
+ *perms = allperms;
+ return label_components_match(profile, rules, label, state, subns,
+ request, perms);
+--
+2.51.0
+
--- /dev/null
+From 9f79861db9d12401d89345e5b1540ff1b31e2067 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Sep 2025 02:22:21 -0700
+Subject: apparmor: move check for aa_null file to cover all cases
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 4a134723f9f1ad2f3621566259db673350d19cb1 ]
+
+files with a dentry pointing aa_null.dentry where already rejected as
+part of file_inheritance. Unfortunately the check in
+common_file_perm() is insufficient to cover all cases causing
+unnecessary audit messages without the original files context.
+
+Eg.
+[ 442.886474] audit: type=1400 audit(1704822661.616:329): apparmor="DENIED" operation="file_inherit" class="file" namespace="root//lxd-juju-98527a-0_<var-snap-lxd-common-lxd>" profile="snap.lxd.activate" name="/apparmor/.null" pid=9525 comm="snap-exec"
+
+Further examples of this are in the logs of
+https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2120439
+https://bugs.launchpad.net/ubuntu/+source/snapd/+bug/1952084
+https://bugs.launchpad.net/snapd/+bug/2049099
+
+These messages have no value and should not be sent to the logs.
+AppArmor was already filtering the out in some cases but the original
+patch did not catch all cases. Fix this by push the existing check
+down into two functions that should cover all cases.
+
+Link: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2122743
+Fixes: 192ca6b55a86 ("apparmor: revalidate files during exec")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/file.c | 12 ++++++++++--
+ security/apparmor/lsm.c | 4 ----
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
+index 919dbbbc87ab6..7de23e85cd5d0 100644
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -154,8 +154,12 @@ static int path_name(const char *op, const struct cred *subj_cred,
+ const char *info = NULL;
+ int error;
+
+- error = aa_path_name(path, flags, buffer, name, &info,
+- labels_profile(label)->disconnected);
++ /* don't reaudit files closed during inheritance */
++ if (unlikely(path->dentry == aa_null.dentry))
++ error = -EACCES;
++ else
++ error = aa_path_name(path, flags, buffer, name, &info,
++ labels_profile(label)->disconnected);
+ if (error) {
+ fn_for_each_confined(label, profile,
+ aa_audit_file(subj_cred,
+@@ -616,6 +620,10 @@ int aa_file_perm(const char *op, const struct cred *subj_cred,
+ AA_BUG(!label);
+ AA_BUG(!file);
+
++ /* don't reaudit files closed during inheritance */
++ if (unlikely(file->f_path.dentry == aa_null.dentry))
++ return -EACCES;
++
+ fctx = file_ctx(file);
+
+ rcu_read_lock();
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index f47d60d8c40a2..8d5d9a966b719 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -525,10 +525,6 @@ static int common_file_perm(const char *op, struct file *file, u32 mask)
+ struct aa_label *label;
+ int error = 0;
+
+- /* don't reaudit files closed during inheritance */
+- if (unlikely(file->f_path.dentry == aa_null.dentry))
+- return -EACCES;
+-
+ label = begin_current_label_crit_section();
+ error = aa_file_perm(op, current_cred(), label, file, mask, false);
+ end_current_label_crit_section(label);
+--
+2.51.0
+
--- /dev/null
+From d674f136f873b74d4a6c844031d52a60e707cb38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Nov 2025 00:14:36 -0800
+Subject: apparmor: remove apply_modes_to_perms from label_match
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit b2e27be2948f2f8c38421cd554b5fc9383215648 ]
+
+The modes shouldn't be applied at the point of label match, it just
+results in them being applied multiple times. Instead they should be
+applied after which is already being done by all callers so it can
+just be dropped from label_match.
+
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 913678f199c35..02ee128f53d13 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1317,7 +1317,6 @@ static int label_compound_match(struct aa_profile *profile,
+ goto fail;
+ }
+ *perms = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, perms);
+ if ((perms->allow & request) != request)
+ return -EACCES;
+
+@@ -1370,7 +1369,6 @@ static int label_components_match(struct aa_profile *profile,
+
+ next:
+ tmp = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ label_for_each_cont(i, label, tp) {
+ if (!aa_ns_visible(profile->ns, tp->ns, subns))
+@@ -1379,7 +1377,6 @@ static int label_components_match(struct aa_profile *profile,
+ if (!state)
+ goto fail;
+ tmp = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 39482724bb541b96c146be11217ece83cfdeb23f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jan 2026 09:35:57 -0800
+Subject: apparmor: return -ENOMEM in unpack_perms_table upon alloc failure
+
+From: Ryan Lee <ryan.lee@canonical.com>
+
+[ Upstream commit 74b7105e53e80a4072bd3e1a50be7aa15e3f0a01 ]
+
+In policy_unpack.c:unpack_perms_table, the perms struct is allocated via
+kcalloc, with the position being reset if the allocation fails. However,
+the error path results in -EPROTO being retured instead of -ENOMEM. Fix
+this to return the correct error code.
+
+Reported-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
+Fixes: fd1b2b95a2117 ("apparmor: add the ability for policy to specify a permission table")
+Reviewed-by: Tyler Hicks <code@tyhicks.com>
+Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy_unpack.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index 7523971e37d9c..dd602bd5fca99 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -687,8 +687,10 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms)
+ if (!aa_unpack_array(e, NULL, &size))
+ goto fail_reset;
+ *perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL);
+- if (!*perms)
+- goto fail_reset;
++ if (!*perms) {
++ e->pos = pos;
++ return -ENOMEM;
++ }
+ for (i = 0; i < size; i++) {
+ if (!unpack_perm(e, version, &(*perms)[i]))
+ goto fail;
+--
+2.51.0
+
--- /dev/null
+From 7d5d36cc29660c6d0fb0e99ff395c943a10cc199 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 11:27:32 +0100
+Subject: ASoC: codecs: aw88261: Fix erroneous bitmask logic in Awinic init
+
+From: Alexandre Ferrieux <alexandre.ferrieux@orange.com>
+
+[ Upstream commit b82fa9b0c26eeb2fde6017f7de2c3c544484efef ]
+
+The aw88261_dev_reg_update() function sets the Awinic registers in a
+rather nonuniform way:
+ - most registers get directly overwritten from the firmware blob
+ - but a handful of them need more delicate logic to preserve
+ some bits from their current value, according to a register-
+ specific mask
+For the latter, the logic is basically
+ NEW = (OLD & MASK) | (VAL & ~MASK)
+However, the ~MASK value is hand-computed, and in the specific case
+of the SYSCTRL register, in a buggy way.
+This patch restores the proper ~MASK value.
+
+Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver")
+Signed-off-by: Alexandre Ferrieux <alexandre.ferrieux@orange.com>
+Link: https://patch.msgid.link/20260211-aw88261-fwname-v1-1-e24e833a019d@fairphone.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/aw88261.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c
+index 8f37bfb974ae4..96b1a85c26aa7 100644
+--- a/sound/soc/codecs/aw88261.c
++++ b/sound/soc/codecs/aw88261.c
+@@ -423,9 +423,10 @@ static int aw88261_dev_reg_update(struct aw88261 *aw88261,
+ if (ret)
+ break;
+
++ /* keep all three bits from current hw status */
+ read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) |
+ (~AW88261_HMUTE_MASK);
+- reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK);
++ reg_val &= (AW88261_AMPPD_MASK & AW88261_PWDN_MASK & AW88261_HMUTE_MASK);
+ reg_val |= read_val;
+
+ /* enable uls hmute */
+--
+2.51.0
+
--- /dev/null
+From 5d8e70762badd7b97f2c9e361bfde92ab2ad377b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 18:57:14 +0000
+Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ]
+
+This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()").
+
+The original patch attempted to acquire the card->controls_rwsem lock in
+fsl_xcvr_mode_put(). However, this function is called from the upper ALSA
+core function snd_ctl_elem_write(), which already holds the write lock on
+controls_rwsem for the whole put operation. So there is no need to simply
+hold the lock for fsl_xcvr_activate_ctl() again.
+
+Acquiring the read lock while holding the write lock in the same thread
+results in a deadlock and a hung task, as reported by Alexander Stein.
+
+Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()")
+Reported-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_xcvr.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
+index 5de93f458b569..a268fb81a2f86 100644
+--- a/sound/soc/fsl/fsl_xcvr.c
++++ b/sound/soc/fsl/fsl_xcvr.c
+@@ -223,13 +223,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,
+
+ xcvr->mode = snd_soc_enum_item_to_val(e, item[0]);
+
+- down_read(&card->snd_card->controls_rwsem);
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_ARC));
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_EARC));
+- up_read(&card->snd_card->controls_rwsem);
+-
+ /* Allow playback for SPDIF only */
+ rtd = snd_soc_get_pcm_runtime(card, card->dai_link);
+ rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
+--
+2.51.0
+
--- /dev/null
+From db9444eb345e65aeafbf0da9bf27bb65fc19bd95 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 15:18:34 -0500
+Subject: ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk
+
+From: Detlev Casanova <detlev.casanova@collabora.com>
+
+[ Upstream commit 0783052534f547f8f201dd4554b1df9f1f8615b5 ]
+
+Drivers will not always call set_sysclk() for all clocks, especially when
+default mclk-fs can be used.
+When that is the case, use the clock rate set in the params multiplied by the
+default mclk-fs.
+
+Fixes: 5323186e2e8d ("ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback")
+Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
+Reported-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Link: https://patch.msgid.link/20260218201834.924358-1-detlev.casanova@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/rockchip/rockchip_i2s_tdm.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
+index 770b9bfbb384a..fc52149ed6ae3 100644
+--- a/sound/soc/rockchip/rockchip_i2s_tdm.c
++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
+@@ -22,6 +22,7 @@
+
+ #define DRV_NAME "rockchip-i2s-tdm"
+
++#define DEFAULT_MCLK_FS 256
+ #define CH_GRP_MAX 4 /* The max channel 8 / 2 */
+ #define MULTIPLEX_CH_MAX 10
+
+@@ -665,6 +666,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
+ mclk_rate = i2s_tdm->mclk_rx_freq;
+ }
+
++ /*
++ * When the dai/component driver doesn't need to set mclk-fs for a specific
++ * clock, it can skip the call to set_sysclk() for that clock.
++ * In that case, simply use the clock rate from the params and multiply it by
++ * the default mclk-fs value.
++ */
++ if (!mclk_rate)
++ mclk_rate = DEFAULT_MCLK_FS * params_rate(params);
++
+ err = clk_set_rate(mclk, mclk_rate);
+ if (err)
+ return err;
+--
+2.51.0
+
--- /dev/null
+From a176234d17b1ef51030f9eb7af99615c86d94bdd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 10:57:55 +0530
+Subject: bnge: fix reserving resources from FW
+
+From: Vikas Gupta <vikas.gupta@broadcom.com>
+
+[ Upstream commit 604530085b2ef484843c723a105b6fd3218b4710 ]
+
+HWRM_FUNC_CFG is used to reserve resources, whereas HWRM_FUNC_QCFG is
+intended for querying resource information from the firmware.
+Since __bnge_hwrm_reserve_pf_rings() reserves resources for a specific
+PF, the command type should be HWRM_FUNC_CFG.
+
+Fixes: 627c67f038d2 ("bng_en: Add resource management support")
+Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
+Reviewed-by: Bhargava Chenna Marreddy <bhargava.marreddy@broadcom.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260218052755.4097468-1-vikas.gupta@broadcom.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
+index 198f49b40dbf0..2994f10446a63 100644
+--- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
++++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
+@@ -442,7 +442,7 @@ __bnge_hwrm_reserve_pf_rings(struct bnge_dev *bd, struct bnge_hw_rings *hwr)
+ struct hwrm_func_cfg_input *req;
+ u32 enables = 0;
+
+- if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_QCFG))
++ if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_CFG))
+ return NULL;
+
+ req->fid = cpu_to_le16(0xffff);
+--
+2.51.0
+
--- /dev/null
+From 52de9d3f828dceb4b44a1e72a797b762a4a468e5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 06:09:19 +0000
+Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ]
+
+The ALB RX path may access rx_hashtbl concurrently with bond
+teardown. During rapid bond up/down cycles, rlb_deinitialize()
+frees rx_hashtbl while RX handlers are still running, leading
+to a null pointer dereference detected by KASAN.
+
+However, the root cause is that rlb_arp_recv() can still be accessed
+after setting recv_probe to NULL, which is actually a use-after-free
+(UAF) issue. That is the reason for using the referenced commit in the
+Fixes tag.
+
+[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI
+[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef]
+[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary)
+[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022
+[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding]
+[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6
+ 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00
+[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206
+[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e
+[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8
+[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8
+[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119
+[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810
+[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000
+[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0
+[ 214.310347] Call Trace:
+[ 214.313070] <IRQ>
+[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding]
+[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding]
+[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding]
+[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710
+[ 214.339199] ? __pfx_arp_process+0x10/0x10
+[ 214.343775] ? sched_balance_find_src_group+0x98/0x630
+[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10
+[ 214.356513] ? arp_rcv+0x307/0x690
+[ 214.360311] ? __pfx_arp_rcv+0x10/0x10
+[ 214.364499] ? __lock_acquire+0x58c/0xbd0
+[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0
+[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10
+[ 214.380743] ? lock_acquire+0x10b/0x140
+[ 214.385026] process_backlog+0x3f1/0x13a0
+[ 214.389502] ? process_backlog+0x3aa/0x13a0
+[ 214.394174] __napi_poll.constprop.0+0x9f/0x370
+[ 214.399233] net_rx_action+0x8c1/0xe60
+[ 214.403423] ? __pfx_net_rx_action+0x10/0x10
+[ 214.408193] ? lock_acquire.part.0+0xbd/0x260
+[ 214.413058] ? sched_clock_cpu+0x6c/0x540
+[ 214.417540] ? mark_held_locks+0x40/0x70
+[ 214.421920] handle_softirqs+0x1fd/0x860
+[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10
+[ 214.431264] ? __neigh_event_send+0x2d6/0xf50
+[ 214.436131] do_softirq+0xb1/0xf0
+[ 214.439830] </IRQ>
+
+The issue is reproducible by repeatedly running
+ip link set bond0 up/down while receiving ARP messages, where
+rlb_arp_recv() can race with rlb_deinitialize() and dereference
+a freed rx_hashtbl entry.
+
+Fix this by setting recv_probe to NULL and then calling
+synchronize_net() to wait for any concurrent RX processing to finish.
+This ensures that no RX handler can access rx_hashtbl after it is freed
+in bond_alb_deinitialize().
+
+Reported-by: Liang Li <liali@redhat.com>
+Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 47f13d86cb7ef..4c58d1dafcacb 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4314,9 +4314,13 @@ static int bond_close(struct net_device *bond_dev)
+
+ bond_work_cancel_all(bond);
+ bond->send_peer_notif = 0;
++ WRITE_ONCE(bond->recv_probe, NULL);
++
++ /* Wait for any in-flight RX handlers */
++ synchronize_net();
++
+ if (bond_is_lb(bond))
+ bond_alb_deinitialize(bond);
+- bond->recv_probe = NULL;
+
+ if (BOND_MODE(bond) == BOND_MODE_8023AD &&
+ bond->params.broadcast_neighbor)
+--
+2.51.0
+
--- /dev/null
+From a2ab6fb298c00d45b603cec8621670515963fafe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 21:29:49 +0000
+Subject: bpf: Add a map/btf from a fd array more consistently
+
+From: Anton Protopopov <a.s.protopopov@gmail.com>
+
+[ Upstream commit b0b1a8583d8e797114e613139e3e3318a1704690 ]
+
+The add_fd_from_fd_array() function takes a file descriptor as a
+parameter and tries to add either map or btf to the corresponding
+list of used objects. As was reported by Dan Carpenter, since the
+commit c81e4322acf0 ("bpf: Fix a potential use-after-free of BTF
+object"), the fdget() is called twice on the file descriptor, and
+thus userspace, potentially, can replace the file pointed to by the
+file descriptor in between the two calls. On practice, this shouldn't
+break anything on the kernel side, but for consistency fix the code
+such that only one fdget() is executed.
+
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/r/aY689z7gHNv8rgVO@stanley.mountain/
+Fixes: ccd2d799ed44 ("bpf: Fix a potential use-after-free of BTF object")
+Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
+Link: https://lore.kernel.org/r/20260213212949.759321-1-a.s.protopopov@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index a16aca34f5834..fe01edfcc34c6 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -24658,9 +24658,11 @@ static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd)
+ return 0;
+ }
+
+- btf = btf_get_by_fd(fd);
+- if (!IS_ERR(btf))
++ btf = __btf_get_by_fd(f);
++ if (!IS_ERR(btf)) {
++ btf_get(btf);
+ return __add_used_btf(env, btf);
++ }
+
+ verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd);
+ return PTR_ERR(map);
+--
+2.51.0
+
--- /dev/null
+From a96fc583215bd3c53c03b9b7fc92cf3437a6522d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 13:29:04 +0000
+Subject: bpf: Fix a potential use-after-free of BTF object
+
+From: Anton Protopopov <a.s.protopopov@gmail.com>
+
+[ Upstream commit ccd2d799ed4467c07f5ee18c2f5c59bcc990822c ]
+
+Refcounting in the check_pseudo_btf_id() function is incorrect:
+the __check_pseudo_btf_id() function might get called with a zero
+refcounted btf. Fix this, and patch related code accordingly.
+
+v3: rephrase a comment (AI)
+v2: fix a refcount leak introduced in v1 (AI)
+
+Reported-by: syzbot+5a0f1995634f7c1dadbf@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=5a0f1995634f7c1dadbf
+Fixes: 76145f725532 ("bpf: Refactor check_pseudo_btf_id")
+Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
+Link: https://lore.kernel.org/r/20260209132904.63908-1-a.s.protopopov@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 52 +++++++++++++++++++++----------------------
+ 1 file changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index c9e2e22da3309..a16aca34f5834 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -20685,29 +20685,29 @@ static int find_btf_percpu_datasec(struct btf *btf)
+ }
+
+ /*
+- * Add btf to the used_btfs array and return the index. (If the btf was
+- * already added, then just return the index.) Upon successful insertion
+- * increase btf refcnt, and, if present, also refcount the corresponding
+- * kernel module.
++ * Add btf to the env->used_btfs array. If needed, refcount the
++ * corresponding kernel module. To simplify caller's logic
++ * in case of error or if btf was added before the function
++ * decreases the btf refcount.
+ */
+ static int __add_used_btf(struct bpf_verifier_env *env, struct btf *btf)
+ {
+ struct btf_mod_pair *btf_mod;
++ int ret = 0;
+ int i;
+
+ /* check whether we recorded this BTF (and maybe module) already */
+ for (i = 0; i < env->used_btf_cnt; i++)
+ if (env->used_btfs[i].btf == btf)
+- return i;
++ goto ret_put;
+
+ if (env->used_btf_cnt >= MAX_USED_BTFS) {
+ verbose(env, "The total number of btfs per program has reached the limit of %u\n",
+ MAX_USED_BTFS);
+- return -E2BIG;
++ ret = -E2BIG;
++ goto ret_put;
+ }
+
+- btf_get(btf);
+-
+ btf_mod = &env->used_btfs[env->used_btf_cnt];
+ btf_mod->btf = btf;
+ btf_mod->module = NULL;
+@@ -20716,12 +20716,18 @@ static int __add_used_btf(struct bpf_verifier_env *env, struct btf *btf)
+ if (btf_is_module(btf)) {
+ btf_mod->module = btf_try_get_module(btf);
+ if (!btf_mod->module) {
+- btf_put(btf);
+- return -ENXIO;
++ ret = -ENXIO;
++ goto ret_put;
+ }
+ }
+
+- return env->used_btf_cnt++;
++ env->used_btf_cnt++;
++ return 0;
++
++ret_put:
++ /* Either error or this BTF was already added */
++ btf_put(btf);
++ return ret;
+ }
+
+ /* replace pseudo btf_id with kernel symbol address */
+@@ -20818,9 +20824,7 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env,
+
+ btf_fd = insn[1].imm;
+ if (btf_fd) {
+- CLASS(fd, f)(btf_fd);
+-
+- btf = __btf_get_by_fd(f);
++ btf = btf_get_by_fd(btf_fd);
+ if (IS_ERR(btf)) {
+ verbose(env, "invalid module BTF object FD specified.\n");
+ return -EINVAL;
+@@ -20830,17 +20834,17 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env,
+ verbose(env, "kernel is missing BTF, make sure CONFIG_DEBUG_INFO_BTF=y is specified in Kconfig.\n");
+ return -EINVAL;
+ }
++ btf_get(btf_vmlinux);
+ btf = btf_vmlinux;
+ }
+
+ err = __check_pseudo_btf_id(env, insn, aux, btf);
+- if (err)
++ if (err) {
++ btf_put(btf);
+ return err;
++ }
+
+- err = __add_used_btf(env, btf);
+- if (err < 0)
+- return err;
+- return 0;
++ return __add_used_btf(env, btf);
+ }
+
+ static bool is_tracing_prog_type(enum bpf_prog_type type)
+@@ -24654,13 +24658,9 @@ static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd)
+ return 0;
+ }
+
+- btf = __btf_get_by_fd(f);
+- if (!IS_ERR(btf)) {
+- err = __add_used_btf(env, btf);
+- if (err < 0)
+- return err;
+- return 0;
+- }
++ btf = btf_get_by_fd(fd);
++ if (!IS_ERR(btf))
++ return __add_used_btf(env, btf);
+
+ verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd);
+ return PTR_ERR(map);
+--
+2.51.0
+
--- /dev/null
+From 7f032f3ee152f3c01d0abb1e9885127d0e65c347 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 11:41:50 -0800
+Subject: bpftool: Fix truncated netlink dumps
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ]
+
+Netlink requires that the recv buffer used during dumps is at least
+min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will
+get truncated. Make sure bpftool follows this requirement, avoid
+missing information on systems with large pages.
+
+Acked-by: Quentin Monnet <qmo@kernel.org>
+Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/net.c | 5 ++++-
+ tools/lib/bpf/netlink.c | 4 +++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c
+index cfc6f944f7c33..1a06b0b5eef35 100644
+--- a/tools/bpf/bpftool/net.c
++++ b/tools/bpf/bpftool/net.c
+@@ -156,7 +156,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ bool multipart = true;
+ struct nlmsgerr *err;
+ struct nlmsghdr *nh;
+- char buf[4096];
++ char buf[8192];
+ int len, ret;
+
+ while (multipart) {
+@@ -201,6 +201,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ return ret;
+ }
+ }
++
++ if (len)
++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len);
+ }
+ ret = 0;
+ done:
+diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
+index c997e69d507fe..c9a78fb16f115 100644
+--- a/tools/lib/bpf/netlink.c
++++ b/tools/lib/bpf/netlink.c
+@@ -143,7 +143,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ struct nlmsghdr *nh;
+ int len, ret;
+
+- ret = alloc_iov(&iov, 4096);
++ ret = alloc_iov(&iov, 8192);
+ if (ret)
+ goto done;
+
+@@ -212,6 +212,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ }
+ }
+ }
++ if (len)
++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len);
+ }
+ ret = 0;
+ done:
+--
+2.51.0
+
--- /dev/null
+From 4d543b0b644040e3759c39855a0dbd0f8a7d3d90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 17:15:53 +0000
+Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not
+ found
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ]
+
+If btrfs_search_slot_for_read() returns 1, it means we did not find any
+key greater than or equals to the key we asked for, meaning we have
+reached the end of the tree and therefore the path is not valid. If
+this happens we need to break out of the loop and stop, instead of
+continuing and accessing an invalid path.
+
+Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/qgroup.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index c634e01140514..bed9d1c11c67a 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1137,11 +1137,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info,
+ }
+ if (ret > 0) {
+ /*
+- * Shouldn't happen, but in case it does we
+- * don't need to do the btrfs_next_item, just
+- * continue.
++ * Shouldn't happen because the key should still
++ * be there (return 0), but in case it does it
++ * means we have reached the end of the tree -
++ * there are no more leaves with items that have
++ * a key greater than or equals to @found_key,
++ * so just stop the search loop.
+ */
+- continue;
++ break;
+ }
+ }
+ ret = btrfs_next_item(tree_root, path);
+--
+2.51.0
+
--- /dev/null
+From 42840cbea92ae30263aea9e6c37b97d826405102 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jan 2026 01:13:38 +0000
+Subject: btrfs: reset block group size class when it becomes empty
+
+From: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+
+[ Upstream commit 5870ec7c8fe57a8b2c65005e5da5efc054faa3e6 ]
+
+Block group size classes are managed consistently everywhere.
+Currently, btrfs_use_block_group_size_class() sets a block group's size
+class to specialize it for a specific allocation size. However, this
+size class remains "stale" even if the block group becomes completely
+empty (both used and reserved bytes reach zero).
+
+This happens in two scenarios:
+
+1. When space reservations are freed (e.g., due to errors or transaction
+ aborts) via btrfs_free_reserved_bytes().
+2. When the last extent in a block group is freed via
+ btrfs_update_block_group().
+
+While size classes are advisory, a stale size class can cause
+find_free_extent to unnecessarily skip candidate block groups during
+initial search loops. This undermines the purpose of size classes to
+reduce fragmentation by keeping block groups restricted to a specific
+size class when they could be reused for any size.
+
+Fix this by resetting the size class to BTRFS_BG_SZ_NONE whenever a
+block group's used and reserved counts both reach zero. This ensures
+that empty block groups are fully available for any allocation size in
+the next cycle.
+
+Fixes: 52bb7a2166af ("btrfs: introduce size class to block group allocator")
+Reviewed-by: Boris Burkov <boris@bur.io>
+Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 08b14449fabeb..c7be37bcbc48d 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -3675,6 +3675,14 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans)
+ return ret;
+ }
+
++static void btrfs_maybe_reset_size_class(struct btrfs_block_group *bg)
++{
++ lockdep_assert_held(&bg->lock);
++ if (btrfs_block_group_should_use_size_class(bg) &&
++ bg->used == 0 && bg->reserved == 0)
++ bg->size_class = BTRFS_BG_SZ_NONE;
++}
++
+ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
+ u64 bytenr, u64 num_bytes, bool alloc)
+ {
+@@ -3739,6 +3747,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans,
+ old_val -= num_bytes;
+ cache->used = old_val;
+ cache->pinned += num_bytes;
++ btrfs_maybe_reset_size_class(cache);
+ btrfs_space_info_update_bytes_pinned(space_info, num_bytes);
+ space_info->bytes_used -= num_bytes;
+ space_info->disk_used -= num_bytes * factor;
+@@ -3867,6 +3876,7 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache, u64 num_bytes,
+ spin_lock(&cache->lock);
+ bg_ro = cache->ro;
+ cache->reserved -= num_bytes;
++ btrfs_maybe_reset_size_class(cache);
+ if (is_delalloc)
+ cache->delalloc_bytes -= num_bytes;
+ spin_unlock(&cache->lock);
+--
+2.51.0
+
--- /dev/null
+From fdde98c6aac6383c9d7f7555c71a6d45b4f47104 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 18:03:35 +0000
+Subject: btrfs: use the correct type to initialize block reserve for delayed
+ refs
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 2155d0c0a761a56ce7ede83a26eb23ea0f935260 ]
+
+When initializing the delayed refs block reserve for a transaction handle
+we are passing a type of BTRFS_BLOCK_RSV_DELOPS, which is meant for
+delayed items and not for delayed refs. The correct type for delayed refs
+is BTRFS_BLOCK_RSV_DELREFS.
+
+On release of any excess space reserved in a local delayed refs reserve,
+we also should transfer that excess space to the global block reserve
+(it it's full, we return to the space info for general availability).
+
+By initializing a transaction's local delayed refs block reserve with a
+type of BTRFS_BLOCK_RSV_DELOPS, we were also causing any excess space
+released from the delayed block reserve (fs_info->delayed_block_rsv, used
+for delayed inodes and items) to be transferred to the global block
+reserve instead of the global delayed refs block reserve. This was an
+unintentional change in commit 28270e25c69a ("btrfs: always reserve space
+for delayed refs when starting transaction"), but it's not particularly
+serious as things tend to cancel out each other most of the time and it's
+relatively rare to be anywhere near exhaustion of the global reserve.
+
+Fix this by initializing a transaction's local delayed refs reserve with
+a type of BTRFS_BLOCK_RSV_DELREFS and making btrfs_block_rsv_release()
+attempt to transfer unused space from such a reserve into the global block
+reserve, just as we did before that commit for when the block reserve is
+a delayed refs rsv.
+
+Reported-by: Alex Lyakas <alex.lyakas@zadara.com>
+Link: https://lore.kernel.org/linux-btrfs/CAOcd+r0FHG5LWzTSu=LknwSoqxfw+C00gFAW7fuX71+Z5AfEew@mail.gmail.com/
+Fixes: 28270e25c69a ("btrfs: always reserve space for delayed refs when starting transaction")
+Reviewed-by: Alex Lyakas <alex.lyakas@zadara.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-rsv.c | 7 ++++---
+ fs/btrfs/transaction.c | 2 +-
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c
+index 96cf7a1629870..52fb7d9425917 100644
+--- a/fs/btrfs/block-rsv.c
++++ b/fs/btrfs/block-rsv.c
+@@ -276,10 +276,11 @@ u64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
+ struct btrfs_block_rsv *target = NULL;
+
+ /*
+- * If we are a delayed block reserve then push to the global rsv,
+- * otherwise dump into the global delayed reserve if it is not full.
++ * If we are a delayed refs block reserve then push to the global
++ * reserve, otherwise dump into the global delayed refs reserve if it is
++ * not full.
+ */
+- if (block_rsv->type == BTRFS_BLOCK_RSV_DELOPS)
++ if (block_rsv->type == BTRFS_BLOCK_RSV_DELREFS)
+ target = global_rsv;
+ else if (block_rsv != global_rsv && !btrfs_block_rsv_full(delayed_rsv))
+ target = delayed_rsv;
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index e3e0d88d53476..d3e1ba257b9c0 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -726,7 +726,7 @@ start_transaction(struct btrfs_root *root, unsigned int num_items,
+
+ h->type = type;
+ INIT_LIST_HEAD(&h->new_bgs);
+- btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELOPS);
++ btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELREFS);
+
+ smp_mb();
+ if (cur_trans->state >= TRANS_STATE_COMMIT_START &&
+--
+2.51.0
+
--- /dev/null
+From 866150bfd5cb22356d2f1e86873fa424116a53d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 00:20:02 +0530
+Subject: cpuidle: Skip governor when only one idle state is available
+
+From: Aboorva Devarajan <aboorvad@linux.ibm.com>
+
+[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ]
+
+On certain platforms (PowerNV systems without a power-mgt DT node),
+cpuidle may register only a single idle state. In cases where that
+single state is a polling state (state 0), the ladder governor may
+incorrectly treat state 1 as the first usable state and pass an
+out-of-bounds index. This can lead to a NULL enter callback being
+invoked, ultimately resulting in a system crash.
+
+[ 13.342636] cpuidle-powernv : Only Snooze is available
+[ 13.351854] Faulting instruction address: 0x00000000
+[ 13.376489] NIP [0000000000000000] 0x0
+[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668
+
+Fix this by adding a bail-out in cpuidle_select() that returns state 0
+directly when state_count <= 1, bypassing the governor and keeping the
+tick running.
+
+Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol")
+Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
+Reviewed-by: Christian Loehle <christian.loehle@arm.com>
+Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/cpuidle.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
+index c7876e9e024f9..65fbb8e807b97 100644
+--- a/drivers/cpuidle/cpuidle.c
++++ b/drivers/cpuidle/cpuidle.c
+@@ -359,6 +359,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
+ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+ bool *stop_tick)
+ {
++ /*
++ * If there is only a single idle state (or none), there is nothing
++ * meaningful for the governor to choose. Skip the governor and
++ * always use state 0 with the tick running.
++ */
++ if (drv->state_count <= 1) {
++ *stop_tick = false;
++ return 0;
++ }
++
+ return cpuidle_curr_governor->select(drv, dev, stop_tick);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 969e0bd9725bd559bd11775bdb27a58c5f9b7d8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 20:40:07 +0100
+Subject: dpll: zl3073x: Fix ref frequency setting
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+[ Upstream commit a047497f952831e377564b606dcb74a7cb309384 ]
+
+The frequency for an input reference is computed as:
+
+ frequency = freq_base * freq_mult * freq_ratio_m / freq_ratio_n
+
+Before commit 5bc02b190a3fb ("dpll: zl3073x: Cache all reference
+properties in zl3073x_ref"), zl3073x_dpll_input_pin_frequency_set()
+explicitly wrote 1 to both the REF_RATIO_M and REF_RATIO_N hardware
+registers whenever a new frequency was set. This ensured the FEC ratio
+was always reset to 1:1 alongside the new base/multiplier values.
+
+The refactoring in that commit introduced zl3073x_ref_freq_set() to
+update the cached ref state, but this helper only sets freq_base and
+freq_mult without resetting freq_ratio_m and freq_ratio_n to 1. Because
+zl3073x_ref_state_set() uses a compare-and-write strategy, unchanged
+ratio fields are never written to the hardware. If the device previously
+had non-unity FEC ratio values, they remain in effect after a frequency
+change, resulting in an incorrect computed frequency.
+
+Explicitly set freq_ratio_m and freq_ratio_n to 1 in zl3073x_ref_freq_set()
+to restore the original behavior.
+
+Fixes: 5bc02b190a3fb ("dpll: zl3073x: Cache all reference properties in zl3073x_ref")
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260216194007.680416-1-ivecera@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dpll/zl3073x/ref.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/dpll/zl3073x/ref.h b/drivers/dpll/zl3073x/ref.h
+index efc7f59cd9f9c..0d8618f5ce8df 100644
+--- a/drivers/dpll/zl3073x/ref.h
++++ b/drivers/dpll/zl3073x/ref.h
+@@ -91,6 +91,8 @@ zl3073x_ref_freq_set(struct zl3073x_ref *ref, u32 freq)
+
+ ref->freq_base = base;
+ ref->freq_mult = mult;
++ ref->freq_ratio_m = 1;
++ ref->freq_ratio_n = 1;
+
+ return 0;
+ }
+--
+2.51.0
+
--- /dev/null
+From af947cdd935afb34b2ceaa65180f880fc3fdc35f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 12:25:03 +0100
+Subject: drm/amd/display: Don't call find_analog_engine() twice
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit 613b1737abe1bd0a65b49851e777231302095e28 ]
+
+The analog engine is already there in the link_analog_engine
+variable and assigned to enc_init_data.analog_engine already.
+
+I suspect this was a rebase mistake.
+
+Fixes: 436d0d22aa70 ("drm/amd/display: Pass proper DAC encoder ID to VBIOS")
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Tested-by: Mauro Rossi <issor.oruam@gmail.com>
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/link/link_factory.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+index d9cb6b6714009..9003e0d314e00 100644
+--- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c
++++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+@@ -648,7 +648,6 @@ static bool construct_phy(struct dc_link *link,
+ enc_init_data.channel = get_ddc_line(link);
+ enc_init_data.hpd_source = get_hpd_line(link);
+ enc_init_data.transmitter = transmitter_from_encoder;
+- enc_init_data.analog_engine = find_analog_engine(link, &enc_init_data.analog_encoder);
+ enc_init_data.encoder = link_encoder;
+ enc_init_data.analog_engine = link_analog_engine;
+
+--
+2.51.0
+
--- /dev/null
+From 4a67f7de4ea1675139a264c2daf6a3ad7d8ef763 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 12:25:07 +0100
+Subject: drm/amd/display: Enable DAC in DCE link encoder
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit 4bd8b5f8bcb57b430c35494d8a2471ce5fd7661d ]
+
+Ensure that the DAC output is enabled at the correct time by
+moving it to the DCE link encoder similarly to how digital
+outputs are enabled.
+
+This also removes the call to DAC1EncoderControl from the DCE
+HWSS, which always felt like it was a hacky solution.
+
+Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)")
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Tested-by: Mauro Rossi <issor.oruam@gmail.com>
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/dc/dce/dce_link_encoder.c | 18 +++++++++++++
+ .../drm/amd/display/dc/dce/dce_link_encoder.h | 5 ++++
+ .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 26 +++++++------------
+ .../drm/amd/display/dc/hwss/hw_sequencer.h | 2 ++
+ .../drm/amd/display/dc/inc/hw/link_encoder.h | 2 ++
+ .../gpu/drm/amd/display/dc/link/link_dpms.c | 14 +++++++++-
+ 6 files changed, 50 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+index 48a1b3b492e7f..bec8dab156eec 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+@@ -102,6 +102,7 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = {
+ .enable_dp_output = dce110_link_encoder_enable_dp_output,
+ .enable_dp_mst_output = dce110_link_encoder_enable_dp_mst_output,
+ .enable_lvds_output = dce110_link_encoder_enable_lvds_output,
++ .enable_analog_output = dce110_link_encoder_enable_analog_output,
+ .disable_output = dce110_link_encoder_disable_output,
+ .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings,
+ .dp_set_phy_pattern = dce110_link_encoder_dp_set_phy_pattern,
+@@ -1192,6 +1193,22 @@ void dce110_link_encoder_enable_lvds_output(
+ }
+ }
+
++void dce110_link_encoder_enable_analog_output(
++ struct link_encoder *enc,
++ uint32_t pixel_clock)
++{
++ struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
++ enum bp_result result;
++
++ result = link_dac_encoder_control(enc110, ENCODER_CONTROL_ENABLE, pixel_clock);
++
++ if (result != BP_RESULT_OK) {
++ DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n",
++ __func__);
++ BREAK_TO_DEBUGGER();
++ }
++}
++
+ /* enables DP PHY output */
+ void dce110_link_encoder_enable_dp_output(
+ struct link_encoder *enc,
+@@ -1776,6 +1793,7 @@ static const struct link_encoder_funcs dce60_lnk_enc_funcs = {
+ .enable_dp_output = dce60_link_encoder_enable_dp_output,
+ .enable_dp_mst_output = dce60_link_encoder_enable_dp_mst_output,
+ .enable_lvds_output = dce110_link_encoder_enable_lvds_output,
++ .enable_analog_output = dce110_link_encoder_enable_analog_output,
+ .disable_output = dce110_link_encoder_disable_output,
+ .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings,
+ .dp_set_phy_pattern = dce60_link_encoder_dp_set_phy_pattern,
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
+index c58b69bc319b7..6870cb619d208 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h
+@@ -273,6 +273,11 @@ void dce110_link_encoder_enable_lvds_output(
+ enum clock_source_id clock_source,
+ uint32_t pixel_clock);
+
++/* enables analog output from the DAC */
++void dce110_link_encoder_enable_analog_output(
++ struct link_encoder *enc,
++ uint32_t pixel_clock);
++
+ /* disable PHY output */
+ void dce110_link_encoder_disable_output(
+ struct link_encoder *enc,
+diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+index c472303276672..5896ce5511ab1 100644
+--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+@@ -659,20 +659,6 @@ void dce110_update_info_frame(struct pipe_ctx *pipe_ctx)
+ }
+ }
+
+-static void
+-dce110_dac_encoder_control(struct pipe_ctx *pipe_ctx, bool enable)
+-{
+- struct dc_link *link = pipe_ctx->stream->link;
+- struct dc_bios *bios = link->ctx->dc_bios;
+- struct bp_encoder_control encoder_control = {0};
+-
+- encoder_control.action = enable ? ENCODER_CONTROL_ENABLE : ENCODER_CONTROL_DISABLE;
+- encoder_control.engine_id = link->link_enc->analog_engine;
+- encoder_control.pixel_clock = pipe_ctx->stream->timing.pix_clk_100hz / 10;
+-
+- bios->funcs->encoder_control(bios, &encoder_control);
+-}
+-
+ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
+ {
+ enum dc_lane_count lane_count =
+@@ -703,8 +689,6 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx)
+
+ tg->funcs->set_early_control(tg, early_control);
+
+- if (dc_is_rgb_signal(pipe_ctx->stream->signal))
+- dce110_dac_encoder_control(pipe_ctx, true);
+ }
+
+ static enum bp_result link_transmitter_control(
+@@ -3285,6 +3269,15 @@ void dce110_enable_tmds_link_output(struct dc_link *link,
+ link->phy_state.symclk_state = SYMCLK_ON_TX_ON;
+ }
+
++static void dce110_enable_analog_link_output(
++ struct dc_link *link,
++ uint32_t pix_clk_100hz)
++{
++ link->link_enc->funcs->enable_analog_output(
++ link->link_enc,
++ pix_clk_100hz);
++}
++
+ void dce110_enable_dp_link_output(
+ struct dc_link *link,
+ const struct link_resource *link_res,
+@@ -3422,6 +3415,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
+ .enable_lvds_link_output = dce110_enable_lvds_link_output,
+ .enable_tmds_link_output = dce110_enable_tmds_link_output,
+ .enable_dp_link_output = dce110_enable_dp_link_output,
++ .enable_analog_link_output = dce110_enable_analog_link_output,
+ .disable_link_output = dce110_disable_link_output,
+ };
+
+diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+index 8ed9eea40c564..4f6bd365e055a 100644
+--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+@@ -1184,6 +1184,8 @@ struct hw_sequencer_funcs {
+ const struct link_resource *link_res,
+ enum clock_source_id clock_source,
+ uint32_t pixel_clock);
++ void (*enable_analog_link_output)(struct dc_link *link,
++ uint32_t pixel_clock);
+ void (*disable_link_output)(struct dc_link *link,
+ const struct link_resource *link_res,
+ enum signal_type signal);
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+index e638325e35ecf..b1a88618c5bf8 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h
+@@ -130,6 +130,8 @@ struct link_encoder_funcs {
+ void (*enable_lvds_output)(struct link_encoder *enc,
+ enum clock_source_id clock_source,
+ uint32_t pixel_clock);
++ void (*enable_analog_output)(struct link_encoder *enc,
++ uint32_t pixel_clock);
+ void (*disable_output)(struct link_encoder *link_enc,
+ enum signal_type signal);
+ void (*dp_set_lane_settings)(struct link_encoder *enc,
+diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
+index 6ae1341476171..635f614c06734 100644
+--- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
++++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c
+@@ -2208,6 +2208,18 @@ static enum dc_status enable_link_dp_mst(
+ return enable_link_dp(state, pipe_ctx);
+ }
+
++static enum dc_status enable_link_analog(
++ struct dc_state *state,
++ struct pipe_ctx *pipe_ctx)
++{
++ struct dc_link *link = pipe_ctx->stream->link;
++
++ link->dc->hwss.enable_analog_link_output(
++ link, pipe_ctx->stream->timing.pix_clk_100hz);
++
++ return DC_OK;
++}
++
+ static enum dc_status enable_link_virtual(struct pipe_ctx *pipe_ctx)
+ {
+ struct dc_link *link = pipe_ctx->stream->link;
+@@ -2263,7 +2275,7 @@ static enum dc_status enable_link(
+ status = DC_OK;
+ break;
+ case SIGNAL_TYPE_RGB:
+- status = DC_OK;
++ status = enable_link_analog(state, pipe_ctx);
+ break;
+ case SIGNAL_TYPE_VIRTUAL:
+ status = enable_link_virtual(pipe_ctx);
+--
+2.51.0
+
--- /dev/null
+From f5a0b3b38eb3e348ada9e691dc02454d66c082ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 20:06:19 +0530
+Subject: drm/amd/display: Fix dc_link NULL handling in HPD init
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit 226a40c06a183abaeb7529a4f54d6c203bd14407 ]
+
+amdgpu_dm_hpd_init() may see connectors without a valid dc_link.
+
+The code already checks dc_link for the polling decision, but later
+unconditionally dereferences it when setting up HPD interrupts.
+
+Assign dc_link early and skip connectors where it is NULL.
+
+Fixes the below:
+drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_irq.c:940 amdgpu_dm_hpd_init()
+error: we previously assumed 'dc_link' could be null (see line 931)
+
+drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_irq.c
+ 923 /*
+ 924 * Analog connectors may be hot-plugged unlike other connector
+ 925 * types that don't support HPD. Only poll analog connectors.
+ 926 */
+ 927 use_polling |=
+ 928 amdgpu_dm_connector->dc_link &&
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The patch adds this NULL check but hopefully it can be removed
+
+ 929 dc_connector_supports_analog(amdgpu_dm_connector->dc_link->link_id.id);
+ 930
+ 931 dc_link = amdgpu_dm_connector->dc_link;
+
+dc_link assigned here.
+
+ 932
+ 933 /*
+ 934 * Get a base driver irq reference for hpd ints for the lifetime
+ 935 * of dm. Note that only hpd interrupt types are registered with
+ 936 * base driver; hpd_rx types aren't. IOW, amdgpu_irq_get/put on
+ 937 * hpd_rx isn't available. DM currently controls hpd_rx
+ 938 * explicitly with dc_interrupt_set()
+ 939 */
+--> 940 if (dc_link->irq_source_hpd != DC_IRQ_SOURCE_INVALID) {
+ ^^^^^^^^^^^^^^^^^^^^^^^ If it's NULL then we are trouble because we dereference it here.
+
+ 941 irq_type = dc_link->irq_source_hpd - DC_IRQ_SOURCE_HPD1;
+ 942 /*
+ 943 * TODO: There's a mismatch between mode_info.num_hpd
+ 944 * and what bios reports as the # of connectors with hpd
+
+Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)")
+Cc: Timur Kristóf <timur.kristof@gmail.com>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Mario Limonciello <superm1@kernel.org>
+Cc: Alex Hung <alex.hung@amd.com>
+Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Cc: ChiaHsuan Chung <chiahsuan.chung@amd.com>
+Cc: Roman Li <roman.li@amd.com>
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+index e7b0928bd3db7..5948e2a6219e3 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+@@ -919,16 +919,15 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev)
+ continue;
+
+ amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
++ dc_link = amdgpu_dm_connector->dc_link;
++ if (!dc_link)
++ continue;
+
+ /*
+ * Analog connectors may be hot-plugged unlike other connector
+ * types that don't support HPD. Only poll analog connectors.
+ */
+- use_polling |=
+- amdgpu_dm_connector->dc_link &&
+- dc_connector_supports_analog(amdgpu_dm_connector->dc_link->link_id.id);
+-
+- dc_link = amdgpu_dm_connector->dc_link;
++ use_polling |= dc_connector_supports_analog(dc_link->link_id.id);
+
+ /*
+ * Get a base driver irq reference for hpd ints for the lifetime
+--
+2.51.0
+
--- /dev/null
+From fcfb9e6cce9b892a7bdfcdb84d465914f0e2806c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 20:49:23 +0530
+Subject: drm/amd/display: Fix out-of-bounds stream encoder index v3
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit abde491143e4e12eecc41337910aace4e8d59603 ]
+
+eng_id can be negative and that stream_enc_regs[]
+can be indexed out of bounds.
+
+eng_id is used directly as an index into stream_enc_regs[], which has
+only 5 entries. When eng_id is 5 (ENGINE_ID_DIGF) or negative, this can
+access memory past the end of the array.
+
+Add a bounds check using ARRAY_SIZE() before using eng_id as an index.
+The unsigned cast also rejects negative values.
+
+This avoids out-of-bounds access.
+
+Fixes the below smatch error:
+dcn*_resource.c: stream_encoder_create() may index
+stream_enc_regs[eng_id] out of bounds (size 5).
+
+drivers/gpu/drm/amd/amdgpu/../display/dc/resource/dcn351/dcn351_resource.c
+ 1246 static struct stream_encoder *dcn35_stream_encoder_create(
+ 1247 enum engine_id eng_id,
+ 1248 struct dc_context *ctx)
+ 1249 {
+
+ ...
+
+ 1255
+ 1256 /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+ 1257 if (eng_id <= ENGINE_ID_DIGF) {
+
+ENGINE_ID_DIGF is 5. should <= be <?
+
+Unrelated but, ugh, why is Smatch saying that "eng_id" can be negative?
+end_id is type signed long, but there are checks in the caller which prevent it from being negative.
+
+ 1258 vpg_inst = eng_id;
+ 1259 afmt_inst = eng_id;
+ 1260 } else
+ 1261 return NULL;
+ 1262
+
+ ...
+
+ 1281
+ 1282 dcn35_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
+ 1283 eng_id, vpg, afmt,
+--> 1284 &stream_enc_regs[eng_id],
+ ^^^^^^^^^^^^^^^^^^^^^^^ This stream_enc_regs[] array has 5 elements so we are one element beyond the end of the array.
+
+ ...
+
+ 1287 return &enc1->base;
+ 1288 }
+
+v2: use explicit bounds check as suggested by Roman/Dan; avoid unsigned int cast
+
+v3: The compiler already knows how to compare the two values, so the
+ cast (int) is not needed. (Roman)
+
+Fixes: 2728e9c7c842 ("drm/amd/display: add DC changes for DCN351")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Mario Limonciello <superm1@kernel.org>
+Cc: Alex Hung <alex.hung@amd.com>
+Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Cc: ChiaHsuan Chung <chiahsuan.chung@amd.com>
+Cc: Roman Li <roman.li@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Roman Li <roman.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/dc/resource/dcn315/dcn315_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn316/dcn316_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn32/dcn32_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn321/dcn321_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 8 ++++----
+ .../drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 8 ++++----
+ 6 files changed, 24 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+index 4e962f522f1be..228ae665c7893 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+@@ -1230,12 +1230,12 @@ static struct stream_encoder *dcn315_stream_encoder_create(
+ /*PHYB is wired off in HW, allow front end to remapping, otherwise needs more changes*/
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+index 5a95dd54cb429..45abf3b2eb2c4 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+@@ -1223,12 +1223,12 @@ static struct stream_encoder *dcn316_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+index b276fec3e479a..d39a0f9c78c92 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+@@ -1211,12 +1211,12 @@ static struct stream_encoder *dcn32_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn32_vpg_create(ctx, vpg_inst);
+ afmt = dcn32_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+index 3466ca34c93fe..c72c6dbc0cb4d 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+@@ -1192,12 +1192,12 @@ static struct stream_encoder *dcn321_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn321_vpg_create(ctx, vpg_inst);
+ afmt = dcn321_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+index d056e5fd54587..9edabd8ceca9b 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+@@ -1274,12 +1274,12 @@ static struct stream_encoder *dcn35_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+index 9fab3169069c4..43ece2bbcd64f 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+@@ -1254,12 +1254,12 @@ static struct stream_encoder *dcn35_stream_encoder_create(
+ int afmt_inst;
+
+ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
+- if (eng_id <= ENGINE_ID_DIGF) {
+- vpg_inst = eng_id;
+- afmt_inst = eng_id;
+- } else
++ if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs))
+ return NULL;
+
++ vpg_inst = eng_id;
++ afmt_inst = eng_id;
++
+ enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ vpg = dcn31_vpg_create(ctx, vpg_inst);
+ afmt = dcn31_afmt_create(ctx, afmt_inst);
+--
+2.51.0
+
--- /dev/null
+From 51c075fbf45e86de859b24e2c965538b41fd00ec Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 12:25:05 +0100
+Subject: drm/amd/display: Initialize DAC in DCE link encoder using VBIOS
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit e2a024345bce78a8e1ed7d9e84c859b05979e41e ]
+
+The VBIOS DAC1EncoderControl() function can initialize the DAC,
+by writing board-specific values to certain registers.
+Call this at link encoder hardware initialization time similarly
+to how the equivalent UNIPHYTransmitterControl initialization
+is done.
+
+This fixes DAC output on the Radeon HD 7790.
+
+Also remove the ENCODER_CONTROL_SETUP enum from the
+dac_encoder_control_prepare_params function which is actually
+not a supported operation for DAC encoders.
+
+Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)")
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Tested-by: Mauro Rossi <issor.oruam@gmail.com>
+Suggested-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/bios/command_table.c | 3 +--
+ drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 10 ++++++++++
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
+index 76a3559f0ddc1..b692fa37402d9 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c
+@@ -1874,8 +1874,7 @@ static void dac_encoder_control_prepare_params(
+ uint8_t dac_standard)
+ {
+ params->ucDacStandard = dac_standard;
+- if (action == ENCODER_CONTROL_SETUP ||
+- action == ENCODER_CONTROL_INIT)
++ if (action == ENCODER_CONTROL_INIT)
+ params->ucAction = ATOM_ENCODER_INIT;
+ else if (action == ENCODER_CONTROL_ENABLE)
+ params->ucAction = ATOM_ENABLE;
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+index 2e742950a62c7..48a1b3b492e7f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+@@ -1033,6 +1033,16 @@ void dce110_link_encoder_hw_init(
+ cntl.coherent = false;
+ cntl.hpd_sel = enc110->base.hpd_source;
+
++ if (enc110->base.analog_engine != ENGINE_ID_UNKNOWN) {
++ result = link_dac_encoder_control(enc110, ENCODER_CONTROL_INIT, 0);
++ if (result != BP_RESULT_OK) {
++ DC_LOG_ERROR("%s: Failed to execute VBIOS command table for DAC!\n",
++ __func__);
++ BREAK_TO_DEBUGGER();
++ return;
++ }
++ }
++
+ /* The code below is only applicable to encoders with a digital transmitter. */
+ if (enc110->base.transmitter == TRANSMITTER_UNKNOWN)
+ return;
+--
+2.51.0
+
--- /dev/null
+From 238db58c8b29ecd7721f16050f26ab1d64e2aaf3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jan 2026 22:08:25 +0100
+Subject: drm/amd/display: Only use analog link encoder with analog engine
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit f402898bd101af3166bde236b7f6a43d926e17a0 ]
+
+Some GPUs have analog connectors that work with a DP bridge chip
+and don't actually have an internal DAC: Those should not use
+the analog link encoder code path.
+
+Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)")
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c | 3 ++-
+ drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c | 3 ++-
+ drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c | 3 ++-
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+index d40d91ec2035f..a916872db7bd4 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+@@ -638,7 +638,8 @@ static struct link_encoder *dce100_link_encoder_create(
+ if (!enc110)
+ return NULL;
+
+- if (enc_init_data->connector.id == CONNECTOR_ID_VGA) {
++ if (enc_init_data->connector.id == CONNECTOR_ID_VGA &&
++ enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) {
+ dce110_link_encoder_construct(enc110,
+ enc_init_data,
+ &link_enc_feature,
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
+index 068fb1df8d889..90d826237cf00 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
+@@ -733,7 +733,8 @@ static struct link_encoder *dce60_link_encoder_create(
+ if (!enc110)
+ return NULL;
+
+- if (enc_init_data->connector.id == CONNECTOR_ID_VGA) {
++ if (enc_init_data->connector.id == CONNECTOR_ID_VGA &&
++ enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) {
+ dce60_link_encoder_construct(enc110,
+ enc_init_data,
+ &link_enc_feature,
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
+index 8687104cabb72..cde2c2cba1dd6 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
+@@ -740,7 +740,8 @@ static struct link_encoder *dce80_link_encoder_create(
+ if (!enc110)
+ return NULL;
+
+- if (enc_init_data->connector.id == CONNECTOR_ID_VGA) {
++ if (enc_init_data->connector.id == CONNECTOR_ID_VGA &&
++ enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) {
+ dce110_link_encoder_construct(enc110,
+ enc_init_data,
+ &link_enc_feature,
+--
+2.51.0
+
--- /dev/null
+From 585a9e80f40b4c39f72af546774287ae7a753529 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jan 2026 22:08:26 +0100
+Subject: drm/amd/display: Only use analog stream encoder with analog engine
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit 17ff034f805e032ed1358624a71381f9d6e29e9e ]
+
+Some GPUs have analog connectors that work with a DP bridge chip
+and don't actually have an internal DAC: Those should not use
+the analog stream encoders.
+
+Fixes: 5834c33fd3f6 ("drm/amd/display: Add concept of analog encoders (v2)")
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+index a916872db7bd4..83b9abb64bfcb 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+@@ -979,7 +979,10 @@ struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link(
+ struct dc_link *link = stream->link;
+ enum engine_id preferred_engine = link->link_enc->preferred_engine;
+
+- if (dc_is_rgb_signal(stream->signal))
++ /* Prefer analog engine if the link encoder has one.
++ * Otherwise, it's an external encoder.
++ */
++ if (dc_is_rgb_signal(stream->signal) && link->link_enc->analog_engine != ENGINE_ID_UNKNOWN)
+ preferred_engine = link->link_enc->analog_engine;
+
+ for (i = 0; i < pool->stream_enc_count; i++) {
+--
+2.51.0
+
--- /dev/null
+From 1f4b6cffa3be92f0814c5a49096654daf981e516 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 18 Jan 2026 15:57:41 +0100
+Subject: drm/amd/display: Reject cursor plane on DCE when scaled differently
+ than primary
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit 41af6215cdbcecd12920f211239479027904abf3 ]
+
+Currently DCE doesn't support the overlay cursor, so the
+dm_crtc_get_cursor_mode() function returns DM_CURSOR_NATIVE_MODE
+unconditionally. The outcome is that it doesn't check for the
+conditions that would necessitate the overlay cursor, meaning
+that it doesn't reject cases where the native cursor mode isn't
+supported on DCE.
+
+Remove the early return from dm_crtc_get_cursor_mode() for
+DCE and instead let it perform the necessary checks and
+return DM_CURSOR_OVERLAY_MODE. Add a later check that rejects
+when DM_CURSOR_OVERLAY_MODE would be used with DCE.
+
+Fixes: 1b04dcca4fb1 ("drm/amd/display: Introduce overlay cursor mode")
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4600
+Suggested-by: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Reviewed-by: Rodrigo Siqueira <siqueira@igalia.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index b31bd6fa70181..62622aa622066 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -12275,10 +12275,9 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev,
+
+ /* Overlay cursor not supported on HW before DCN
+ * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions
+- * as previous DCN generations, so enable native mode on DCN401 in addition to DCE
++ * as previous DCN generations, so enable native mode on DCN401
+ */
+- if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 ||
+- amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {
++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) {
+ *cursor_mode = DM_CURSOR_NATIVE_MODE;
+ return 0;
+ }
+@@ -12598,6 +12597,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+ * need to be added for DC to not disable a plane by mistake
+ */
+ if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE) {
++ if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) {
++ drm_dbg(dev, "Overlay cursor not supported on DCE\n");
++ ret = -EINVAL;
++ goto fail;
++ }
++
+ ret = drm_atomic_add_affected_planes(state, crtc);
+ if (ret)
+ goto fail;
+--
+2.51.0
+
--- /dev/null
+From 3c41d946a418f482679daa80023a9dbb45bb7f75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 12:25:06 +0100
+Subject: drm/amd/display: Set CRTC source for DAC using registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit cbced93894d145239c83881d7fd953b7392c23a8 ]
+
+Apparently the VBIOS SelectCRTC_Source function overwrites
+a few registers (such as FMT_*) which DC writes in a different
+place, which can cause problems.
+
+Instead of using the SelectCRTC_Source function from the
+VBIOS, use the DAC_SOURCE_SELECT register directly, similarly
+to how it is done for digital link encoders.
+
+Fixes: 3be26d81b150 ("drm/amd/display: Support DAC in dce110_hwseq")
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Tested-by: Mauro Rossi <issor.oruam@gmail.com>
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/dc/dce/dce_stream_encoder.c | 23 +++++++++++++---
+ .../amd/display/dc/dce/dce_stream_encoder.h | 12 +++++++--
+ .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 26 +------------------
+ .../dc/resource/dce100/dce100_resource.c | 6 +++--
+ .../dc/resource/dce60/dce60_resource.c | 7 +++--
+ .../dc/resource/dce80/dce80_resource.c | 6 +++--
+ 6 files changed, 43 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
+index 574618d5d4a4e..87c19f17c799f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c
+@@ -1498,7 +1498,10 @@ static void dig_connect_to_otg(
+ {
+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
+
+- REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst);
++ if (enc->id == ENGINE_ID_DACA || enc->id == ENGINE_ID_DACB)
++ REG_UPDATE(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, tg_inst);
++ else
++ REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst);
+ }
+
+ static unsigned int dig_source_otg(
+@@ -1507,7 +1510,10 @@ static unsigned int dig_source_otg(
+ uint32_t tg_inst = 0;
+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
+
+- REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst);
++ if (enc->id == ENGINE_ID_DACA || enc->id == ENGINE_ID_DACB)
++ REG_GET(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, &tg_inst);
++ else
++ REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst);
+
+ return tg_inst;
+ }
+@@ -1568,16 +1574,25 @@ void dce110_stream_encoder_construct(
+ enc110->se_mask = se_mask;
+ }
+
+-static const struct stream_encoder_funcs dce110_an_str_enc_funcs = {};
++static const struct stream_encoder_funcs dce110_an_str_enc_funcs = {
++ .dig_connect_to_otg = dig_connect_to_otg,
++ .dig_source_otg = dig_source_otg,
++};
+
+ void dce110_analog_stream_encoder_construct(
+ struct dce110_stream_encoder *enc110,
+ struct dc_context *ctx,
+ struct dc_bios *bp,
+- enum engine_id eng_id)
++ enum engine_id eng_id,
++ const struct dce110_stream_enc_registers *regs,
++ const struct dce_stream_encoder_shift *se_shift,
++ const struct dce_stream_encoder_mask *se_mask)
+ {
+ enc110->base.funcs = &dce110_an_str_enc_funcs;
+ enc110->base.ctx = ctx;
+ enc110->base.id = eng_id;
+ enc110->base.bp = bp;
++ enc110->regs = regs;
++ enc110->se_shift = se_shift;
++ enc110->se_mask = se_mask;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h
+index 068de1392121e..342c0afe6a949 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h
+@@ -65,6 +65,7 @@
+ SRI(AFMT_60958_1, DIG, id), \
+ SRI(AFMT_60958_2, DIG, id), \
+ SRI(DIG_FE_CNTL, DIG, id), \
++ SR(DAC_SOURCE_SELECT), \
+ SRI(HDMI_CONTROL, DIG, id), \
+ SRI(HDMI_GC, DIG, id), \
+ SRI(HDMI_GENERIC_PACKET_CONTROL0, DIG, id), \
+@@ -290,7 +291,8 @@
+ #define SE_COMMON_MASK_SH_LIST_DCE80_100(mask_sh)\
+ SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\
+ SE_SF(TMDS_CNTL, TMDS_PIXEL_ENCODING, mask_sh),\
+- SE_SF(TMDS_CNTL, TMDS_COLOR_FORMAT, mask_sh)
++ SE_SF(TMDS_CNTL, TMDS_COLOR_FORMAT, mask_sh),\
++ SE_SF(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, mask_sh)
+
+ #define SE_COMMON_MASK_SH_LIST_DCE110(mask_sh)\
+ SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\
+@@ -494,6 +496,7 @@ struct dce_stream_encoder_shift {
+ uint8_t DP_VID_N_MUL;
+ uint8_t DP_VID_M_DOUBLE_VALUE_EN;
+ uint8_t DIG_SOURCE_SELECT;
++ uint8_t DAC_SOURCE_SELECT;
+ };
+
+ struct dce_stream_encoder_mask {
+@@ -626,6 +629,7 @@ struct dce_stream_encoder_mask {
+ uint32_t DP_VID_N_MUL;
+ uint32_t DP_VID_M_DOUBLE_VALUE_EN;
+ uint32_t DIG_SOURCE_SELECT;
++ uint32_t DAC_SOURCE_SELECT;
+ };
+
+ struct dce110_stream_enc_registers {
+@@ -653,6 +657,7 @@ struct dce110_stream_enc_registers {
+ uint32_t AFMT_60958_1;
+ uint32_t AFMT_60958_2;
+ uint32_t DIG_FE_CNTL;
++ uint32_t DAC_SOURCE_SELECT;
+ uint32_t DP_MSE_RATE_CNTL;
+ uint32_t DP_MSE_RATE_UPDATE;
+ uint32_t DP_PIXEL_FORMAT;
+@@ -712,7 +717,10 @@ void dce110_analog_stream_encoder_construct(
+ struct dce110_stream_encoder *enc110,
+ struct dc_context *ctx,
+ struct dc_bios *bp,
+- enum engine_id eng_id);
++ enum engine_id eng_id,
++ const struct dce110_stream_enc_registers *regs,
++ const struct dce_stream_encoder_shift *se_shift,
++ const struct dce_stream_encoder_mask *se_mask);
+
+ void dce110_se_audio_mute_control(
+ struct stream_encoder *enc, bool mute);
+diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+index fd41e52e4d2f1..c472303276672 100644
+--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+@@ -1600,25 +1600,6 @@ static enum dc_status dce110_enable_stream_timing(
+ return DC_OK;
+ }
+
+-static void
+-dce110_select_crtc_source(struct pipe_ctx *pipe_ctx)
+-{
+- struct dc_link *link = pipe_ctx->stream->link;
+- struct dc_bios *bios = link->ctx->dc_bios;
+- struct bp_crtc_source_select crtc_source_select = {0};
+- enum engine_id engine_id = link->link_enc->preferred_engine;
+-
+- if (dc_is_rgb_signal(pipe_ctx->stream->signal))
+- engine_id = link->link_enc->analog_engine;
+-
+- crtc_source_select.controller_id = CONTROLLER_ID_D0 + pipe_ctx->stream_res.tg->inst;
+- crtc_source_select.color_depth = pipe_ctx->stream->timing.display_color_depth;
+- crtc_source_select.engine_id = engine_id;
+- crtc_source_select.sink_signal = pipe_ctx->stream->signal;
+-
+- bios->funcs->select_crtc_source(bios, &crtc_source_select);
+-}
+-
+ enum dc_status dce110_apply_single_controller_ctx_to_hw(
+ struct pipe_ctx *pipe_ctx,
+ struct dc_state *context,
+@@ -1638,10 +1619,6 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(
+ hws->funcs.disable_stream_gating(dc, pipe_ctx);
+ }
+
+- if (pipe_ctx->stream->signal == SIGNAL_TYPE_RGB) {
+- dce110_select_crtc_source(pipe_ctx);
+- }
+-
+ if (pipe_ctx->stream_res.audio != NULL) {
+ struct audio_output audio_output = {0};
+
+@@ -1721,8 +1698,7 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw(
+ pipe_ctx->stream_res.tg->funcs->set_static_screen_control(
+ pipe_ctx->stream_res.tg, event_triggers, 2);
+
+- if (!dc_is_virtual_signal(pipe_ctx->stream->signal) &&
+- !dc_is_rgb_signal(pipe_ctx->stream->signal))
++ if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
+ pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg(
+ pipe_ctx->stream_res.stream_enc,
+ pipe_ctx->stream_res.tg->inst);
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+index 83b9abb64bfcb..b78bb595d69ed 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c
+@@ -242,7 +242,8 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = {
+ stream_enc_regs(3),
+ stream_enc_regs(4),
+ stream_enc_regs(5),
+- stream_enc_regs(6)
++ stream_enc_regs(6),
++ {SR(DAC_SOURCE_SELECT),} /* DACA */
+ };
+
+ static const struct dce_stream_encoder_shift se_shift = {
+@@ -491,7 +492,8 @@ static struct stream_encoder *dce100_stream_encoder_create(
+ return NULL;
+
+ if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) {
+- dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id);
++ dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
++ &stream_enc_regs[eng_id], &se_shift, &se_mask);
+ return &enc110->base;
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
+index 90d826237cf00..6cf2faffc961b 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
+@@ -258,7 +258,9 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = {
+ stream_enc_regs(2),
+ stream_enc_regs(3),
+ stream_enc_regs(4),
+- stream_enc_regs(5)
++ stream_enc_regs(5),
++ {0},
++ {SR(DAC_SOURCE_SELECT),} /* DACA */
+ };
+
+ static const struct dce_stream_encoder_shift se_shift = {
+@@ -607,7 +609,8 @@ static struct stream_encoder *dce60_stream_encoder_create(
+ return NULL;
+
+ if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) {
+- dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id);
++ dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
++ &stream_enc_regs[eng_id], &se_shift, &se_mask);
+ return &enc110->base;
+ }
+
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
+index cde2c2cba1dd6..066dbf8125a87 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
+@@ -258,7 +258,8 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = {
+ stream_enc_regs(3),
+ stream_enc_regs(4),
+ stream_enc_regs(5),
+- stream_enc_regs(6)
++ stream_enc_regs(6),
++ {SR(DAC_SOURCE_SELECT),} /* DACA */
+ };
+
+ static const struct dce_stream_encoder_shift se_shift = {
+@@ -614,7 +615,8 @@ static struct stream_encoder *dce80_stream_encoder_create(
+ return NULL;
+
+ if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) {
+- dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id);
++ dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id,
++ &stream_enc_regs[eng_id], &se_shift, &se_mask);
+ return &enc110->base;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From e3a82348739ce91450f0a3e8e7883766b5c467d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 12:25:04 +0100
+Subject: drm/amd/display: Turn off DAC in DCE link encoder using VBIOS
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit e021ee995056ee7e58114edd92bcd4578d8b4bb5 ]
+
+Apparently, the VBIOS DAC1EncoderControl function is much more
+graceful about turning off the DAC. It writes various DAC
+registers in a specific sequence. Use that instead of just
+clearing the DAC_ENABLE register.
+
+Do this in just the dce110_link_encoder_disable_output
+function and remove it from the HWSS.
+
+Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)")
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Tested-by: Mauro Rossi <issor.oruam@gmail.com>
+Suggested-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/display/dc/dce/dce_link_encoder.c | 30 +++++++++++--------
+ .../amd/display/dc/hwss/dce110/dce110_hwseq.c | 3 --
+ 2 files changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+index 5c1a10f77733a..2e742950a62c7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
+@@ -131,6 +131,21 @@ static enum bp_result link_transmitter_control(
+ return result;
+ }
+
++static enum bp_result link_dac_encoder_control(
++ struct dce110_link_encoder *link_enc,
++ enum bp_encoder_control_action action,
++ uint32_t pix_clk_100hz)
++{
++ struct dc_bios *bios = link_enc->base.ctx->dc_bios;
++ struct bp_encoder_control encoder_control = {0};
++
++ encoder_control.action = action;
++ encoder_control.engine_id = link_enc->base.analog_engine;
++ encoder_control.pixel_clock = pix_clk_100hz / 10;
++
++ return bios->funcs->encoder_control(bios, &encoder_control);
++}
++
+ static void enable_phy_bypass_mode(
+ struct dce110_link_encoder *enc110,
+ bool enable)
+@@ -1337,19 +1352,8 @@ void dce110_link_encoder_disable_output(
+ struct bp_transmitter_control cntl = { 0 };
+ enum bp_result result;
+
+- switch (enc->analog_engine) {
+- case ENGINE_ID_DACA:
+- REG_UPDATE(DAC_ENABLE, DAC_ENABLE, 0);
+- break;
+- case ENGINE_ID_DACB:
+- /* DACB doesn't seem to be present on DCE6+,
+- * although there are references to it in the register file.
+- */
+- DC_LOG_ERROR("%s DACB is unsupported\n", __func__);
+- break;
+- default:
+- break;
+- }
++ if (enc->analog_engine != ENGINE_ID_UNKNOWN)
++ link_dac_encoder_control(enc110, ENCODER_CONTROL_DISABLE, 0);
+
+ /* The code below only applies to connectors that support digital signals. */
+ if (enc->transmitter == TRANSMITTER_UNKNOWN)
+diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+index ebd74b43e935e..fd41e52e4d2f1 100644
+--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+@@ -1218,9 +1218,6 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
+ dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst,
+ link_enc->transmitter - TRANSMITTER_UNIPHY_A);
+ }
+-
+- if (dc_is_rgb_signal(pipe_ctx->stream->signal))
+- dce110_dac_encoder_control(pipe_ctx, false);
+ }
+
+ void dce110_unblank_stream(struct pipe_ctx *pipe_ctx,
+--
+2.51.0
+
--- /dev/null
+From 674df3f14a80ca6d211ff258bc5b4542c2b6389e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Jan 2026 22:08:24 +0100
+Subject: drm/amd/display: Use DCE 6 link encoder for DCE 6 analog connectors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit 2de34fbcab2063cd3d52e5872a801b9a5fc755d0 ]
+
+DCE 6 should use the DCE 6 specific link encoder.
+This was a copy paste mistake.
+
+Fixes: 0fbe321a93ce ("drm/amd/display: Implement DCE analog link encoders (v2)")
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Reviewed-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
+index f0152933bee2c..068fb1df8d889 100644
+--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c
+@@ -734,7 +734,7 @@ static struct link_encoder *dce60_link_encoder_create(
+ return NULL;
+
+ if (enc_init_data->connector.id == CONNECTOR_ID_VGA) {
+- dce110_link_encoder_construct(enc110,
++ dce60_link_encoder_construct(enc110,
+ enc_init_data,
+ &link_enc_feature,
+ &link_enc_regs[ENGINE_ID_DACA],
+--
+2.51.0
+
--- /dev/null
+From 210ff702204f6c81f911cc2cfe363c8bcd96bad9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 23:38:28 +0100
+Subject: drm/amd/display: Use same max plane scaling limits for all 64 bpp
+ formats
+
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+
+[ Upstream commit f0157ce46cf0e5e2257e19d590c9b16036ce26d4 ]
+
+The plane scaling hw seems to have the same min/max plane scaling limits
+for all 16 bpc / 64 bpp interleaved pixel color formats.
+
+Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for
+all the 16 bpc fixed-point / unorm formats to use the same .fp16
+up/downscaling factor limits as used by the fp16 floating point formats.
+
+So far, 16 bpc unorm formats were not handled, and the default: path
+returned max/min factors for 32 bpp argb8888 formats, which were wrong
+and bigger than what many DCE / DCN hw generations could handle.
+
+The result sometimes was misscaling of framebuffers with
+DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616,
+DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested
+on Polaris11 / DCE-11.2.
+
+So far this went unnoticed, because only few userspace clients used such
+16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they
+did not experience this issue.
+
+With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL
+and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland
+compositor allowing for direct scanout of these formats, the scaling
+hw will be used on these formats if possible for HiDPI display scaling,
+so it is important to use the correct hw scaling limits to avoid wrong
+display.
+
+Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50
+on HiDPI displays with scaling enabled. The mutter Wayland compositor now
+correctly falls back to scaling via desktop compositing instead of direct
+scanout, thereby avoiding wrong image display. For unscaled mode, it
+correctly uses direct scanout.
+
+Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.")
+Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+index 7c4496fb4b9d4..f0946e67aef97 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+@@ -1060,10 +1060,15 @@ static void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev,
+ *min_downscale = plane_cap->max_downscale_factor.nv12;
+ break;
+
++ /* All 64 bpp formats have the same fp16 scaling limits */
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ABGR16161616F:
++ case DRM_FORMAT_XRGB16161616:
++ case DRM_FORMAT_ARGB16161616:
++ case DRM_FORMAT_XBGR16161616:
++ case DRM_FORMAT_ABGR16161616:
+ *max_upscale = plane_cap->max_upscale_factor.fp16;
+ *min_downscale = plane_cap->max_downscale_factor.fp16;
+ break;
+--
+2.51.0
+
--- /dev/null
+From 59d10ec5f2006f6c062f3b25ae60a512dadbc22d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 12:09:05 +0530
+Subject: drm/amdgpu: clean up the amdgpu_cs_parser_bos
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sunil Khatri <sunil.khatri@amd.com>
+
+[ Upstream commit f025a2b8d93358467b8e8f4b3a617e88c5f02fab ]
+
+In low memory conditions, kmalloc can fail. In such conditions
+unlock the mutex for a clean exit.
+
+We do not need to amdgpu_bo_list_put as it's been handled in the
+amdgpu_cs_parser_fini.
+
+Fixes: 737da5363cc0 ("drm/amdgpu: update the functions to use amdgpu version of hmm")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/r/202602030017.7E0xShmH-lkp@intel.com/
+Signed-off-by: Sunil Khatri <sunil.khatri@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index ecdfe6cb36ccd..dac0b15823f2a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -892,8 +892,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
+ struct amdgpu_bo *bo = e->bo;
+
+ e->range = amdgpu_hmm_range_alloc(NULL);
+- if (unlikely(!e->range))
+- return -ENOMEM;
++ if (unlikely(!e->range)) {
++ r = -ENOMEM;
++ goto out_free_user_pages;
++ }
+
+ r = amdgpu_ttm_tt_get_user_pages(bo, e->range);
+ if (r)
+--
+2.51.0
+
--- /dev/null
+From 06a0ff33b8d3b779d4586497780f255aa7ef527e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 09:25:32 +0000
+Subject: drm/amdgpu: Fix memory leak in amdgpu_acpi_enumerate_xcc()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit c9be63d565789b56ca7b0197e2cb78a3671f95a8 ]
+
+In amdgpu_acpi_enumerate_xcc(), if amdgpu_acpi_dev_init() returns -ENOMEM,
+the function returns directly without releasing the allocated xcc_info,
+resulting in a memory leak.
+
+Fix this by ensuring that xcc_info is properly freed in the error paths.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: 4d5275ab0b18 ("drm/amdgpu: Add parsing of acpi xcc objects")
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+index d31460a9e9582..7c9d8a6d0bfdb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+@@ -1135,8 +1135,10 @@ static int amdgpu_acpi_enumerate_xcc(void)
+ if (!dev_info)
+ ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, sbdf);
+
+- if (ret == -ENOMEM)
++ if (ret == -ENOMEM) {
++ kfree(xcc_info);
+ return ret;
++ }
+
+ if (!dev_info) {
+ kfree(xcc_info);
+--
+2.51.0
+
--- /dev/null
+From 81ef3e5b87c4fa8efb0644016a6927fef11c5909 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 08:35:15 +0000
+Subject: drm/amdgpu: Fix memory leak in amdgpu_ras_init()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit ee41e5b63c8210525c936ee637a2c8d185ce873c ]
+
+When amdgpu_nbio_ras_sw_init() fails in amdgpu_ras_init(), the function
+returns directly without freeing the allocated con structure, leading
+to a memory leak.
+
+Fix this by jumping to the release_con label to properly clean up the
+allocated memory before returning the error code.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: fdc94d3a8c88 ("drm/amdgpu: Rework pcie_bif ras sw_init")
+Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+index 2a6cf7963dde2..8de9f68f7bea6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+@@ -4343,7 +4343,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
+ * to handle fatal error */
+ r = amdgpu_nbio_ras_sw_init(adev);
+ if (r)
+- return r;
++ goto release_con;
+
+ if (adev->nbio.ras &&
+ adev->nbio.ras->init_ras_controller_interrupt) {
+--
+2.51.0
+
--- /dev/null
+From 76ea02802259f38f7748d1555c392230891ebdbc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 19:53:05 +0530
+Subject: drm/amdgpu: Fix missing unwind in amdgpu_ib_schedule() error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit ba038065655c45728be346d0b174a6da08d8a5c5 ]
+
+amdgpu_ib_schedule() returns early after calling amdgpu_ring_undo().
+This skips the common free_fence cleanup path. Other error paths were
+already changed to use goto free_fence, but this one was missed.
+
+Change the early return to goto free_fence so all error paths clean up
+the same way.
+
+Fixes the below:
+drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c:232 amdgpu_ib_schedule()
+warn: missing unwind goto?
+
+drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+ 124 int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
+ 125 struct amdgpu_ib *ibs, struct amdgpu_job *job,
+ 126 struct dma_fence **f)
+ 127 {
+
+ ...
+
+ 224
+ 225 if (ring->funcs->insert_start)
+ 226 ring->funcs->insert_start(ring);
+ 227
+ 228 if (job) {
+ 229 r = amdgpu_vm_flush(ring, job, need_pipe_sync);
+ 230 if (r) {
+ 231 amdgpu_ring_undo(ring);
+--> 232 return r;
+
+ The patch changed the other error paths to goto free_fence but
+ this one was accidentally skipped.
+
+ 233 }
+ 234 }
+ 235
+ 236 amdgpu_ring_ib_begin(ring);
+
+ ...
+
+ 338
+ 339 free_fence:
+ 340 if (!job)
+ 341 kfree(af);
+ 342 return r;
+ 343 }
+
+Fixes: f903b85ed0f1 ("drm/amdgpu: fix possible fence leaks from job structure")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+index 44f230d67da24..bfa64cd7a62d4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+@@ -229,7 +229,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
+ r = amdgpu_vm_flush(ring, job, need_pipe_sync);
+ if (r) {
+ amdgpu_ring_undo(ring);
+- return r;
++ goto free_fence;
+ }
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 79cbd5b6ee2616770f7f555fbad86067c5c7ef49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 11:51:45 -0500
+Subject: drm/amdgpu/sdma5: enable queue resets unconditionally
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 46a2cb7d24f21132e970cab52359210c3f5ea3c6 ]
+
+There is no firmware version dependency.
+
+Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask")
+Cc: Jesse Zhang <Jesse.Zhang@amd.com>
+Reviewed-by: Jesse.Zhang <Jesse.zhang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 15 +++------------
+ 1 file changed, 3 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+index 8ddc4df06a1fd..45e2933214a80 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
+@@ -1424,18 +1424,9 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block)
+
+ adev->sdma.supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
+- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) {
+- case IP_VERSION(5, 0, 0):
+- case IP_VERSION(5, 0, 2):
+- case IP_VERSION(5, 0, 5):
+- if ((adev->sdma.instance[0].fw_version >= 35) &&
+- !amdgpu_sriov_vf(adev) &&
+- !adev->debug_disable_gpu_ring_reset)
+- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+- break;
+- default:
+- break;
+- }
++ if (!amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+
+ /* Allocate memory for SDMA IP Dump buffer */
+ ptr = kcalloc(adev->sdma.num_instances * reg_count, sizeof(uint32_t), GFP_KERNEL);
+--
+2.51.0
+
--- /dev/null
+From ae71f9207da511fc585e4fb123ae57bb5f873148 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 11:52:46 -0500
+Subject: drm/amdgpu/sdma5.2: enable queue resets unconditionally
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 314d30ad50622fc0d70da71509f9dff21545be14 ]
+
+There is no firmware version dependency. This also
+enables sdma queue resets on all SDMA 5.2.x based
+chips.
+
+Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask")
+Cc: Jesse Zhang <Jesse.Zhang@amd.com>
+Reviewed-by: Jesse.Zhang <Jesse.zhang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 22 +++-------------------
+ 1 file changed, 3 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+index 51101b0aa2fab..82b1d34a6533e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+@@ -1342,25 +1342,9 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block)
+
+ adev->sdma.supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
+- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) {
+- case IP_VERSION(5, 2, 0):
+- case IP_VERSION(5, 2, 2):
+- case IP_VERSION(5, 2, 3):
+- case IP_VERSION(5, 2, 4):
+- if ((adev->sdma.instance[0].fw_version >= 76) &&
+- !amdgpu_sriov_vf(adev) &&
+- !adev->debug_disable_gpu_ring_reset)
+- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+- break;
+- case IP_VERSION(5, 2, 5):
+- if ((adev->sdma.instance[0].fw_version >= 34) &&
+- !amdgpu_sriov_vf(adev) &&
+- !adev->debug_disable_gpu_ring_reset)
+- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+- break;
+- default:
+- break;
+- }
++ if (!amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+
+ /* Allocate memory for SDMA IP Dump buffer */
+ ptr = kcalloc(adev->sdma.num_instances * reg_count, sizeof(uint32_t), GFP_KERNEL);
+--
+2.51.0
+
--- /dev/null
+From 4665dfb40041a079b2a3a694013b5a9b11613770 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 11:53:51 -0500
+Subject: drm/amdgpu/sdma6: enable queue resets unconditionally
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 56423871e9eef1dd069bddef895207fa5ce275fe ]
+
+There is no firmware version dependency. This also
+enables sdma queue resets on all SDMA 6.x based
+chips.
+
+Fixes: 59fd50b8663b ("drm/amdgpu: Add sysfs interface for sdma reset mask")
+Cc: Jesse Zhang <Jesse.Zhang@amd.com>
+Reviewed-by: Jesse.Zhang <Jesse.zhang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 15 +++------------
+ 1 file changed, 3 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+index 2170400449872..6809c6d4be5b1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+@@ -1351,18 +1351,9 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
+
+ adev->sdma.supported_reset =
+ amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring);
+- switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) {
+- case IP_VERSION(6, 0, 0):
+- case IP_VERSION(6, 0, 2):
+- case IP_VERSION(6, 0, 3):
+- if ((adev->sdma.instance[0].fw_version >= 21) &&
+- !amdgpu_sriov_vf(adev) &&
+- !adev->debug_disable_gpu_ring_reset)
+- adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+- break;
+- default:
+- break;
+- }
++ if (!amdgpu_sriov_vf(adev) &&
++ !adev->debug_disable_gpu_ring_reset)
++ adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
+
+ if (amdgpu_sdma_ras_sw_init(adev)) {
+ dev_err(adev->dev, "Failed to initialize sdma ras block!\n");
+--
+2.51.0
+
--- /dev/null
+From 91bce3d993cb5cdfe84dfdbc8565c0da954bd74b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 09:05:42 +0000
+Subject: drm/amdgpu: Use kvfree instead of kfree in
+ amdgpu_gmc_get_nps_memranges()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit 0c44d61945c4a80775292d96460aa2f22e62f86c ]
+
+amdgpu_discovery_get_nps_info() internally allocates memory for ranges
+using kvcalloc(), which may use vmalloc() for large allocation. Using
+kfree() to release vmalloc memory will lead to a memory corruption.
+
+Use kvfree() to safely handle both kmalloc and vmalloc allocations.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: b194d21b9bcc ("drm/amdgpu: Use NPS ranges from discovery table")
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+index d9c7ad297293b..2b37398337afc 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+@@ -1387,7 +1387,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
+ if (!*exp_ranges)
+ *exp_ranges = range_cnt;
+ err:
+- kfree(ranges);
++ kvfree(ranges);
+
+ return ret;
+ }
+--
+2.51.0
+
--- /dev/null
+From 3d79a11f6f79740d2241dc2e5e122ec070426e47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 21:18:11 +0530
+Subject: drm/amdkfd: Fix watch_id bounds checking in debug address watch v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit 5a19302cab5cec7ae7f1a60c619951e6c17d8742 ]
+
+The address watch clear code receives watch_id as an unsigned value
+(u32), but some helper functions were using a signed int and checked
+bits by shifting with watch_id.
+
+If a very large watch_id is passed from userspace, it can be converted
+to a negative value. This can cause invalid shifts and may access
+memory outside the watch_points array.
+
+drm/amdkfd: Fix watch_id bounds checking in debug address watch v2
+
+Fix this by checking that watch_id is within MAX_WATCH_ADDRESSES before
+using it. Also use BIT(watch_id) to test and clear bits safely.
+
+This keeps the behavior unchanged for valid watch IDs and avoids
+undefined behavior for invalid ones.
+
+Fixes the below:
+drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c:448
+kfd_dbg_trap_clear_dev_address_watch() error: buffer overflow
+'pdd->watch_points' 4 <= u32max user_rl='0-3,2147483648-u32max' uncapped
+
+drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c
+ 433 int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd,
+ 434 uint32_t watch_id)
+ 435 {
+ 436 int r;
+ 437
+ 438 if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id))
+
+kfd_dbg_owns_dev_watch_id() doesn't check for negative values so if
+watch_id is larger than INT_MAX it leads to a buffer overflow.
+(Negative shifts are undefined).
+
+ 439 return -EINVAL;
+ 440
+ 441 if (!pdd->dev->kfd->shared_resources.enable_mes) {
+ 442 r = debug_lock_and_unmap(pdd->dev->dqm);
+ 443 if (r)
+ 444 return r;
+ 445 }
+ 446
+ 447 amdgpu_gfx_off_ctrl(pdd->dev->adev, false);
+--> 448 pdd->watch_points[watch_id] = pdd->dev->kfd2kgd->clear_address_watch(
+ 449 pdd->dev->adev,
+ 450 watch_id);
+
+v2: (as per, Jonathan Kim)
+ - Add early watch_id >= MAX_WATCH_ADDRESSES validation in the set path to
+ match the clear path.
+ - Drop the redundant bounds check in kfd_dbg_owns_dev_watch_id().
+
+Fixes: e0f85f4690d0 ("drm/amdkfd: add debug set and clear address watch points operation")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Cc: Jonathan Kim <jonathan.kim@amd.com>
+Cc: Felix Kuehling <felix.kuehling@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Jonathan Kim <jonathan.kim@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+index ba99e0f258aee..986cb297de8f8 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+@@ -401,27 +401,25 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i
+ return -ENOMEM;
+ }
+
+-static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id)
++static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id)
+ {
+ spin_lock(&pdd->dev->watch_points_lock);
+
+ /* process owns device watch point so safe to clear */
+- if ((pdd->alloc_watch_ids >> watch_id) & 0x1) {
+- pdd->alloc_watch_ids &= ~(0x1 << watch_id);
+- pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id);
++ if (pdd->alloc_watch_ids & BIT(watch_id)) {
++ pdd->alloc_watch_ids &= ~BIT(watch_id);
++ pdd->dev->alloc_watch_ids &= ~BIT(watch_id);
+ }
+
+ spin_unlock(&pdd->dev->watch_points_lock);
+ }
+
+-static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id)
++static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id)
+ {
+ bool owns_watch_id = false;
+
+ spin_lock(&pdd->dev->watch_points_lock);
+- owns_watch_id = watch_id < MAX_WATCH_ADDRESSES &&
+- ((pdd->alloc_watch_ids >> watch_id) & 0x1);
+-
++ owns_watch_id = pdd->alloc_watch_ids & BIT(watch_id);
+ spin_unlock(&pdd->dev->watch_points_lock);
+
+ return owns_watch_id;
+@@ -432,6 +430,9 @@ int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd,
+ {
+ int r;
+
++ if (watch_id >= MAX_WATCH_ADDRESSES)
++ return -EINVAL;
++
+ if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id))
+ return -EINVAL;
+
+@@ -469,6 +470,9 @@ int kfd_dbg_trap_set_dev_address_watch(struct kfd_process_device *pdd,
+ if (r)
+ return r;
+
++ if (*watch_id >= MAX_WATCH_ADDRESSES)
++ return -EINVAL;
++
+ if (!pdd->dev->kfd->shared_resources.enable_mes) {
+ r = debug_lock_and_unmap(pdd->dev->dqm);
+ if (r) {
+--
+2.51.0
+
--- /dev/null
+From 96a1d5e9254814e0919926cffe7375dea2515ad5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jan 2026 08:55:49 +0530
+Subject: drm/i915/acpi: free _DSM package when no connectors
+
+From: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+
+[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ]
+
+acpi_evaluate_dsm_typed() returns an ACPI package in pkg.
+When pkg->package.count == 0, we returned without freeing pkg,
+leaking memory. Free pkg before returning on the empty case.
+
+Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_acpi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c
+index 68c01932f7b4f..e06f324027bec 100644
+--- a/drivers/gpu/drm/i915/display/intel_acpi.c
++++ b/drivers/gpu/drm/i915/display/intel_acpi.c
+@@ -96,6 +96,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle)
+
+ if (!pkg->package.count) {
+ DRM_DEBUG_DRIVER("no connection in _DSM\n");
++ ACPI_FREE(pkg);
+ return;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From b0157cec3d749b6f4a09a6fb4d230e93b579da15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 11:26:22 +0530
+Subject: drm/xe/bo: Redirect faults to dummy page for wedged device
+
+From: Raag Jadav <raag.jadav@intel.com>
+
+[ Upstream commit 4e83a8d58e1c721a89b3ffe15f549007080272e2 ]
+
+As per uapi documentation[1], the prerequisite for wedged device is to
+redirected page faults to a dummy page. Follow it.
+
+[1] Documentation/gpu/drm-uapi.rst
+
+v2: Add uapi reference and fixes tag (Matthew Brost)
+
+Fixes: 7bc00751f877 ("drm/xe: Use device wedged event")
+Signed-off-by: Raag Jadav <raag.jadav@intel.com>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patch.msgid.link/20260212055622.2054991-1-raag.jadav@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit c020fff70d757612933711dd3cc3751d7d782d3c)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_bo.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
+index 71acd45aa33b0..579e98dec7492 100644
+--- a/drivers/gpu/drm/xe/xe_bo.c
++++ b/drivers/gpu/drm/xe/xe_bo.c
+@@ -1942,7 +1942,7 @@ static vm_fault_t xe_bo_cpu_fault(struct vm_fault *vmf)
+ int err = 0;
+ int idx;
+
+- if (!drm_dev_enter(&xe->drm, &idx))
++ if (xe_device_wedged(xe) || !drm_dev_enter(&xe->drm, &idx))
+ return ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
+
+ ret = xe_bo_cpu_fault_fastpath(vmf, xe, bo, needs_rpm);
+--
+2.51.0
+
--- /dev/null
+From d8e1903a39aaef8b8a7b159046a238d3e9148627 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 3 Feb 2026 20:37:45 +0100
+Subject: drm/xe/configfs: Fix 'parameter name omitted' errors
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ Upstream commit 2a673fb4d787ce6672862cb693112378bff86abb ]
+
+On some configs and old compilers we can get following build errors:
+
+ ../drivers/gpu/drm/xe/xe_configfs.h: In function 'xe_configfs_get_ctx_restore_mid_bb':
+ ../drivers/gpu/drm/xe/xe_configfs.h:40:76: error: parameter name omitted
+ static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class,
+ ^~~~~~~~~~~~~~~~~~~~
+ ../drivers/gpu/drm/xe/xe_configfs.h: In function 'xe_configfs_get_ctx_restore_post_bb':
+ ../drivers/gpu/drm/xe/xe_configfs.h:42:77: error: parameter name omitted
+ static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class,
+ ^~~~~~~~~~~~~~~~~~~~
+when trying to define our configfs stub functions. Fix that.
+
+Fixes: 7a4756b2fd04 ("drm/xe/lrc: Allow to add user commands mid context switch")
+Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Reviewed-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260203193745.576-1-michal.wajdeczko@intel.com
+(cherry picked from commit f59cde8a2452b392115d2af8f1143a94725f4827)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_configfs.h | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_configfs.h b/drivers/gpu/drm/xe/xe_configfs.h
+index fed57be0b90e1..f3683bc7eb90c 100644
+--- a/drivers/gpu/drm/xe/xe_configfs.h
++++ b/drivers/gpu/drm/xe/xe_configfs.h
+@@ -21,9 +21,11 @@ bool xe_configfs_primary_gt_allowed(struct pci_dev *pdev);
+ bool xe_configfs_media_gt_allowed(struct pci_dev *pdev);
+ u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev);
+ bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev);
+-u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class,
++u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev,
++ enum xe_engine_class class,
+ const u32 **cs);
+-u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class,
++u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev,
++ enum xe_engine_class class,
+ const u32 **cs);
+ #ifdef CONFIG_PCI_IOV
+ unsigned int xe_configfs_get_max_vfs(struct pci_dev *pdev);
+@@ -37,9 +39,11 @@ static inline bool xe_configfs_primary_gt_allowed(struct pci_dev *pdev) { return
+ static inline bool xe_configfs_media_gt_allowed(struct pci_dev *pdev) { return true; }
+ static inline u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev) { return U64_MAX; }
+ static inline bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev) { return false; }
+-static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class,
++static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev,
++ enum xe_engine_class class,
+ const u32 **cs) { return 0; }
+-static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class,
++static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev,
++ enum xe_engine_class class,
+ const u32 **cs) { return 0; }
+ static inline unsigned int xe_configfs_get_max_vfs(struct pci_dev *pdev) { return UINT_MAX; }
+ #endif
+--
+2.51.0
+
--- /dev/null
+From 7c623e978d9fe0f2fa7c82bdfd14ab36bf373cca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 18:18:54 +0000
+Subject: drm/xe: Make xe_modparam.force_vram_bar_size signed
+
+From: Shuicheng Lin <shuicheng.lin@intel.com>
+
+[ Upstream commit 1acec6ef0511b92e7974cc5a8768bfd3a659feaf ]
+
+vram_bar_size is registered as an int module parameter and is documented
+to accept negative values to disable BAR resizing.
+Store it as an int in xe_modparam as well, so negative values work as
+intended and the module_param type matches.
+
+Fixes: 80742a1aa26e ("drm/xe: Allow to drop vram resizing")
+Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Signed-off-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260202181853.1095736-2-shuicheng.lin@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit 25c9aa4dcb5ef2ad9f354d19f8f1eeb690d1c161)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_module.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_module.h b/drivers/gpu/drm/xe/xe_module.h
+index 5a3bfea8b7b4c..b668495392701 100644
+--- a/drivers/gpu/drm/xe/xe_module.h
++++ b/drivers/gpu/drm/xe/xe_module.h
+@@ -12,7 +12,7 @@
+ struct xe_modparam {
+ bool force_execlist;
+ bool probe_display;
+- u32 force_vram_bar_size;
++ int force_vram_bar_size;
+ int guc_log_level;
+ char *guc_firmware_path;
+ char *huc_firmware_path;
+--
+2.51.0
+
--- /dev/null
+From 4749844f8e36ad04ad08d7c0feac5d2c72bac2ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jan 2026 16:56:22 +0000
+Subject: drm/xe/mmio: Avoid double-adjust in 64-bit reads
+
+From: Shuicheng Lin <shuicheng.lin@intel.com>
+
+[ Upstream commit 4a9b4e1fa52a6aaa1adbb7f759048df14afed54c ]
+
+xe_mmio_read64_2x32() was adjusting register addresses and then
+calling xe_mmio_read32(), which applies the adjustment again.
+This may shift accesses twice if adj_offset < adj_limit. There is
+no issue currently, as for media gt, adj_offset > adj_limit, so
+the 2nd adjust will be a no-op. But it may not work in future.
+
+To fix it, replace the adjusted-address comparison with a direct
+sanity check that ensures the MMIO address adjustment cutoff never
+falls within the 8-byte range of a 64-bit register. And let
+xe_mmio_read32() handle address translation.
+
+v2: rewrite the sanity check in a more natural way. (Matt)
+v3: Add Fixes tag. (Jani)
+
+Fixes: 07431945d8ae ("drm/xe: Avoid 64-bit register reads")
+Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
+Cc: Jani Nikula <jani.nikula@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260130165621.471408-2-shuicheng.lin@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit a30f999681126b128a43137793ac84b6a5b7443f)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_mmio.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
+index 350dca1f09259..3d59440ec44dd 100644
+--- a/drivers/gpu/drm/xe/xe_mmio.c
++++ b/drivers/gpu/drm/xe/xe_mmio.c
+@@ -260,11 +260,11 @@ u64 xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg)
+ struct xe_reg reg_udw = { .addr = reg.addr + 0x4 };
+ u32 ldw, udw, oldudw, retries;
+
+- reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr);
+- reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr);
+-
+- /* we shouldn't adjust just one register address */
+- xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4);
++ /*
++ * The two dwords of a 64-bit register can never straddle the offset
++ * adjustment cutoff.
++ */
++ xe_tile_assert(mmio->tile, !in_range(mmio->adj_limit, reg.addr + 1, 7));
+
+ oldudw = xe_mmio_read32(mmio, reg_udw);
+ for (retries = 5; retries; --retries) {
+--
+2.51.0
+
--- /dev/null
+From 9e56a23cd646ae886dae8e2157a6b745b738af74 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 00:53:32 +0100
+Subject: drm/xe/pf: Fix sysfs initialization
+
+From: Michal Wajdeczko <michal.wajdeczko@intel.com>
+
+[ Upstream commit bf7172cd25ed182f30af2cbb9f80c730dc717d8e ]
+
+In case of devm_add_action_or_reset() failure the provided cleanup
+action will be run immediately on the not yet initialized kobject.
+This may lead to errors like:
+
+ [ ] kobject: '(null)' (ff110001393608e0): is not initialized, yet kobject_put() is being called.
+ [ ] WARNING: lib/kobject.c:734 at kobject_put+0xd9/0x250, CPU#0: kworker/0:0/9
+ [ ] RIP: 0010:kobject_put+0xdf/0x250
+ [ ] Call Trace:
+ [ ] xe_sriov_pf_sysfs_init+0x21/0x100 [xe]
+ [ ] xe_sriov_pf_init_late+0x87/0x2b0 [xe]
+ [ ] xe_sriov_init_late+0x5f/0x2c0 [xe]
+ [ ] xe_device_probe+0x5f2/0xc20 [xe]
+ [ ] xe_pci_probe+0x396/0x610 [xe]
+ [ ] local_pci_probe+0x47/0xb0
+
+ [ ] refcount_t: underflow; use-after-free.
+ [ ] WARNING: lib/refcount.c:28 at refcount_warn_saturate+0x68/0xb0, CPU#0: kworker/0:0/9
+ [ ] RIP: 0010:refcount_warn_saturate+0x68/0xb0
+ [ ] Call Trace:
+ [ ] kobject_put+0x174/0x250
+ [ ] xe_sriov_pf_sysfs_init+0x21/0x100 [xe]
+ [ ] xe_sriov_pf_init_late+0x87/0x2b0 [xe]
+ [ ] xe_sriov_init_late+0x5f/0x2c0 [xe]
+ [ ] xe_device_probe+0x5f2/0xc20 [xe]
+ [ ] xe_pci_probe+0x396/0x610 [xe]
+ [ ] local_pci_probe+0x47/0xb0
+
+Fix that by calling kobject_init() and kobject_add() separately
+and register cleanup action after the kobject is initialized.
+
+Also make this cleanup registration a part of the create helper to
+fix another mistake, as in the loop we were wrongly passing parent
+kobject while registering cleanup action, and this resulted in some
+undetected leaks.
+
+Fixes: 5c170a4d9c53 ("drm/xe/pf: Prepare sysfs for SR-IOV admin attributes")
+Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Reviewed-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260203235332.1350-1-michal.wajdeczko@intel.com
+(cherry picked from commit 98b16727f07e26a5d4de84d88805ce7ffcfdd324)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c | 54 +++++++++++++-------------
+ 1 file changed, 26 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c
+index c0b767ac735cf..d1c1f6c295664 100644
+--- a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c
++++ b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c
+@@ -349,18 +349,33 @@ static const struct attribute_group *xe_sriov_vf_attr_groups[] = {
+
+ /* no user serviceable parts below */
+
+-static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid)
++static void action_put_kobject(void *arg)
++{
++ struct kobject *kobj = arg;
++
++ kobject_put(kobj);
++}
++
++static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid,
++ const struct kobj_type *ktype)
+ {
+ struct xe_sriov_kobj *vkobj;
++ int err;
+
+ xe_sriov_pf_assert_vfid(xe, vfid);
+
+ vkobj = kzalloc(sizeof(*vkobj), GFP_KERNEL);
+ if (!vkobj)
+- return NULL;
++ return ERR_PTR(-ENOMEM);
+
+ vkobj->xe = xe;
+ vkobj->vfid = vfid;
++ kobject_init(&vkobj->base, ktype);
++
++ err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, &vkobj->base);
++ if (err)
++ return ERR_PTR(err);
++
+ return &vkobj->base;
+ }
+
+@@ -471,28 +486,17 @@ static void pf_sysfs_note(struct xe_device *xe, int err, const char *what)
+ xe_sriov_dbg(xe, "Failed to setup sysfs %s (%pe)\n", what, ERR_PTR(err));
+ }
+
+-static void action_put_kobject(void *arg)
+-{
+- struct kobject *kobj = arg;
+-
+- kobject_put(kobj);
+-}
+-
+ static int pf_setup_root(struct xe_device *xe)
+ {
+ struct kobject *parent = &xe->drm.dev->kobj;
+ struct kobject *root;
+ int err;
+
+- root = create_xe_sriov_kobj(xe, PFID);
+- if (!root)
+- return pf_sysfs_error(xe, -ENOMEM, "root obj");
+-
+- err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root);
+- if (err)
+- return pf_sysfs_error(xe, err, "root action");
++ root = create_xe_sriov_kobj(xe, PFID, &xe_sriov_dev_ktype);
++ if (IS_ERR(root))
++ return pf_sysfs_error(xe, PTR_ERR(root), "root obj");
+
+- err = kobject_init_and_add(root, &xe_sriov_dev_ktype, parent, "sriov_admin");
++ err = kobject_add(root, parent, "sriov_admin");
+ if (err)
+ return pf_sysfs_error(xe, err, "root init");
+
+@@ -513,20 +517,14 @@ static int pf_setup_tree(struct xe_device *xe)
+ root = xe->sriov.pf.sysfs.root;
+
+ for (n = 0; n <= totalvfs; n++) {
+- kobj = create_xe_sriov_kobj(xe, VFID(n));
+- if (!kobj)
+- return pf_sysfs_error(xe, -ENOMEM, "tree obj");
+-
+- err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root);
+- if (err)
+- return pf_sysfs_error(xe, err, "tree action");
++ kobj = create_xe_sriov_kobj(xe, VFID(n), &xe_sriov_vf_ktype);
++ if (IS_ERR(kobj))
++ return pf_sysfs_error(xe, PTR_ERR(kobj), "tree obj");
+
+ if (n)
+- err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype,
+- root, "vf%u", n);
++ err = kobject_add(kobj, root, "vf%u", n);
+ else
+- err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype,
+- root, "pf");
++ err = kobject_add(kobj, root, "pf");
+ if (err)
+ return pf_sysfs_error(xe, err, "tree init");
+
+--
+2.51.0
+
--- /dev/null
+From e3b0257cc0786db6923a17f3da5d2f6f9ab14cb8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 12:50:41 +0100
+Subject: drm/xe/vf: Avoid reading media version when media GT is disabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Piotr Piórkowski <piotr.piorkowski@intel.com>
+
+[ Upstream commit 5e905ec67214444362b81345ef8fde63e58425b6 ]
+
+When the media GT is not allowed, a VF must not attempt to read
+the media version from the GuC. The GuC may not be loaded, and
+any attempt to communicate with it would result in a timeout
+and a VF probe failure:
+
+(...)
+[ 1912.406046] xe 0000:01:00.1: [drm] *ERROR* Tile0: GT1: GuC mmio request 0x5507: no reply 0x5507
+[ 1912.407277] xe 0000:01:00.1: [drm] *ERROR* Tile0: GT1: [GUC COMMUNICATION] MMIO send failed (-ETIMEDOUT)
+[ 1912.408689] xe 0000:01:00.1: [drm] *ERROR* VF: Tile0: GT1: Failed to reset GuC state (-ETIMEDOUT)
+[ 1912.413986] xe 0000:01:00.1: probe with driver xe failed with error -110
+
+Let's skip reading the media version for VFs when the media GT is not
+allowed.
+
+v2: move the condition directly to the VF path
+
+Fixes: 7abd69278bb5 ("drm/xe/configfs: Add attribute to disable GT types")
+Signed-off-by: Piotr Piórkowski <piotr.piorkowski@intel.com>
+Cc: Matt Roper <matthew.d.roper@intel.com>
+Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
+Cc: Shuicheng Lin <shuicheng.lin@intel.com>
+Reviewed-by: Shuicheng Lin <shuicheng.lin@intel.com>
+Link: https://patch.msgid.link/20260202115041.2863357-1-piotr.piorkowski@intel.com
+Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
+(cherry picked from commit 0bcacf56dc0b265f9c47056c6a4f0c1394a8a3f0)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_pci.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
+index 2aa883f5ef797..38ea9d7dad091 100644
+--- a/drivers/gpu/drm/xe/xe_pci.c
++++ b/drivers/gpu/drm/xe/xe_pci.c
+@@ -533,6 +533,12 @@ static int read_gmdid(struct xe_device *xe, enum xe_gmdid_type type, u32 *ver, u
+ struct xe_gt *gt __free(kfree) = NULL;
+ int err;
+
++ /* Don't try to read media ver if media GT is not allowed */
++ if (type == GMDID_MEDIA && !xe_configfs_media_gt_allowed(to_pci_dev(xe->drm.dev))) {
++ *ver = *revid = 0;
++ return 0;
++ }
++
+ gt = kzalloc(sizeof(*gt), GFP_KERNEL);
+ if (!gt)
+ return -ENOMEM;
+--
+2.51.0
+
--- /dev/null
+From b9df89a3b93ae981b193e0304d5c334791f55b14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Feb 2026 14:05:09 -0800
+Subject: drm/xe/xe2_hpg: Fix handling of Wa_14019988906 & Wa_14019877138
+
+From: Matt Roper <matthew.d.roper@intel.com>
+
+[ Upstream commit bc6387a2e0c1562faa56ce2a98cef50cab809e08 ]
+
+The PSS_CHICKEN register has been part of the RCS engine's LRC since it
+was first introduced in Xe_LP. That means that any workarounds that
+adjust its value (such as Wa_14019988906 and Wa_14019877138) need to be
+implemented in the lrc_was[] table so that they become part of the
+default LRC from which all subsequent LRCs are copied. Although these
+workarounds were implemented correctly on most platforms, they were
+incorrectly placed on the engine_was[] table for Xe2_HPG.
+
+Move the workarounds to the proper lrc_was[] table and switch the
+'xe_rtp_match_first_render_or_compute' rule to specifically match the
+RCS since that's the engine whose LRC manages the register.
+
+Bspec: 65182
+Fixes: 7f3ee7d88058 ("drm/xe/xe2hpg: Add initial GT workarounds")
+Reviewed-by: Shekhar Chauhan <shekhar.chauhan@intel.com>
+Link: https://patch.msgid.link/20260205220508.51905-2-matthew.d.roper@intel.com
+Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
+(cherry picked from commit e04c609eedf4d6748ac0bcada4de1275b034fed6)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_wa.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
+index e32dd2fde6f1c..c7eab0c4af7a8 100644
+--- a/drivers/gpu/drm/xe/xe_wa.c
++++ b/drivers/gpu/drm/xe/xe_wa.c
+@@ -567,16 +567,6 @@ static const struct xe_rtp_entry_sr engine_was[] = {
+ FUNC(xe_rtp_match_first_render_or_compute)),
+ XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS))
+ },
+- { XE_RTP_NAME("14019988906"),
+- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
+- FUNC(xe_rtp_match_first_render_or_compute)),
+- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD))
+- },
+- { XE_RTP_NAME("14019877138"),
+- XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
+- FUNC(xe_rtp_match_first_render_or_compute)),
+- XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT))
+- },
+ { XE_RTP_NAME("14020338487"),
+ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002),
+ FUNC(xe_rtp_match_first_render_or_compute)),
+@@ -873,6 +863,14 @@ static const struct xe_rtp_entry_sr lrc_was[] = {
+ XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(WM_CHICKEN3, HIZ_PLANE_COMPRESSION_DIS))
+ },
++ { XE_RTP_NAME("14019988906"),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)),
++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD))
++ },
++ { XE_RTP_NAME("14019877138"),
++ XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)),
++ XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT))
++ },
+ { XE_RTP_NAME("14021490052"),
+ XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
+ XE_RTP_ACTIONS(SET(FF_MODE,
+--
+2.51.0
+
--- /dev/null
+From 7e7cd481fb1fc6c6d66eb54d07b5f8044d87b09d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 10:49:56 +0000
+Subject: efi: Fix reservation of unaccepted memory table
+
+From: Kiryl Shutsemau (Meta) <kas@kernel.org>
+
+[ Upstream commit 0862438c90487e79822d5647f854977d50381505 ]
+
+The reserve_unaccepted() function incorrectly calculates the size of the
+memblock reservation for the unaccepted memory table. It aligns the
+size of the table, but fails to account for cases where the table's
+starting physical address (efi.unaccepted) is not page-aligned.
+
+If the table starts at an offset within a page and its end crosses into
+a subsequent page that the aligned size does not cover, the end of the
+table will not be reserved. This can lead to the table being overwritten
+or inaccessible, causing a kernel panic in accept_memory().
+
+This issue was observed when starting Intel TDX VMs with specific memory
+sizes (e.g., > 64GB).
+
+Fix this by calculating the end address first (including the unaligned
+start) and then aligning it up, ensuring the entire range is covered
+by the reservation.
+
+Fixes: 8dbe33956d96 ("efi/unaccepted: Make sure unaccepted table is mapped")
+Reported-by: Moritz Sanft <ms@edgeless.systems>
+Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/efi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index 17b5f3415465e..92e91c3eb4690 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -692,13 +692,13 @@ static __init int match_config_table(const efi_guid_t *guid,
+
+ static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted)
+ {
+- phys_addr_t start, size;
++ phys_addr_t start, end;
+
+ start = PAGE_ALIGN_DOWN(efi.unaccepted);
+- size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size);
++ end = PAGE_ALIGN(efi.unaccepted + sizeof(*unaccepted) + unaccepted->size);
+
+- memblock_add(start, size);
+- memblock_reserve(start, size);
++ memblock_add(start, end - start);
++ memblock_reserve(start, end - start);
+ }
+
+ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+--
+2.51.0
+
--- /dev/null
+From 68138ad93cf0231fa5031cbd07fbaf374ce692f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Feb 2026 09:19:49 -0800
+Subject: eth: fbnic: Add validation for MTU changes
+
+From: Dimitri Daskalakis <dimitri.daskalakis1@gmail.com>
+
+[ Upstream commit ccd8e87748ad083047d6c8544c5809b7f96cc8df ]
+
+Increasing the MTU beyond the HDS threshold causes the hardware to
+fragment packets across multiple buffers. If a single-buffer XDP program
+is attached, the driver will drop all multi-frag frames. While we can't
+prevent a remote sender from sending non-TCP packets larger than the MTU,
+this will prevent users from inadvertently breaking new TCP streams.
+
+Traditionally, drivers supported XDP with MTU less than 4Kb
+(packet per page). Fbnic currently prevents attaching XDP when MTU is too high.
+But it does not prevent increasing MTU after XDP is attached.
+
+Fixes: 1b0a3950dbd4 ("eth: fbnic: Add XDP pass, drop, abort support")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Dimitri Daskalakis <dimitri.daskalakis1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+index 81c9d5c9a4b2c..e3ca5fcfabef3 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+@@ -262,6 +262,23 @@ static int fbnic_set_mac(struct net_device *netdev, void *p)
+ return 0;
+ }
+
++static int fbnic_change_mtu(struct net_device *dev, int new_mtu)
++{
++ struct fbnic_net *fbn = netdev_priv(dev);
++
++ if (fbnic_check_split_frames(fbn->xdp_prog, new_mtu, fbn->hds_thresh)) {
++ dev_err(&dev->dev,
++ "MTU %d is larger than HDS threshold %d in XDP mode\n",
++ new_mtu, fbn->hds_thresh);
++
++ return -EINVAL;
++ }
++
++ WRITE_ONCE(dev->mtu, new_mtu);
++
++ return 0;
++}
++
+ void fbnic_clear_rx_mode(struct fbnic_dev *fbd)
+ {
+ struct net_device *netdev = fbd->netdev;
+@@ -533,6 +550,7 @@ static const struct net_device_ops fbnic_netdev_ops = {
+ .ndo_start_xmit = fbnic_xmit_frame,
+ .ndo_features_check = fbnic_features_check,
+ .ndo_set_mac_address = fbnic_set_mac,
++ .ndo_change_mtu = fbnic_change_mtu,
+ .ndo_set_rx_mode = fbnic_set_rx_mode,
+ .ndo_get_stats64 = fbnic_get_stats64,
+ .ndo_bpf = fbnic_bpf,
+--
+2.51.0
+
--- /dev/null
+From 31ccee2271d2b89e312df7ab123ac0da811f54b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 19:06:20 -0800
+Subject: eth: fbnic: Advertise supported XDP features.
+
+From: Dimitri Daskalakis <dimitri.daskalakis1@gmail.com>
+
+[ Upstream commit e977fcb3a318b53b47f23b44ac237fceb1b731fe ]
+
+Drivers are supposed to advertise the XDP features they support. This was
+missed while adding XDP support.
+
+Before:
+$ ynl --family netdev --dump dev-get
+...
+ {'ifindex': 3,
+ 'xdp-features': set(),
+ 'xdp-rx-metadata-features': set(),
+ 'xsk-features': set()},
+...
+
+After:
+$ ynl --family netdev --dump dev-get
+...
+ {'ifindex': 3,
+ 'xdp-features': {'basic', 'rx-sg'},
+ 'xdp-rx-metadata-features': set(),
+ 'xsk-features': set()},
+...
+
+Fixes: 168deb7b31b2 ("eth: fbnic: Add support for XDP_TX action")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Dimitri Daskalakis <dimitri.daskalakis1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260218030620.3329608-1-dimitri.daskalakis1@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_netdev.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+index e3ca5fcfabef3..b4b396ca9bce3 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
+@@ -805,6 +805,8 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)
+ netdev->hw_enc_features |= netdev->features;
+ netdev->features |= NETIF_F_NTUPLE;
+
++ netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_RX_SG;
++
+ netdev->min_mtu = IPV6_MIN_MTU;
+ netdev->max_mtu = FBNIC_MAX_JUMBO_FRAME_SIZE - ETH_HLEN;
+
+--
+2.51.0
+
--- /dev/null
+From e47f478f2f54575f3b48e63f40333359c9cea1c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 17:00:42 -0800
+Subject: eth: fbnic: increase FBNIC_HDR_BYTES_MIN from 128 to 256 bytes
+
+From: Bobby Eshleman <bobbyeshleman@meta.com>
+
+[ Upstream commit bd254115f38db3c046332bb62e8719e0dc7c2b53 ]
+
+Increase FBNIC_HDR_BYTES_MIN from 128 to 256 bytes. The previous minimum
+was too small to guarantee that very long L2+L3+L4 headers always fit
+within the header buffer. When EN_HDR_SPLIT is disabled and a packet
+exceeds MAX_HEADER_BYTES, splitting occurs at that byte offset instead
+of the header boundary, resulting in some of the header landing in the
+payload page. The increased minimum ensures headers always fit with the
+MAX_HEADER_BYTES cut off and land in the header page.
+
+Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration")
+Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
+Acked-by: Mohsin Bashir <mohsin.bashr@gmail.com>
+Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-2-55d050e6f606@meta.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+index 27776e844e29b..51a98f27d5d91 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
+@@ -66,7 +66,7 @@ struct fbnic_net;
+ (4096 - FBNIC_RX_HROOM - FBNIC_RX_TROOM - FBNIC_RX_PAD)
+ #define FBNIC_HDS_THRESH_DEFAULT \
+ (1536 - FBNIC_RX_PAD)
+-#define FBNIC_HDR_BYTES_MIN 128
++#define FBNIC_HDR_BYTES_MIN 256
+
+ struct fbnic_pkt_buff {
+ struct xdp_buff buff;
+--
+2.51.0
+
--- /dev/null
+From 372d012fa178fb032fbaf62eb6342ff611a5e9ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 17:00:43 -0800
+Subject: eth: fbnic: set DMA_HINT_L4 for all flows
+
+From: Bobby Eshleman <bobbyeshleman@meta.com>
+
+[ Upstream commit 0f30a31b55c4179fc55613a75ef41d496687d465 ]
+
+fbnic always advertises ETHTOOL_TCP_DATA_SPLIT_ENABLED via ethtool
+.get_ringparam. To enable proper splitting for all flow types, even for
+IP/Ethernet flows, this patch sets DMA_HINT_L4 unconditionally for all
+RSS and NFC flow steering rules. According to the spec, L4 falls back to
+L3 if no valid L4 is found, and L3 falls back to L2 if no L3 is found.
+This makes sure that the correct header boundary is used regardless of
+traffic type. This is important for zero-copy use cases where we must
+ensure that all ZC packets are split correctly.
+
+Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration")
+Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
+Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-3-55d050e6f606@meta.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c | 3 +++
+ drivers/net/ethernet/meta/fbnic/fbnic_rpc.c | 5 ++---
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+index 693ebdf387055..5edc28ba29553 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
+@@ -1142,6 +1142,9 @@ static int fbnic_set_cls_rule_ins(struct fbnic_net *fbn,
+ return -EINVAL;
+ }
+
++ dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT,
++ FBNIC_RCD_HDR_AL_DMA_HINT_L4);
++
+ /* Write action table values */
+ act_tcam->dest = dest;
+ act_tcam->rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, hash_idx);
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
+index 7f31e890031c0..42a186db43ea9 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c
+@@ -338,9 +338,8 @@ void fbnic_rss_reinit(struct fbnic_dev *fbd, struct fbnic_net *fbn)
+ else if (tstamp_mask & (1u << flow_type))
+ dest |= FBNIC_RPC_ACT_TBL0_TS_ENA;
+
+- if (act1_value[flow_type] & FBNIC_RPC_TCAM_ACT1_L4_VALID)
+- dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT,
+- FBNIC_RCD_HDR_AL_DMA_HINT_L4);
++ dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT,
++ FBNIC_RCD_HDR_AL_DMA_HINT_L4);
+
+ rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, flow_type);
+
+--
+2.51.0
+
--- /dev/null
+From 46b5e3c20823fbf13cbc72060553dd6bfe18a0de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 17:00:41 -0800
+Subject: eth: fbnic: set FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT on RDE_CTL0
+
+From: Bobby Eshleman <bobbyeshleman@meta.com>
+
+[ Upstream commit bbeb3bfbffe0279fa47c041658b037fb38a93965 ]
+
+Fix EN_HDR_SPLIT configuration by writing the field to RDE_CTL0 instead
+of RDE_CTL1.
+
+Because drop mode configuration and header splitting enablement both use
+RDE_CTL0, we consolidate these configurations into the single function
+fbnic_config_drop_mode.
+
+Fixes: 2b30fc01a6c7 ("eth: fbnic: Add support for HDS configuration")
+Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
+Acked-by: Mohsin Bashir <mohsin.bashr@gmail.com>
+Link: https://patch.msgid.link/20260211-fbnic-tcp-hds-fixes-v1-1-55d050e6f606@meta.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 25 +++++++++++---------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+index 13d508ce637f1..e119526fce14c 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+@@ -2575,7 +2575,8 @@ static void fbnic_enable_bdq(struct fbnic_ring *hpq, struct fbnic_ring *ppq)
+ }
+
+ static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv,
+- struct fbnic_ring *rcq, bool tx_pause)
++ struct fbnic_ring *rcq, bool tx_pause,
++ bool hdr_split)
+ {
+ struct fbnic_net *fbn = netdev_priv(nv->napi.dev);
+ u32 drop_mode, rcq_ctl;
+@@ -2588,22 +2589,26 @@ static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv,
+ /* Specify packet layout */
+ rcq_ctl = FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_DROP_MODE_MASK, drop_mode) |
+ FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_HROOM_MASK, FBNIC_RX_HROOM) |
+- FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_TROOM_MASK, FBNIC_RX_TROOM);
++ FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_TROOM_MASK, FBNIC_RX_TROOM) |
++ FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT, hdr_split);
+
+ fbnic_ring_wr32(rcq, FBNIC_QUEUE_RDE_CTL0, rcq_ctl);
+ }
+
+-void fbnic_config_drop_mode(struct fbnic_net *fbn, bool tx_pause)
++void fbnic_config_drop_mode(struct fbnic_net *fbn, bool txp)
+ {
++ bool hds;
+ int i, t;
+
++ hds = fbn->hds_thresh < FBNIC_HDR_BYTES_MIN;
++
+ for (i = 0; i < fbn->num_napi; i++) {
+ struct fbnic_napi_vector *nv = fbn->napi[i];
+
+ for (t = 0; t < nv->rxt_count; t++) {
+ struct fbnic_q_triad *qt = &nv->qt[nv->txt_count + t];
+
+- fbnic_config_drop_mode_rcq(nv, &qt->cmpl, tx_pause);
++ fbnic_config_drop_mode_rcq(nv, &qt->cmpl, txp, hds);
+ }
+ }
+ }
+@@ -2654,20 +2659,18 @@ static void fbnic_enable_rcq(struct fbnic_napi_vector *nv,
+ {
+ struct fbnic_net *fbn = netdev_priv(nv->napi.dev);
+ u32 log_size = fls(rcq->size_mask);
+- u32 hds_thresh = fbn->hds_thresh;
+ u32 rcq_ctl = 0;
+-
+- fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause);
++ bool hdr_split;
++ u32 hds_thresh;
+
+ /* Force lower bound on MAX_HEADER_BYTES. Below this, all frames should
+ * be split at L4. It would also result in the frames being split at
+ * L2/L3 depending on the frame size.
+ */
+- if (fbn->hds_thresh < FBNIC_HDR_BYTES_MIN) {
+- rcq_ctl = FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT;
+- hds_thresh = FBNIC_HDR_BYTES_MIN;
+- }
++ hdr_split = fbn->hds_thresh < FBNIC_HDR_BYTES_MIN;
++ fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause, hdr_split);
+
++ hds_thresh = max(fbn->hds_thresh, FBNIC_HDR_BYTES_MIN);
+ rcq_ctl |= FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_PADLEN_MASK, FBNIC_RX_PAD) |
+ FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_MAX_HDR_MASK, hds_thresh) |
+ FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_PAYLD_OFF_MASK,
+--
+2.51.0
+
--- /dev/null
+From 3ba2d343e2091336cb146a6930917b8fd4a66f97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 19:13:29 +0000
+Subject: fbnic: close fw_log race between users and teardown
+
+From: Chengfeng Ye <dg573847474@gmail.com>
+
+[ Upstream commit ee5492fd88cfc079c19fbeac78e9e53b7f6c04f3 ]
+
+Fixes a theoretical race on fw_log between the teardown path and fw_log
+write functions.
+
+fw_log is written inside fbnic_fw_log_write() and can be reached from
+the mailbox handler fbnic_fw_msix_intr(), but fw_log is freed before
+IRQ/MBX teardown during cleanup, resulting in a potential data race of
+dereferencing a freed/null variable.
+
+Possible Interleaving Scenario:
+ CPU0: fbnic_fw_msix_intr() // Entry
+ fbnic_fw_log_write()
+ if (fbnic_fw_log_ready()) // true
+ ... preempt ...
+ CPU1: fbnic_remove() // Entry
+ fbnic_fw_log_free()
+ vfree(log->data_start);
+ log->data_start = NULL;
+ CPU0: continues, walks log->entries or writes to log->data_start
+
+The initialization also has an incorrect order problem, as the fw_log
+is currently allocated after MBX setup during initialization.
+Fix the problems by adjusting the synchronization order to put
+initialization in place before the mailbox is enabled, and not cleared
+until after the mailbox has been disabled.
+
+Fixes: ecc53b1b46c89 ("eth: fbnic: Enable firmware logging")
+Signed-off-by: Chengfeng Ye <dg573847474@gmail.com>
+Link: https://patch.msgid.link/20260211191329.530886-1-dg573847474@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/meta/fbnic/fbnic_fw_log.c | 3 ---
+ drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 19 ++++++++++++-------
+ 2 files changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c
+index 85a883dba385f..d8a9a7d7c2375 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c
+@@ -51,8 +51,6 @@ int fbnic_fw_log_init(struct fbnic_dev *fbd)
+ log->data_start = data;
+ log->data_end = data + FBNIC_FW_LOG_SIZE;
+
+- fbnic_fw_log_enable(fbd, true);
+-
+ return 0;
+ }
+
+@@ -63,7 +61,6 @@ void fbnic_fw_log_free(struct fbnic_dev *fbd)
+ if (!fbnic_fw_log_ready(fbd))
+ return;
+
+- fbnic_fw_log_disable(fbd);
+ INIT_LIST_HEAD(&log->entries);
+ log->size = 0;
+ vfree(log->data_start);
+diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+index 9240673c7533d..e92187bc1c0fa 100644
+--- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
++++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c
+@@ -307,11 +307,17 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ goto free_irqs;
+ }
+
++ err = fbnic_fw_log_init(fbd);
++ if (err)
++ dev_warn(fbd->dev,
++ "Unable to initialize firmware log buffer: %d\n",
++ err);
++
+ err = fbnic_fw_request_mbx(fbd);
+ if (err) {
+ dev_err(&pdev->dev,
+ "Firmware mailbox initialization failure\n");
+- goto free_irqs;
++ goto free_fw_log;
+ }
+
+ /* Send the request to enable the FW logging to host. Note if this
+@@ -319,11 +325,7 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ * possible the FW is just too old to support the logging and needs
+ * to be updated.
+ */
+- err = fbnic_fw_log_init(fbd);
+- if (err)
+- dev_warn(fbd->dev,
+- "Unable to initialize firmware log buffer: %d\n",
+- err);
++ fbnic_fw_log_enable(fbd, true);
+
+ fbnic_devlink_register(fbd);
+ fbnic_devlink_otp_check(fbd, "error detected during probe");
+@@ -370,6 +372,8 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ * firmware updates for fixes.
+ */
+ return 0;
++free_fw_log:
++ fbnic_fw_log_free(fbd);
+ free_irqs:
+ fbnic_free_irqs(fbd);
+ err_destroy_health:
+@@ -404,8 +408,9 @@ static void fbnic_remove(struct pci_dev *pdev)
+ fbnic_hwmon_unregister(fbd);
+ fbnic_dbg_fbd_exit(fbd);
+ fbnic_devlink_unregister(fbd);
+- fbnic_fw_log_free(fbd);
++ fbnic_fw_log_disable(fbd);
+ fbnic_fw_free_mbx(fbd);
++ fbnic_fw_log_free(fbd);
+ fbnic_free_irqs(fbd);
+
+ fbnic_devlink_health_destroy(fbd);
+--
+2.51.0
+
--- /dev/null
+From 5a11392d8f69158feb13dd893406b7c72d29a525 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Dec 2025 16:10:10 +0100
+Subject: fs/ntfs3: fix deadlock in ni_read_folio_cmpr
+
+From: Szymon Wilczek <swilczek.lx@gmail.com>
+
+[ Upstream commit e37a75bb866c29da954b51d0dd7670406246d9ee ]
+
+Syzbot reported a task hung in ni_readpage_cmpr (now ni_read_folio_cmpr).
+This is caused by a lock inversion deadlock involving the inode mutex
+(ni_lock) and page locks.
+
+Scenario:
+1. Task A enters ntfs_read_folio() for page X. It acquires ni_lock.
+2. Task A calls ni_read_folio_cmpr(), which attempts to lock all pages in
+ the compressed frame (including page Y).
+3. Concurrently, Task B (e.g., via readahead) has locked page Y and
+ calls ntfs_read_folio().
+4. Task B waits for ni_lock (held by A).
+5. Task A waits for page Y lock (held by B).
+ -> DEADLOCK.
+
+The fix is to restructure locking: do not take ni_lock in ntfs_read_folio().
+Instead, acquire ni_lock inside ni_read_folio_cmpr() ONLY AFTER all required
+page locks for the frame have been successfully acquired. This restores the
+correct lock ordering (Page Lock -> ni_lock) consistent with VFS.
+
+Reported-by: syzbot+5af33dd272b913b65880@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=5af33dd272b913b65880
+Fixes: f35590ee26f5 ("fs/ntfs3: remove ntfs_bio_pages and use page cache for compressed I/O")
+Signed-off-by: Szymon Wilczek <swilczek.lx@gmail.com>
+[almaz.alexandrovich@paragon-software.com: ni_readpage_cmpr was renamed to ni_read_folio_cmpr]
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/frecord.c | 2 ++
+ fs/ntfs3/inode.c | 3 +--
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
+index 7e3d61de2f8fa..d5bbd47e1ee9d 100644
+--- a/fs/ntfs3/frecord.c
++++ b/fs/ntfs3/frecord.c
+@@ -2107,7 +2107,9 @@ int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio)
+ pages[i] = pg;
+ }
+
++ ni_lock(ni);
+ err = ni_read_frame(ni, frame_vbo, pages, pages_per_frame, 0);
++ ni_unlock(ni);
+
+ out1:
+ for (i = 0; i < pages_per_frame; i++) {
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index 1319b99dfeb41..ec8e954f4426c 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -735,9 +735,8 @@ static int ntfs_read_folio(struct file *file, struct folio *folio)
+ }
+
+ if (is_compressed(ni)) {
+- ni_lock(ni);
++ /* ni_lock is taken inside ni_read_folio_cmpr after page locks */
+ err = ni_read_folio_cmpr(ni, folio);
+- ni_unlock(ni);
+ return err;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From e0d10835ab57b076d0031e45de03493c5d2424b0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Dec 2025 15:21:41 +0800
+Subject: fs/ntfs3: fix ntfs_mount_options leak in ntfs_fill_super()
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit f7edab0cee03a1cbe0e55a7bcab8d2d8b6b74278 ]
+
+In ntfs_fill_super(), the fc->fs_private pointer is set to NULL without
+first freeing the memory it points to. This causes the subsequent call to
+ntfs_fs_free() to skip freeing the ntfs_mount_options structure.
+
+This results in a kmemleak report:
+
+ unreferenced object 0xff1100015378b800 (size 32):
+ comm "mount", pid 582, jiffies 4294890685
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+ 00 00 00 00 00 00 00 00 ed ff ed ff 00 04 00 00 ................
+ backtrace (crc ed541d8c):
+ __kmalloc_cache_noprof+0x424/0x5a0
+ __ntfs_init_fs_context+0x47/0x590
+ alloc_fs_context+0x5d8/0x960
+ __x64_sys_fsopen+0xb1/0x190
+ do_syscall_64+0x50/0x1f0
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+This issue can be reproduced using the following commands:
+ fallocate -l 100M test.file
+ mount test.file /tmp/test
+
+Since sbi->options is duplicated from fc->fs_private and does not
+directly use the memory allocated for fs_private, it is unnecessary to
+set fc->fs_private to NULL.
+
+Additionally, this patch simplifies the code by utilizing the helper
+function put_mount_options() instead of open-coding the cleanup logic.
+
+Reported-by: syzbot+23aee7afc440fe803545@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=23aee7afc440fe803545
+Fixes: aee4d5a521e9 ("ntfs3: fix double free of sbi->options->nls and clarify ownership of fc->fs_private")
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/super.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
+index 8b0cf0ed4f72c..0567a3b224ed3 100644
+--- a/fs/ntfs3/super.c
++++ b/fs/ntfs3/super.c
+@@ -705,9 +705,7 @@ static void ntfs_put_super(struct super_block *sb)
+ ntfs_set_state(sbi, NTFS_DIRTY_CLEAR);
+
+ if (sbi->options) {
+- unload_nls(sbi->options->nls);
+- kfree(sbi->options->nls_name);
+- kfree(sbi->options);
++ put_mount_options(sbi->options);
+ sbi->options = NULL;
+ }
+
+@@ -1253,7 +1251,6 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
+ }
+ }
+ sbi->options = options;
+- fc->fs_private = NULL;
+ sb->s_flags |= SB_NODIRATIME;
+ sb->s_magic = 0x7366746e; // "ntfs"
+ sb->s_op = &ntfs_sops;
+@@ -1679,9 +1676,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
+ out:
+ /* sbi->options == options */
+ if (options) {
+- unload_nls(options->nls);
+- kfree(options->nls_name);
+- kfree(options);
++ put_mount_options(sbi->options);
+ sbi->options = NULL;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From f8f77ec37c07da9b1d64c82337de2c761ea7dade Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jan 2026 16:50:24 +0000
+Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot
+
+From: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+
+[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ]
+
+In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the
+entry size ('esize') is retrieved from the log record without adequate
+bounds checking.
+
+Specifically, the code calculates the end of the entry ('e2') using:
+ e2 = Add2Ptr(e1, esize);
+
+It then calculates the size for memmove using 'PtrOffset(e2, ...)',
+which subtracts the end pointer from the buffer limit. If 'esize' is
+maliciously large, 'e2' exceeds the used buffer size. This results in
+a negative offset which, when cast to size_t for memmove, interprets
+as a massive unsigned integer, leading to a heap buffer overflow.
+
+This commit adds a check to ensure that the entry size ('esize') strictly
+fits within the remaining used space of the index header before performing
+memory operations.
+
+Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
+Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/fslog.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
+index 38934e6978ece..28bd611f580d9 100644
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -3429,6 +3429,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe,
+
+ e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off));
+ esize = le16_to_cpu(e1->size);
++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize)
++ goto dirty_vol;
++
+ e2 = Add2Ptr(e1, esize);
+
+ memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used)));
+--
+2.51.0
+
--- /dev/null
+From 814af6655a618a54c7567f9de7e1263a58c5de66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Nov 2025 23:02:51 +0100
+Subject: fs/ntfs3: Initialize new folios before use
+
+From: Bartlomiej Kubik <kubik.bartlomiej@gmail.com>
+
+[ Upstream commit f223ebffa185cc8da934333c5a31ff2d4f992dc9 ]
+
+KMSAN reports an uninitialized value in longest_match_std(), invoked
+from ntfs_compress_write(). When new folios are allocated without being
+marked uptodate and ni_read_frame() is skipped because the caller expects
+the frame to be completely overwritten, some reserved folios may remain
+only partially filled, leaving the rest memory uninitialized.
+
+Fixes: 584f60ba22f7 ("ntfs3: Convert ntfs_get_frame_pages() to use a folio")
+Tested-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com
+Reported-by: syzbot+08d8956768c96a2c52cf@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=08d8956768c96a2c52cf
+
+Signed-off-by: Bartlomiej Kubik <kubik.bartlomiej@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index 2e7b2e566ebe1..732260087066d 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -995,7 +995,7 @@ static int ntfs_get_frame_pages(struct address_space *mapping, pgoff_t index,
+
+ folio = __filemap_get_folio(mapping, index,
+ FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
+- gfp_mask);
++ gfp_mask | __GFP_ZERO);
+ if (IS_ERR(folio)) {
+ while (npages--) {
+ folio = page_folio(pages[npages]);
+--
+2.51.0
+
--- /dev/null
+From 7f8958188bcccef6bc46ad6fb34a2c5ab3dc2aae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Dec 2025 11:53:25 +0800
+Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the
+ same
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ]
+
+When processing valid within the range [valid : pos), if valid cannot
+be retrieved correctly, for example, if the retrieved valid value is
+always the same, this can trigger a potential infinite loop, similar
+to the hung problem reported by syzbot [1].
+
+Adding a check for the valid value within the loop body, and terminating
+the loop and returning -EINVAL if the value is the same as the current
+value, can prevent this.
+
+[1]
+INFO: task syz.4.21:6056 blocked for more than 143 seconds.
+Call Trace:
+ rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244
+ inode_lock include/linux/fs.h:1027 [inline]
+ ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284
+
+Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
+Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/file.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index 732260087066d..5120bd7851694 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -1077,8 +1077,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from)
+ goto out;
+
+ if (lcn == SPARSE_LCN) {
+- ni->i_valid = valid =
+- frame_vbo + ((u64)clen << sbi->cluster_bits);
++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits);
++ if (ni->i_valid == valid) {
++ err = -EINVAL;
++ goto out;
++ }
++ ni->i_valid = valid;
+ continue;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 407f842cf9f5c24fe054bc010e3957a21276ac27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 22:57:46 +0300
+Subject: fs/ntfs3: rename ni_readpage_cmpr into ni_read_folio_cmpr
+
+From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+
+[ Upstream commit 4248f563f0b76f3fb74b2a28ee068bf66fcbbedf ]
+
+The old "readpage" naming is still used in ni_readpage_cmpr(), even though
+the vfs has transitioned to the folio-based read_folio() API.
+
+This patch performs a straightforward renaming of the helper:
+ni_readpage_cmpr() -> ni_read_folio_cmpr().
+
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Stable-dep-of: e37a75bb866c ("fs/ntfs3: fix deadlock in ni_read_folio_cmpr")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/frecord.c | 8 ++++----
+ fs/ntfs3/inode.c | 2 +-
+ fs/ntfs3/ntfs_fs.h | 2 +-
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
+index 641ddaf8d4a07..7e3d61de2f8fa 100644
+--- a/fs/ntfs3/frecord.c
++++ b/fs/ntfs3/frecord.c
+@@ -2046,18 +2046,18 @@ static struct page *ntfs_lock_new_page(struct address_space *mapping,
+ }
+
+ /*
+- * ni_readpage_cmpr
++ * ni_read_folio_cmpr
+ *
+ * When decompressing, we typically obtain more than one page per reference.
+ * We inject the additional pages into the page cache.
+ */
+-int ni_readpage_cmpr(struct ntfs_inode *ni, struct folio *folio)
++int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio)
+ {
+ int err;
+ struct ntfs_sb_info *sbi = ni->mi.sbi;
+ struct address_space *mapping = folio->mapping;
+- pgoff_t index = folio->index;
+- u64 frame_vbo, vbo = (u64)index << PAGE_SHIFT;
++ pgoff_t index;
++ u64 frame_vbo, vbo = folio_pos(folio);
+ struct page **pages = NULL; /* Array of at most 16 pages. stack? */
+ u8 frame_bits;
+ CLST frame;
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index 0a9ac5efeb67c..1319b99dfeb41 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -736,7 +736,7 @@ static int ntfs_read_folio(struct file *file, struct folio *folio)
+
+ if (is_compressed(ni)) {
+ ni_lock(ni);
+- err = ni_readpage_cmpr(ni, folio);
++ err = ni_read_folio_cmpr(ni, folio);
+ ni_unlock(ni);
+ return err;
+ }
+diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
+index a4559c9f64e68..7b619bb151ce9 100644
+--- a/fs/ntfs3/ntfs_fs.h
++++ b/fs/ntfs3/ntfs_fs.h
+@@ -568,7 +568,7 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint);
+ #define _ni_write_inode(i, w) ni_write_inode(i, w, __func__)
+ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
+ __u64 vbo, __u64 len);
+-int ni_readpage_cmpr(struct ntfs_inode *ni, struct folio *folio);
++int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio);
+ int ni_decompress_file(struct ntfs_inode *ni);
+ int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages,
+ u32 pages_per_frame, int copy);
+--
+2.51.0
+
--- /dev/null
+From 94e7c37b7cd3c1886f06c4df96147b48645ee0de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 14:11:49 -0800
+Subject: gpio: amd-fch: ionly return allowed values from amd_fch_gpio_get()
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+[ Upstream commit fbd03587ba732c612b8a569d1cf5bed72bd3a27c ]
+
+As of 86ef402d805d ("gpiolib: sanitize the return value of
+gpio_chip::get()") gpiolib requires drivers implementing GPIOs to only
+return 0, 1 or negative error for the get() callbacks. Ensure that
+amd-fch complies with this requirement.
+
+Fixes: 86ef402d805d ("gpiolib: sanitize the return value of gpio_chip::get()")
+Reported-and-tested-by: Tj <tj.iam.tj@proton.me>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Link: https://patch.msgid.link/aZTlwnvHt2Gho4yN@google.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-amd-fch.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpio/gpio-amd-fch.c b/drivers/gpio/gpio-amd-fch.c
+index e6c6c3ec7656e..9f329938202bf 100644
+--- a/drivers/gpio/gpio-amd-fch.c
++++ b/drivers/gpio/gpio-amd-fch.c
+@@ -8,6 +8,7 @@
+ *
+ */
+
++#include <linux/bitfield.h>
+ #include <linux/err.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+@@ -120,15 +121,15 @@ static int amd_fch_gpio_get(struct gpio_chip *gc,
+ unsigned int offset)
+ {
+ unsigned long flags;
+- int ret;
++ u32 val;
+ struct amd_fch_gpio_priv *priv = gpiochip_get_data(gc);
+ void __iomem *ptr = amd_fch_gpio_addr(priv, offset);
+
+ spin_lock_irqsave(&priv->lock, flags);
+- ret = (readl_relaxed(ptr) & AMD_FCH_GPIO_FLAG_READ);
++ val = readl_relaxed(ptr);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+- return ret;
++ return FIELD_GET(AMD_FCH_GPIO_FLAG_READ, val);
+ }
+
+ static int amd_fch_gpio_request(struct gpio_chip *chip,
+--
+2.51.0
+
--- /dev/null
+From 08ef006907255e2a072c0fc2ab28ac6fdf9ee911 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Feb 2026 12:05:55 -0800
+Subject: gpio: cdev: Avoid NULL dereference in linehandle_create()
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 6af6be278e3ba2ffb6af5b796c89dfb3f5d9063e ]
+
+In linehandle_create(), there is a statement like this:
+ retain_and_null_ptr(lh);
+
+Soon after, there is a debug printout that dereferences "lh", which
+will crash things.
+
+Avoid the crash by using handlereq.lines, which is the same value.
+
+Fixes: da7e394bf58f ("gpio: convert linehandle_create() to FD_PREPARE()")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://patch.msgid.link/20260215120555.v2.1.I77c3eb563271c21870379eefd16ebbc4e09635bb@changeid
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib-cdev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
+index 2adc3c0709082..189127721e383 100644
+--- a/drivers/gpio/gpiolib-cdev.c
++++ b/drivers/gpio/gpiolib-cdev.c
+@@ -388,7 +388,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
+ fd_publish(fdf);
+
+ dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n",
+- lh->num_descs);
++ handlereq.lines);
+
+ return 0;
+ }
+--
+2.51.0
+
--- /dev/null
+From 801b4d9ad5761d229cbccf162639b5294705458b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:28 +0000
+Subject: icmp: prevent possible overflow in icmp_global_allow()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 034bbd806298e9ba4197dd1587b0348ee30996ea ]
+
+Following expression can overflow
+if sysctl_icmp_msgs_per_sec is big enough.
+
+sysctl_icmp_msgs_per_sec * delta / HZ;
+
+Fixes: 4cdf507d5452 ("icmp: add a global rate limitation")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216142832.3834174-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/icmp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index a2cff16668d72..471dd862f6639 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -248,7 +248,8 @@ bool icmp_global_allow(struct net *net)
+ if (delta < HZ / 50)
+ return false;
+
+- incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ;
++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec);
++ incr = div_u64((u64)incr * delta, HZ);
+ if (!incr)
+ return false;
+
+--
+2.51.0
+
--- /dev/null
+From 48835273717464aed4e66f52d263c9b3d5d3fc21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:29 +0000
+Subject: inet: move icmp_global_{credit,stamp} to a separate cache line
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87b08913a9ae82082e276d237ece08fc8ee24380 ]
+
+icmp_global_credit was meant to be changed ~1000 times per second,
+but if an admin sets net.ipv4.icmp_msgs_per_sec to a very high value,
+icmp_global_credit changes can inflict false sharing to surrounding
+fields that are read mostly.
+
+Move icmp_global_credit and icmp_global_stamp to a separate
+cacheline aligned group.
+
+Fixes: b056b4cd9178 ("icmp: move icmp_global.credit and icmp_global.stamp to per netns storage")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216142832.3834174-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netns/ipv4.h | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 2dbd46fc4734b..8e971c7bf1646 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -88,6 +88,12 @@ struct netns_ipv4 {
+ int sysctl_tcp_rcvbuf_low_rtt;
+ __cacheline_group_end(netns_ipv4_read_rx);
+
++ /* ICMP rate limiter hot cache line. */
++ __cacheline_group_begin_aligned(icmp);
++ atomic_t icmp_global_credit;
++ u32 icmp_global_stamp;
++ __cacheline_group_end_aligned(icmp);
++
+ struct inet_timewait_death_row tcp_death_row;
+ struct udp_table *udp_table;
+
+@@ -141,8 +147,7 @@ struct netns_ipv4 {
+ int sysctl_icmp_ratemask;
+ int sysctl_icmp_msgs_per_sec;
+ int sysctl_icmp_msgs_burst;
+- atomic_t icmp_global_credit;
+- u32 icmp_global_stamp;
++
+ u32 ip_rt_min_pmtu;
+ int ip_rt_mtu_expires;
+ int ip_rt_min_advmss;
+--
+2.51.0
+
--- /dev/null
+From ae6029d2a55a080518b8392d5f74117e2039e7fa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:22:02 +0000
+Subject: ipv6: fix a race in ip6_sock_set_v6only()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ]
+
+It is unlikely that this function will be ever called
+with isk->inet_num being not zero.
+
+Perform the check on isk->inet_num inside the locked section
+for complete safety.
+
+Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ipv6.h | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index 74fbf1ad8065a..6a933690e0ff5 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -1280,12 +1280,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
+
+ static inline int ip6_sock_set_v6only(struct sock *sk)
+ {
+- if (inet_sk(sk)->inet_num)
+- return -EINVAL;
++ int ret = 0;
++
+ lock_sock(sk);
+- sk->sk_ipv6only = true;
++ if (inet_sk(sk)->inet_num)
++ ret = -EINVAL;
++ else
++ sk->sk_ipv6only = true;
+ release_sock(sk);
+- return 0;
++ return ret;
+ }
+
+ static inline void ip6_sock_set_recverr(struct sock *sk)
+--
+2.51.0
+
--- /dev/null
+From 02042b9abe3538355cbceb89e0000ec10214a476 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 17:50:21 +0000
+Subject: ipv6: Fix out-of-bound access in fib6_add_rt2node().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 8244f959e2c125c849e569f5b23ed49804cce695 ]
+
+syzbot reported out-of-bound read in fib6_add_rt2node(). [0]
+
+When IPv6 route is created with RTA_NH_ID, struct fib6_info
+does not have the trailing struct fib6_nh.
+
+The cited commit started to check !iter->fib6_nh->fib_nh_gw_family
+to ensure that rt6_qualify_for_ecmp() will return false for iter.
+
+If iter->nh is not NULL, rt6_qualify_for_ecmp() returns false anyway.
+
+Let's check iter->nh before reading iter->fib6_nh and avoid OOB read.
+
+[0]:
+BUG: KASAN: slab-out-of-bounds in fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142
+Read of size 1 at addr ffff8880384ba6de by task syz.0.18/5500
+
+CPU: 0 UID: 0 PID: 5500 Comm: syz.0.18 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xba/0x230 mm/kasan/report.c:482
+ kasan_report+0x117/0x150 mm/kasan/report.c:595
+ fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142
+ fib6_add_rt2node_nh net/ipv6/ip6_fib.c:1363 [inline]
+ fib6_add+0x910/0x18c0 net/ipv6/ip6_fib.c:1531
+ __ip6_ins_rt net/ipv6/route.c:1351 [inline]
+ ip6_route_add+0xde/0x1b0 net/ipv6/route.c:3957
+ inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660
+ rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f9316b9aeb9
+Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007ffd8809b678 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f9316e15fa0 RCX: 00007f9316b9aeb9
+RDX: 0000000000000000 RSI: 0000200000004380 RDI: 0000000000000003
+RBP: 00007f9316c08c1f R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 00007f9316e15fac R14: 00007f9316e15fa0 R15: 00007f9316e15fa0
+ </TASK>
+
+Allocated by task 5499:
+ kasan_save_stack mm/kasan/common.c:57 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263 [inline]
+ __do_kmalloc_node mm/slub.c:5657 [inline]
+ __kmalloc_noprof+0x40c/0x7e0 mm/slub.c:5669
+ kmalloc_noprof include/linux/slab.h:961 [inline]
+ kzalloc_noprof include/linux/slab.h:1094 [inline]
+ fib6_info_alloc+0x30/0xf0 net/ipv6/ip6_fib.c:155
+ ip6_route_info_create+0x142/0x860 net/ipv6/route.c:3820
+ ip6_route_add+0x49/0x1b0 net/ipv6/route.c:3949
+ inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660
+ rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: bbf4a17ad9ff ("ipv6: Fix ECMP sibling count mismatch when clearing RTF_ADDRCONF")
+Reported-by: syzbot+707d6a5da1ab9e0c6f9d@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/698cbfba.050a0220.2eeac1.009d.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Reviewed-by: Shigeru Yoshida <syoshida@redhat.com>
+Link: https://patch.msgid.link/20260211175133.3657034-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_fib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index c6439e30e892a..cc149227b49f4 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -1139,7 +1139,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
+ fib6_add_gc_list(iter);
+ }
+ if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) &&
+- !iter->fib6_nh->fib_nh_gw_family) {
++ (iter->nh || !iter->fib6_nh->fib_nh_gw_family)) {
+ iter->fib6_flags &= ~RTF_ADDRCONF;
+ iter->fib6_flags &= ~RTF_PREFIX_RT;
+ }
+--
+2.51.0
+
--- /dev/null
+From 3fb24ec4dccf88d6253ef67c610551ddd992c6b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:30 +0000
+Subject: ipv6: icmp: remove obsolete code in icmpv6_xrlim_allow()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0201eedb69b24a6be9b7c1716287a89c4dde2320 ]
+
+Following part was needed before the blamed commit, because
+inet_getpeer_v6() second argument was the prefix.
+
+ /* Give more bandwidth to wider prefixes. */
+ if (rt->rt6i_dst.plen < 128)
+ tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
+
+Now inet_getpeer_v6() retrieves hosts, we need to remove
+@tmo adjustement or wider prefixes likes /24 allow 8x
+more ICMP to be sent for a given ratelimit.
+
+As we had this issue for a while, this patch changes net.ipv6.icmp.ratelimit
+default value from 1000ms to 100ms to avoid potential regressions.
+
+Also add a READ_ONCE() when reading net->ipv6.sysctl.icmpv6_time.
+
+Fixes: fd0273d7939f ("ipv6: Remove external dependency on rt6i_dst and rt6i_src")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Cc: Martin KaFai Lau <martin.lau@kernel.org>
+Link: https://patch.msgid.link/20260216142832.3834174-4-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/networking/ip-sysctl.rst | 7 ++++---
+ net/ipv6/af_inet6.c | 2 +-
+ net/ipv6/icmp.c | 7 +------
+ 3 files changed, 6 insertions(+), 10 deletions(-)
+
+diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
+index bc9a01606daf5..2c65d57103fb1 100644
+--- a/Documentation/networking/ip-sysctl.rst
++++ b/Documentation/networking/ip-sysctl.rst
+@@ -3232,12 +3232,13 @@ enhanced_dad - BOOLEAN
+ ===========
+
+ ratelimit - INTEGER
+- Limit the maximal rates for sending ICMPv6 messages.
++ Limit the maximal rates for sending ICMPv6 messages to a particular
++ peer.
+
+ 0 to disable any limiting,
+- otherwise the minimal space between responses in milliseconds.
++ otherwise the space between responses in milliseconds.
+
+- Default: 1000
++ Default: 100
+
+ ratemask - list of comma separated ranges
+ For ICMPv6 message types matching the ranges in the ratemask, limit
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index b705751eb73c6..d3534bdb805da 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -955,7 +955,7 @@ static int __net_init inet6_net_init(struct net *net)
+ int err = 0;
+
+ net->ipv6.sysctl.bindv6only = 0;
+- net->ipv6.sysctl.icmpv6_time = 1*HZ;
++ net->ipv6.sysctl.icmpv6_time = HZ / 10;
+ net->ipv6.sysctl.icmpv6_echo_ignore_all = 0;
+ net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0;
+ net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0;
+diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
+index a77f3113ef23b..55b1aa75ab802 100644
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -217,14 +217,9 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
+ } else if (dev && (dev->flags & IFF_LOOPBACK)) {
+ res = true;
+ } else {
+- struct rt6_info *rt = dst_rt6_info(dst);
+- int tmo = net->ipv6.sysctl.icmpv6_time;
++ int tmo = READ_ONCE(net->ipv6.sysctl.icmpv6_time);
+ struct inet_peer *peer;
+
+- /* Give more bandwidth to wider prefixes. */
+- if (rt->rt6i_dst.plen < 128)
+- tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
+-
+ peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr);
+ res = inet_peer_xrlim_allow(peer, tmo);
+ }
+--
+2.51.0
+
--- /dev/null
+From 9e6303b7a931eb6f039347083b09de673b256d9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Feb 2026 16:58:50 +0200
+Subject: ipvs: do not keep dest_dst if dev is going down
+
+From: Julian Anastasov <ja@ssi.bg>
+
+[ Upstream commit 8fde939b0206afc1d5846217a01a16b9bc8c7896 ]
+
+There is race between the netdev notifier ip_vs_dst_event()
+and the code that caches dst with dev that is going down.
+As the FIB can be notified for the closed device after our
+handler finishes, it is possible valid route to be returned
+and cached resuling in a leaked dev reference until the dest
+is not removed.
+
+To prevent new dest_dst to be attached to dest just after the
+handler dropped the old one, add a netif_running() check
+to make sure the notifier handler is not currently running
+for device that is closing.
+
+Fixes: 7a4f0761fce3 ("IPVS: init and cleanup restructuring")
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 46 ++++++++++++++++++++++++++-------
+ 1 file changed, 36 insertions(+), 10 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index 64c697212578a..124f779424b0f 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -294,6 +294,12 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs,
+ return true;
+ }
+
++/* rt has device that is down */
++static bool rt_dev_is_down(const struct net_device *dev)
++{
++ return dev && !netif_running(dev);
++}
++
+ /* Get route to destination or remote server */
+ static int
+ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+@@ -309,9 +315,11 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+
+ if (dest) {
+ dest_dst = __ip_vs_dst_check(dest);
+- if (likely(dest_dst))
++ if (likely(dest_dst)) {
+ rt = dst_rtable(dest_dst->dst_cache);
+- else {
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.ip;
++ } else {
+ dest_dst = ip_vs_dest_dst_alloc();
+ spin_lock_bh(&dest->dst_lock);
+ if (!dest_dst) {
+@@ -327,14 +335,22 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+ ip_vs_dest_dst_free(dest_dst);
+ goto err_unreach;
+ }
+- __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0);
++ /* It is forbidden to attach dest->dest_dst if
++ * device is going down.
++ */
++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst)))
++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0);
++ else
++ noref = 0;
+ spin_unlock_bh(&dest->dst_lock);
+ IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d\n",
+ &dest->addr.ip, &dest_dst->dst_saddr.ip,
+ rcuref_read(&rt->dst.__rcuref));
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.ip;
++ if (!noref)
++ ip_vs_dest_dst_free(dest_dst);
+ }
+- if (ret_saddr)
+- *ret_saddr = dest_dst->dst_saddr.ip;
+ } else {
+ noref = 0;
+
+@@ -471,9 +487,11 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+
+ if (dest) {
+ dest_dst = __ip_vs_dst_check(dest);
+- if (likely(dest_dst))
++ if (likely(dest_dst)) {
+ rt = dst_rt6_info(dest_dst->dst_cache);
+- else {
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.in6;
++ } else {
+ u32 cookie;
+
+ dest_dst = ip_vs_dest_dst_alloc();
+@@ -494,14 +512,22 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
+ }
+ rt = dst_rt6_info(dst);
+ cookie = rt6_get_cookie(rt);
+- __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie);
++ /* It is forbidden to attach dest->dest_dst if
++ * device is going down.
++ */
++ if (!rt_dev_is_down(dst_dev_rcu(&rt->dst)))
++ __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie);
++ else
++ noref = 0;
+ spin_unlock_bh(&dest->dst_lock);
+ IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n",
+ &dest->addr.in6, &dest_dst->dst_saddr.in6,
+ rcuref_read(&rt->dst.__rcuref));
++ if (ret_saddr)
++ *ret_saddr = dest_dst->dst_saddr.in6;
++ if (!noref)
++ ip_vs_dest_dst_free(dest_dst);
+ }
+- if (ret_saddr)
+- *ret_saddr = dest_dst->dst_saddr.in6;
+ } else {
+ noref = 0;
+ dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm,
+--
+2.51.0
+
--- /dev/null
+From 9a2373589647bda5b67d7e6f554c35be23b29490 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 14 Feb 2026 16:58:49 +0200
+Subject: ipvs: skip ipv6 extension headers for csum checks
+
+From: Julian Anastasov <ja@ssi.bg>
+
+[ Upstream commit 05cfe9863ef049d98141dc2969eefde72fb07625 ]
+
+Protocol checksum validation fails for IPv6 if there are extension
+headers before the protocol header. iph->len already contains its
+offset, so use it to fix the problem.
+
+Fixes: 2906f66a5682 ("ipvs: SCTP Trasport Loadbalancing Support")
+Fixes: 0bbdd42b7efa ("IPVS: Extend protocol DNAT/SNAT and state handlers")
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_proto_sctp.c | 18 ++++++------------
+ net/netfilter/ipvs/ip_vs_proto_tcp.c | 21 +++++++--------------
+ net/netfilter/ipvs/ip_vs_proto_udp.c | 20 +++++++-------------
+ 3 files changed, 20 insertions(+), 39 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
+index 83e452916403d..63c78a1f3918a 100644
+--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
++++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
+@@ -10,7 +10,8 @@
+ #include <net/ip_vs.h>
+
+ static int
+-sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp);
++sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
++ unsigned int sctphoff);
+
+ static int
+ sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,
+@@ -108,7 +109,7 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
+ int ret;
+
+ /* Some checks before mangling */
+- if (!sctp_csum_check(cp->af, skb, pp))
++ if (!sctp_csum_check(cp->af, skb, pp, sctphoff))
+ return 0;
+
+ /* Call application helper if needed */
+@@ -156,7 +157,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
+ int ret;
+
+ /* Some checks before mangling */
+- if (!sctp_csum_check(cp->af, skb, pp))
++ if (!sctp_csum_check(cp->af, skb, pp, sctphoff))
+ return 0;
+
+ /* Call application helper if needed */
+@@ -185,19 +186,12 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
+ }
+
+ static int
+-sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
++sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
++ unsigned int sctphoff)
+ {
+- unsigned int sctphoff;
+ struct sctphdr *sh;
+ __le32 cmp, val;
+
+-#ifdef CONFIG_IP_VS_IPV6
+- if (af == AF_INET6)
+- sctphoff = sizeof(struct ipv6hdr);
+- else
+-#endif
+- sctphoff = ip_hdrlen(skb);
+-
+ sh = (struct sctphdr *)(skb->data + sctphoff);
+ cmp = sh->checksum;
+ val = sctp_compute_cksum(skb, sctphoff);
+diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
+index f68a1533ee455..8cc0a8ce62411 100644
+--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
++++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
+@@ -28,7 +28,8 @@
+ #include <net/ip_vs.h>
+
+ static int
+-tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp);
++tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
++ unsigned int tcphoff);
+
+ static int
+ tcp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,
+@@ -165,7 +166,7 @@ tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
+ int ret;
+
+ /* Some checks before mangling */
+- if (!tcp_csum_check(cp->af, skb, pp))
++ if (!tcp_csum_check(cp->af, skb, pp, tcphoff))
+ return 0;
+
+ /* Call application helper if needed */
+@@ -243,7 +244,7 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
+ int ret;
+
+ /* Some checks before mangling */
+- if (!tcp_csum_check(cp->af, skb, pp))
++ if (!tcp_csum_check(cp->af, skb, pp, tcphoff))
+ return 0;
+
+ /*
+@@ -300,17 +301,9 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
+
+
+ static int
+-tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
++tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
++ unsigned int tcphoff)
+ {
+- unsigned int tcphoff;
+-
+-#ifdef CONFIG_IP_VS_IPV6
+- if (af == AF_INET6)
+- tcphoff = sizeof(struct ipv6hdr);
+- else
+-#endif
+- tcphoff = ip_hdrlen(skb);
+-
+ switch (skb->ip_summed) {
+ case CHECKSUM_NONE:
+ skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
+@@ -321,7 +314,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
+ if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ skb->len - tcphoff,
+- ipv6_hdr(skb)->nexthdr,
++ IPPROTO_TCP,
+ skb->csum)) {
+ IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
+ "Failed checksum for");
+diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
+index 0f0107c80dd23..f9de632e38cdd 100644
+--- a/net/netfilter/ipvs/ip_vs_proto_udp.c
++++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
+@@ -24,7 +24,8 @@
+ #include <net/ip6_checksum.h>
+
+ static int
+-udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp);
++udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
++ unsigned int udphoff);
+
+ static int
+ udp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,
+@@ -154,7 +155,7 @@ udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
+ int ret;
+
+ /* Some checks before mangling */
+- if (!udp_csum_check(cp->af, skb, pp))
++ if (!udp_csum_check(cp->af, skb, pp, udphoff))
+ return 0;
+
+ /*
+@@ -237,7 +238,7 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
+ int ret;
+
+ /* Some checks before mangling */
+- if (!udp_csum_check(cp->af, skb, pp))
++ if (!udp_csum_check(cp->af, skb, pp, udphoff))
+ return 0;
+
+ /*
+@@ -296,17 +297,10 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
+
+
+ static int
+-udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
++udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
++ unsigned int udphoff)
+ {
+ struct udphdr _udph, *uh;
+- unsigned int udphoff;
+-
+-#ifdef CONFIG_IP_VS_IPV6
+- if (af == AF_INET6)
+- udphoff = sizeof(struct ipv6hdr);
+- else
+-#endif
+- udphoff = ip_hdrlen(skb);
+
+ uh = skb_header_pointer(skb, udphoff, sizeof(_udph), &_udph);
+ if (uh == NULL)
+@@ -324,7 +318,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
+ if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ skb->len - udphoff,
+- ipv6_hdr(skb)->nexthdr,
++ IPPROTO_UDP,
+ skb->csum)) {
+ IP_VS_DBG_RL_PKT(0, af, pp, skb, 0,
+ "Failed checksum for");
+--
+2.51.0
+
--- /dev/null
+From 4c975cb278a0922e6bcf4e2f3c26d1c11748769b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 13:45:22 -0800
+Subject: kbuild: Add objtool to top-level clean target
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 68b4fe32d73789dea23e356f468de67c8367ef8f ]
+
+Objtool is an integral part of the build, make sure it gets cleaned by
+"make clean" and "make mrproper".
+
+Fixes: 442f04c34a1a ("objtool: Add tool to perform compile-time stack metadata validation")
+Reported-by: Jens Remus <jremus@linux.ibm.com>
+Closes: https://lore.kernel.org/15f2af3b-be33-46fc-b972-6b8e7e0aa52e@linux.ibm.com
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Tested-by: Jens Remus <jremus@linux.ibm.com>
+Link: https://patch.msgid.link/968faf2ed30fa8b3519f79f01a1ecfe7929553e5.1770759919.git.jpoimboe@kernel.org
+[nathan: use Closes: instead of Link: per checkpatch.pl]
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile | 11 ++++++++++-
+ tools/objtool/Makefile | 2 ++
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index 21df635071198..7e34042743d9e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1474,6 +1474,15 @@ ifneq ($(wildcard $(resolve_btfids_O)),)
+ $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean
+ endif
+
++PHONY += objtool_clean
++
++objtool_O = $(abspath $(objtree))/tools/objtool
++
++objtool_clean:
++ifneq ($(wildcard $(objtool_O)),)
++ $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean
++endif
++
+ tools/: FORCE
+ $(Q)mkdir -p $(objtree)/tools
+ $(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/
+@@ -1637,7 +1646,7 @@ vmlinuxclean:
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean
+ $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean)
+
+-clean: archclean vmlinuxclean resolve_btfids_clean
++clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean
+
+ # mrproper - Delete all generated files, including .config
+ #
+diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
+index a40f302329291..6964175abdfdf 100644
+--- a/tools/objtool/Makefile
++++ b/tools/objtool/Makefile
+@@ -29,6 +29,8 @@ srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+ srctree := $(patsubst %/,%,$(dir $(srctree)))
+ endif
+
++RM ?= rm -f
++
+ LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/
+ ifneq ($(OUTPUT),)
+ LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd
+--
+2.51.0
+
--- /dev/null
+From e0c698a0a0d0f75696e5624610f9dfc7ad5b589a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 15:01:34 -0800
+Subject: libbpf: Fix invalid write loop logic in bpf_linker__add_buf()
+
+From: Amery Hung <ameryhung@gmail.com>
+
+[ Upstream commit 04999b99e81eaa7b6223ec1c03af3bcb4ac57aaa ]
+
+Fix bpf_linker__add_buf()'s logic of copying data from memory buffer into
+memfd. In the event of short write not writing entire buf_sz bytes into memfd
+file, we'll append bytes from the beginning of buf *again* (corrupting ELF
+file contents) instead of correctly appending the rest of not-yet-read buf
+contents.
+
+Closes: https://github.com/libbpf/libbpf/issues/945
+Fixes: 6d5e5e5d7ce1 ("libbpf: Extend linker API to support in-memory ELF files")
+Signed-off-by: Amery Hung <ameryhung@gmail.com>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Link: https://lore.kernel.org/bpf/20260209230134.3530521-1-ameryhung@gmail.com
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/linker.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
+index f4403e3cf9946..78f92c39290af 100644
+--- a/tools/lib/bpf/linker.c
++++ b/tools/lib/bpf/linker.c
+@@ -581,7 +581,7 @@ int bpf_linker__add_buf(struct bpf_linker *linker, void *buf, size_t buf_sz,
+
+ written = 0;
+ while (written < buf_sz) {
+- ret = write(fd, buf, buf_sz);
++ ret = write(fd, buf + written, buf_sz - written);
+ if (ret < 0) {
+ ret = -errno;
+ pr_warn("failed to write '%s': %s\n", filename, errstr(ret));
+--
+2.51.0
+
--- /dev/null
+From 849581d7f5a79a15193cdcdfde73e029b850d59a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:25:57 +0000
+Subject: macvlan: observe an RCU grace period in macvlan_common_newlink()
+ error path
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ]
+
+valis reported that a race condition still happens after my prior patch.
+
+macvlan_common_newlink() might have made @dev visible before
+detecting an error, and its caller will directly call free_netdev(dev).
+
+We must respect an RCU period, either in macvlan or the core networking
+stack.
+
+After adding a temporary mdelay(1000) in macvlan_forward_source_one()
+to open the race window, valis repro was:
+
+ip link add p1 type veth peer p2
+ip link set address 00:00:00:00:00:20 dev p1
+ip link set up dev p1
+ip link set up dev p2
+ip link add mv0 link p2 type macvlan mode source
+
+(ip link add invalid% link p2 type macvlan mode source macaddr add
+00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4
+PING 1.2.3.4 (1.2.3.4): 56 data bytes
+RTNETLINK answers: Invalid argument
+
+BUG: KASAN: slab-use-after-free in macvlan_forward_source
+(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+Read of size 8 at addr ffff888016bb89c0 by task e/175
+
+CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
+Call Trace:
+<IRQ>
+dump_stack_lvl (lib/dump_stack.c:123)
+print_report (mm/kasan/report.c:379 mm/kasan/report.c:482)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+kasan_report (mm/kasan/report.c:597)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+? tasklet_init (kernel/softirq.c:983)
+macvlan_handle_frame (drivers/net/macvlan.c:501)
+
+Allocated by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+__kasan_kmalloc (mm/kasan/common.c:419)
+__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657
+mm/slub.c:7140)
+alloc_netdev_mqs (net/core/dev.c:12012)
+rtnl_create_link (net/core/rtnetlink.c:3648)
+rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Freed by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+kasan_save_free_info (mm/kasan/generic.c:587)
+__kasan_slab_free (mm/kasan/common.c:287)
+kfree (mm/slub.c:6674 mm/slub.c:6882)
+rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: valis <sec@valis.email>
+Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macvlan.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index c509228be84d1..4433b8e95b6ac 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1572,6 +1572,11 @@ int macvlan_common_newlink(struct net_device *dev,
+ if (create)
+ macvlan_port_destroy(port->dev);
+ }
++ /* @dev might have been made visible before an error was detected.
++ * Make sure to observe an RCU grace period before our caller
++ * (rtnl_newlink()) frees it.
++ */
++ synchronize_net();
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(macvlan_common_newlink);
+--
+2.51.0
+
--- /dev/null
+From e67c5598626666e384fd9de6346bb29b80bc0452 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Feb 2026 04:40:10 -0500
+Subject: mshv: fix SRCU protection in irqfd resampler ack handler
+
+From: Li RongQing <lirongqing@baidu.com>
+
+[ Upstream commit 2e7577cd5ddc1f86d1b6c48caf3cfa87dbb14e34 ]
+
+Replace hlist_for_each_entry_rcu() with hlist_for_each_entry_srcu()
+in mshv_irqfd_resampler_ack() to correctly handle SRCU-protected
+linked list traversal.
+
+The function uses SRCU (sleepable RCU) synchronization via
+partition->pt_irq_srcu, but was incorrectly using the RCU variant
+for list iteration. This could lead to race conditions when the
+list is modified concurrently.
+
+Also add srcu_read_lock_held() assertion as required by
+hlist_for_each_entry_srcu() to ensure we're in the proper
+read-side critical section.
+
+Fixes: 621191d709b14 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs")
+Signed-off-by: Li RongQing <lirongqing@baidu.com>
+Reviewed-by: Anirudh Rayabharam (Microsoft) <anirudh@anirudhrb.com>
+Acked-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/mshv_eventfd.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hv/mshv_eventfd.c b/drivers/hv/mshv_eventfd.c
+index 0b75ff1edb735..6d176ed8ae516 100644
+--- a/drivers/hv/mshv_eventfd.c
++++ b/drivers/hv/mshv_eventfd.c
+@@ -87,8 +87,9 @@ static void mshv_irqfd_resampler_ack(struct mshv_irq_ack_notifier *mian)
+
+ idx = srcu_read_lock(&partition->pt_irq_srcu);
+
+- hlist_for_each_entry_rcu(irqfd, &resampler->rsmplr_irqfd_list,
+- irqfd_resampler_hnode) {
++ hlist_for_each_entry_srcu(irqfd, &resampler->rsmplr_irqfd_list,
++ irqfd_resampler_hnode,
++ srcu_read_lock_held(&partition->pt_irq_srcu)) {
+ if (hv_should_clear_interrupt(irqfd->irqfd_lapic_irq.lapic_control.interrupt_type))
+ hv_call_clear_virtual_interrupt(partition->pt_id);
+
+--
+2.51.0
+
--- /dev/null
+From 5527061049067225b66f380a271b68e6c1a38d05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 09:00:30 +0200
+Subject: net: bridge: mcast: always update mdb_n_entries for vlan contexts
+
+From: Nikolay Aleksandrov <nikolay@nvidia.com>
+
+[ Upstream commit 8b769e311a86bb9d15c5658ad283b86fc8f080a2 ]
+
+syzbot triggered a warning[1] about the number of mdb entries in a context.
+It turned out that there are multiple ways to trigger that warning today
+(some got added during the years), the root cause of the problem is that
+the increase is done conditionally, and over the years these different
+conditions increased so there were new ways to trigger the warning, that is
+to do a decrease which wasn't paired with a previous increase.
+
+For example one way to trigger it is with flush:
+ $ ip l add br0 up type bridge vlan_filtering 1 mcast_snooping 1
+ $ ip l add dumdum up master br0 type dummy
+ $ bridge mdb add dev br0 port dumdum grp 239.0.0.1 permanent vid 1
+ $ ip link set dev br0 down
+ $ ip link set dev br0 type bridge mcast_vlan_snooping 1
+ ^^^^ this will enable snooping, but will not update mdb_n_entries
+ because in __br_multicast_enable_port_ctx() we check !netif_running
+ $ bridge mdb flush dev br0
+ ^^^ this will trigger the warning because it will delete the pg which
+ we added above, which will try to decrease mdb_n_entries
+
+Fix the problem by removing the conditional increase and always keep the
+count up-to-date while the vlan exists. In order to do that we have to
+first initialize it on port-vlan context creation, and then always increase
+or decrease the value regardless of mcast options. To keep the current
+behaviour we have to enforce the mdb limit only if the context is port's or
+if the port-vlan's mcast snooping is enabled.
+
+[1]
+ ------------[ cut here ]------------
+ n == 0
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline], CPU#0: syz.4.4607/22043
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline], CPU#0: syz.4.4607/22043
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825, CPU#0: syz.4.4607/22043
+ Modules linked in:
+ CPU: 0 UID: 0 PID: 22043 Comm: syz.4.4607 Not tainted syzkaller #0 PREEMPT(full)
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026
+ RIP: 0010:br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline]
+ RIP: 0010:br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline]
+ RIP: 0010:br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825
+ Code: 41 5f 5d e9 04 7a 48 f7 e8 3f 73 5c f7 90 0f 0b 90 e9 cf fd ff ff e8 31 73 5c f7 90 0f 0b 90 e9 16 fd ff ff e8 23 73 5c f7 90 <0f> 0b 90 e9 60 fd ff ff e8 15 73 5c f7 eb 05 e8 0e 73 5c f7 48 8b
+ RSP: 0018:ffffc9000c207220 EFLAGS: 00010293
+ RAX: ffffffff8a68042d RBX: ffff88807c6f1800 RCX: ffff888066e90000
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+ RBP: 0000000000000000 R08: ffff888066e90000 R09: 000000000000000c
+ R10: 000000000000000c R11: 0000000000000000 R12: ffff8880303ef800
+ R13: dffffc0000000000 R14: ffff888050eb11c4 R15: 1ffff1100a1d6238
+ FS: 00007fa45921b6c0(0000) GS:ffff8881256f5000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007fa4591f9ff8 CR3: 0000000081df2000 CR4: 00000000003526f0
+ Call Trace:
+ <TASK>
+ br_mdb_flush_pgs net/bridge/br_mdb.c:1525 [inline]
+ br_mdb_flush net/bridge/br_mdb.c:1544 [inline]
+ br_mdb_del_bulk+0x5e2/0xb20 net/bridge/br_mdb.c:1561
+ rtnl_mdb_del+0x48a/0x640 net/core/rtnetlink.c:-1
+ rtnetlink_rcv_msg+0x77e/0xbe0 net/core/rtnetlink.c:6967
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ RIP: 0033:0x7fa45839aeb9
+ Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48
+ RSP: 002b:00007fa45921b028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+ RAX: ffffffffffffffda RBX: 00007fa458615fa0 RCX: 00007fa45839aeb9
+ RDX: 0000000000000000 RSI: 00002000000000c0 RDI: 0000000000000004
+ RBP: 00007fa458408c1f R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+ R13: 00007fa458616038 R14: 00007fa458615fa0 R15: 00007fff0b59fae8
+ </TASK>
+
+Fixes: b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port")
+Reported-by: syzbot+d5d1b7343531d17bd3c5@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/aYrWbRp83MQR1ife@debil/T/#t
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Link: https://patch.msgid.link/20260213070031.1400003-2-nikolay@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_multicast.c | 45 ++++++++++++++++-----------------------
+ 1 file changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index d55a4ab87837f..e9a7e65304017 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -244,14 +244,11 @@ br_multicast_port_vid_to_port_ctx(struct net_bridge_port *port, u16 vid)
+
+ lockdep_assert_held_once(&port->br->multicast_lock);
+
+- if (!br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED))
+- return NULL;
+-
+ /* Take RCU to access the vlan. */
+ rcu_read_lock();
+
+ vlan = br_vlan_find(nbp_vlan_group_rcu(port), vid);
+- if (vlan && !br_multicast_port_ctx_vlan_disabled(&vlan->port_mcast_ctx))
++ if (vlan)
+ pmctx = &vlan->port_mcast_ctx;
+
+ rcu_read_unlock();
+@@ -701,7 +698,10 @@ br_multicast_port_ngroups_inc_one(struct net_bridge_mcast_port *pmctx,
+ u32 max = READ_ONCE(pmctx->mdb_max_entries);
+ u32 n = READ_ONCE(pmctx->mdb_n_entries);
+
+- if (max && n >= max) {
++ /* enforce the max limit when it's a port pmctx or a port-vlan pmctx
++ * with snooping enabled
++ */
++ if (!br_multicast_port_ctx_vlan_disabled(pmctx) && max && n >= max) {
+ NL_SET_ERR_MSG_FMT_MOD(extack, "%s is already in %u groups, and mcast_max_groups=%u",
+ what, n, max);
+ return -E2BIG;
+@@ -736,9 +736,7 @@ static int br_multicast_port_ngroups_inc(struct net_bridge_port *port,
+ return err;
+ }
+
+- /* Only count on the VLAN context if VID is given, and if snooping on
+- * that VLAN is enabled.
+- */
++ /* Only count on the VLAN context if VID is given */
+ if (!group->vid)
+ return 0;
+
+@@ -2011,6 +2009,18 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port,
+ timer_setup(&pmctx->ip6_own_query.timer,
+ br_ip6_multicast_port_query_expired, 0);
+ #endif
++ /* initialize mdb_n_entries if a new port vlan is being created */
++ if (vlan) {
++ struct net_bridge_port_group *pg;
++ u32 n = 0;
++
++ spin_lock_bh(&port->br->multicast_lock);
++ hlist_for_each_entry(pg, &port->mglist, mglist)
++ if (pg->key.addr.vid == vlan->vid)
++ n++;
++ WRITE_ONCE(pmctx->mdb_n_entries, n);
++ spin_unlock_bh(&port->br->multicast_lock);
++ }
+ }
+
+ void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx)
+@@ -2094,25 +2104,6 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
+ br_ip4_multicast_add_router(brmctx, pmctx);
+ br_ip6_multicast_add_router(brmctx, pmctx);
+ }
+-
+- if (br_multicast_port_ctx_is_vlan(pmctx)) {
+- struct net_bridge_port_group *pg;
+- u32 n = 0;
+-
+- /* The mcast_n_groups counter might be wrong. First,
+- * BR_VLFLAG_MCAST_ENABLED is toggled before temporary entries
+- * are flushed, thus mcast_n_groups after the toggle does not
+- * reflect the true values. And second, permanent entries added
+- * while BR_VLFLAG_MCAST_ENABLED was disabled, are not reflected
+- * either. Thus we have to refresh the counter.
+- */
+-
+- hlist_for_each_entry(pg, &pmctx->port->mglist, mglist) {
+- if (pg->key.addr.vid == pmctx->vlan->vid)
+- n++;
+- }
+- WRITE_ONCE(pmctx->mdb_n_entries, n);
+- }
+ }
+
+ static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
+--
+2.51.0
+
--- /dev/null
+From 4296ed5d4fd5c80db2211f5e665c9cf912ef91d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 19:36:53 +0000
+Subject: net: do not delay zero-copy skbs in skb_attempt_defer_free()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 0943404b1f3b178e1e54386dadcbf4f2729c7762 ]
+
+After the blamed commit, TCP tx zero copy notifications could be
+arbitrarily delayed and cause regressions in applications waiting
+for them.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Fixes: e20dfbad8aab ("net: fix napi_consume_skb() with alien skbs")
+Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20260216193653.627617-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skbuff.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 61746c2b95f63..fa6209f45de9c 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -7231,10 +7231,15 @@ void skb_attempt_defer_free(struct sk_buff *skb)
+ {
+ struct skb_defer_node *sdn;
+ unsigned long defer_count;
+- int cpu = skb->alloc_cpu;
+ unsigned int defer_max;
+ bool kick;
++ int cpu;
+
++ /* zero copy notifications should not be delayed. */
++ if (skb_zcopy(skb))
++ goto nodefer;
++
++ cpu = skb->alloc_cpu;
+ if (cpu == raw_smp_processor_id() ||
+ WARN_ON_ONCE(cpu >= nr_cpu_ids) ||
+ !cpu_online(cpu)) {
+--
+2.51.0
+
--- /dev/null
+From a9c7fddbd583759f2f27a96d651c9a814a8130ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 15:27:33 +0800
+Subject: net: mctp: ensure our nlmsg responses are initialised
+
+From: Jeremy Kerr <jk@codeconstruct.com.au>
+
+[ Upstream commit a6a9bc544b675d8b5180f2718ec985ad267b5cbf ]
+
+Syed Faraz Abrar (@farazsth98) from Zellic, and Pumpkin (@u1f383) from
+DEVCORE Research Team working with Trend Micro Zero Day Initiative
+report that a RTM_GETNEIGH will return uninitalised data in the pad
+bytes of the ndmsg data.
+
+Ensure we're initialising the netlink data to zero, in the link, addr
+and neigh response messages.
+
+Fixes: 831119f88781 ("mctp: Add neighbour netlink interface")
+Fixes: 06d2f4c583a7 ("mctp: Add netlink route management")
+Fixes: 583be982d934 ("mctp: Add device handling and netlink interface")
+Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260209-dev-mctp-nlmsg-v1-1-f1e30c346a43@codeconstruct.com.au
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mctp/device.c | 1 +
+ net/mctp/neigh.c | 1 +
+ net/mctp/route.c | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/net/mctp/device.c b/net/mctp/device.c
+index 4d404edd7446e..04c5570bacff6 100644
+--- a/net/mctp/device.c
++++ b/net/mctp/device.c
+@@ -70,6 +70,7 @@ static int mctp_fill_addrinfo(struct sk_buff *skb,
+ return -EMSGSIZE;
+
+ hdr = nlmsg_data(nlh);
++ memset(hdr, 0, sizeof(*hdr));
+ hdr->ifa_family = AF_MCTP;
+ hdr->ifa_prefixlen = 0;
+ hdr->ifa_flags = 0;
+diff --git a/net/mctp/neigh.c b/net/mctp/neigh.c
+index 05b899f22d902..fc85f0e693014 100644
+--- a/net/mctp/neigh.c
++++ b/net/mctp/neigh.c
+@@ -218,6 +218,7 @@ static int mctp_fill_neigh(struct sk_buff *skb, u32 portid, u32 seq, int event,
+ return -EMSGSIZE;
+
+ hdr = nlmsg_data(nlh);
++ memset(hdr, 0, sizeof(*hdr));
+ hdr->ndm_family = AF_MCTP;
+ hdr->ndm_ifindex = dev->ifindex;
+ hdr->ndm_state = 0; // TODO other state bits?
+diff --git a/net/mctp/route.c b/net/mctp/route.c
+index 2ac4011a953ff..ecbbe4beb2133 100644
+--- a/net/mctp/route.c
++++ b/net/mctp/route.c
+@@ -1643,6 +1643,7 @@ static int mctp_fill_rtinfo(struct sk_buff *skb, struct mctp_route *rt,
+ return -EMSGSIZE;
+
+ hdr = nlmsg_data(nlh);
++ memset(hdr, 0, sizeof(*hdr));
+ hdr->rtm_family = AF_MCTP;
+
+ /* we use the _len fields as a number of EIDs, rather than
+--
+2.51.0
+
--- /dev/null
+From e8685a828e6c57390ca724f150464acb6e069137 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:29:01 +0200
+Subject: net/mlx5: Fix misidentification of write combining CQE during poll
+ loop
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit d451994ebc7d4392610bd4b2ab339b255deb4143 ]
+
+The write combining completion poll loop uses usleep_range() which can
+sleep much longer than requested due to scheduler latency. Under load,
+we witnessed a 20ms+ delay until the process was rescheduled, causing
+the jiffies based timeout to expire while the thread is sleeping.
+
+The original do-while loop structure (poll, sleep, check timeout) would
+exit without a final poll when waking after timeout, missing a CQE that
+arrived during sleep.
+
+Instead of the open-coded while loop, use the kernel's poll_timeout_us()
+which always performs an additional check after the sleep expiration,
+and is less error-prone.
+
+Note: poll_timeout_us() doesn't accept a sleep range, by passing 10
+sleep_us the sleep range effectively changes from 2-10 to 3-10 usecs.
+
+Fixes: d98995b4bf98 ("net/mlx5: Reimplement write combining test")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-4-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/wc.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wc.c b/drivers/net/ethernet/mellanox/mlx5/core/wc.c
+index 815a7c97d6b09..04d03be1bb775 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/wc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/wc.c
+@@ -2,6 +2,7 @@
+ // Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/mlx5/transobj.h>
+ #include "lib/clock.h"
+ #include "mlx5_core.h"
+@@ -15,7 +16,7 @@
+ #define TEST_WC_NUM_WQES 255
+ #define TEST_WC_LOG_CQ_SZ (order_base_2(TEST_WC_NUM_WQES))
+ #define TEST_WC_SQ_LOG_WQ_SZ TEST_WC_LOG_CQ_SZ
+-#define TEST_WC_POLLING_MAX_TIME_JIFFIES msecs_to_jiffies(100)
++#define TEST_WC_POLLING_MAX_TIME_USEC (100 * USEC_PER_MSEC)
+
+ struct mlx5_wc_cq {
+ /* data path - accessed per cqe */
+@@ -359,7 +360,6 @@ static int mlx5_wc_poll_cq(struct mlx5_wc_sq *sq)
+ static void mlx5_core_test_wc(struct mlx5_core_dev *mdev)
+ {
+ unsigned int offset = 0;
+- unsigned long expires;
+ struct mlx5_wc_sq *sq;
+ int i, err;
+
+@@ -389,13 +389,9 @@ static void mlx5_core_test_wc(struct mlx5_core_dev *mdev)
+
+ mlx5_wc_post_nop(sq, &offset, true);
+
+- expires = jiffies + TEST_WC_POLLING_MAX_TIME_JIFFIES;
+- do {
+- err = mlx5_wc_poll_cq(sq);
+- if (err)
+- usleep_range(2, 10);
+- } while (mdev->wc_state == MLX5_WC_STATE_UNINITIALIZED &&
+- time_is_after_jiffies(expires));
++ poll_timeout_us(mlx5_wc_poll_cq(sq),
++ mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED, 10,
++ TEST_WC_POLLING_MAX_TIME_USEC, false);
+
+ mlx5_wc_destroy_sq(sq);
+
+--
+2.51.0
+
--- /dev/null
+From 05ee32f7a14d6875e6a2405475f635d22c0d3196 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:28:59 +0200
+Subject: net/mlx5: Fix multiport device check over light SFs
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 47bf2e813817159f4d195be83a9b5a640ee6baec ]
+
+Driver is using num_vhca_ports capability to distinguish between
+multiport master device and multiport slave device. num_vhca_ports is a
+capability the driver sets according to the MAX num_vhca_ports
+capability reported by FW. On the other hand, light SFs doesn't set the
+above capbility.
+
+This leads to wrong results whenever light SFs is checking whether he is
+a multiport master or slave.
+
+Therefore, use the MAX capability to distinguish between master and
+slave devices.
+
+Fixes: e71383fb9cd1 ("net/mlx5: Light probe local SFs")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-2-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mlx5/driver.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index 1c54aa6f74fbc..1967d1c79139b 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -1281,12 +1281,12 @@ static inline bool mlx5_rl_is_supported(struct mlx5_core_dev *dev)
+ static inline int mlx5_core_is_mp_slave(struct mlx5_core_dev *dev)
+ {
+ return MLX5_CAP_GEN(dev, affiliate_nic_vport_criteria) &&
+- MLX5_CAP_GEN(dev, num_vhca_ports) <= 1;
++ MLX5_CAP_GEN_MAX(dev, num_vhca_ports) <= 1;
+ }
+
+ static inline int mlx5_core_is_mp_master(struct mlx5_core_dev *dev)
+ {
+- return MLX5_CAP_GEN(dev, num_vhca_ports) > 1;
++ return MLX5_CAP_GEN_MAX(dev, num_vhca_ports) > 1;
+ }
+
+ static inline int mlx5_core_mp_enabled(struct mlx5_core_dev *dev)
+--
+2.51.0
+
--- /dev/null
+From 3b8b6144afddccbf04a0eb8529b5c41bc6472f77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:29:03 +0200
+Subject: net/mlx5e: Fix deadlocks between devlink and netdev instance locks
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 83ac0304a2d77519dae1e54c9713cbe1aedf19c9 ]
+
+In the mentioned "Fixes" commit, various work tasks triggering devlink
+health reporter recovery were switched to use netdev_trylock to protect
+against concurrent tear down of the channels being recovered. But this
+had the side effect of introducing potential deadlocks because of
+incorrect lock ordering.
+
+The correct lock order is described by the init flow:
+probe_one -> mlx5_init_one (acquires devlink lock)
+-> mlx5_init_one_devl_locked -> mlx5_register_device
+-> mlx5_rescan_drivers_locked -...-> mlx5e_probe -> _mlx5e_probe
+-> register_netdev (acquires rtnl lock)
+-> register_netdevice (acquires netdev lock)
+=> devlink lock -> rtnl lock -> netdev lock.
+
+But in the current recovery flow, the order is wrong:
+mlx5e_tx_err_cqe_work (acquires netdev lock)
+-> mlx5e_reporter_tx_err_cqe -> mlx5e_health_report
+-> devlink_health_report (acquires devlink lock => boom!)
+-> devlink_health_reporter_recover
+-> mlx5e_tx_reporter_recover -> mlx5e_tx_reporter_recover_from_ctx
+-> mlx5e_tx_reporter_err_cqe_recover
+
+The same pattern exists in:
+mlx5e_reporter_rx_timeout
+mlx5e_reporter_tx_ptpsq_unhealthy
+mlx5e_reporter_tx_timeout
+
+Fix these by moving the netdev_trylock calls from the work handlers
+lower in the call stack, in the respective recovery functions, where
+they are actually necessary.
+
+Fixes: 8f7b00307bf1 ("net/mlx5e: Convert mlx5 netdevs to instance locking")
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-6-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/mellanox/mlx5/core/en/ptp.c | 14 -----
+ .../mellanox/mlx5/core/en/reporter_rx.c | 13 +++++
+ .../mellanox/mlx5/core/en/reporter_tx.c | 52 +++++++++++++++++--
+ .../net/ethernet/mellanox/mlx5/core/en_main.c | 40 --------------
+ 4 files changed, 61 insertions(+), 58 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+index 424f8a2728a3e..74660e7fe6748 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
+@@ -457,22 +457,8 @@ static void mlx5e_ptpsq_unhealthy_work(struct work_struct *work)
+ {
+ struct mlx5e_ptpsq *ptpsq =
+ container_of(work, struct mlx5e_ptpsq, report_unhealthy_work);
+- struct mlx5e_txqsq *sq = &ptpsq->txqsq;
+-
+- /* Recovering the PTP SQ means re-enabling NAPI, which requires the
+- * netdev instance lock. However, SQ closing has to wait for this work
+- * task to finish while also holding the same lock. So either get the
+- * lock or find that the SQ is no longer enabled and thus this work is
+- * not relevant anymore.
+- */
+- while (!netdev_trylock(sq->netdev)) {
+- if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state))
+- return;
+- msleep(20);
+- }
+
+ mlx5e_reporter_tx_ptpsq_unhealthy(ptpsq);
+- netdev_unlock(sq->netdev);
+ }
+
+ static int mlx5e_ptp_open_txqsq(struct mlx5e_ptp *c, u32 tisn,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
+index 0686fbdd5a059..6efb626b55062 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
+@@ -1,6 +1,8 @@
+ // SPDX-License-Identifier: GPL-2.0
+ // Copyright (c) 2019 Mellanox Technologies.
+
++#include <net/netdev_lock.h>
++
+ #include "health.h"
+ #include "params.h"
+ #include "txrx.h"
+@@ -177,6 +179,16 @@ static int mlx5e_rx_reporter_timeout_recover(void *ctx)
+ rq = ctx;
+ priv = rq->priv;
+
++ /* Acquire netdev instance lock to synchronize with channel close and
++ * reopen flows. Either successfully obtain the lock, or detect that
++ * channels are closing for another reason, making this work no longer
++ * necessary.
++ */
++ while (!netdev_trylock(rq->netdev)) {
++ if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &rq->priv->state))
++ return 0;
++ msleep(20);
++ }
+ mutex_lock(&priv->state_lock);
+
+ eq = rq->cq.mcq.eq;
+@@ -186,6 +198,7 @@ static int mlx5e_rx_reporter_timeout_recover(void *ctx)
+ clear_bit(MLX5E_SQ_STATE_ENABLED, &rq->icosq->state);
+
+ mutex_unlock(&priv->state_lock);
++ netdev_unlock(rq->netdev);
+
+ return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+index 9e2cf191ed308..9f6454102cf79 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+@@ -1,6 +1,8 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+ /* Copyright (c) 2019 Mellanox Technologies. */
+
++#include <net/netdev_lock.h>
++
+ #include "health.h"
+ #include "en/ptp.h"
+ #include "en/devlink.h"
+@@ -78,6 +80,18 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx)
+ if (!test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state))
+ return 0;
+
++ /* Recovering queues means re-enabling NAPI, which requires the netdev
++ * instance lock. However, SQ closing flows have to wait for work tasks
++ * to finish while also holding the netdev instance lock. So either get
++ * the lock or find that the SQ is no longer enabled and thus this work
++ * is not relevant anymore.
++ */
++ while (!netdev_trylock(dev)) {
++ if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state))
++ return 0;
++ msleep(20);
++ }
++
+ err = mlx5_core_query_sq_state(mdev, sq->sqn, &state);
+ if (err) {
+ netdev_err(dev, "Failed to query SQ 0x%x state. err = %d\n",
+@@ -113,9 +127,11 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx)
+ else
+ mlx5e_trigger_napi_sched(sq->cq.napi);
+
++ netdev_unlock(dev);
+ return 0;
+ out:
+ clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state);
++ netdev_unlock(dev);
+ return err;
+ }
+
+@@ -136,10 +152,24 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx)
+ sq = to_ctx->sq;
+ eq = sq->cq.mcq.eq;
+ priv = sq->priv;
++
++ /* Recovering the TX queues implies re-enabling NAPI, which requires
++ * the netdev instance lock.
++ * However, channel closing flows have to wait for this work to finish
++ * while holding the same lock. So either get the lock or find that
++ * channels are being closed for other reason and this work is not
++ * relevant anymore.
++ */
++ while (!netdev_trylock(sq->netdev)) {
++ if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state))
++ return 0;
++ msleep(20);
++ }
++
+ err = mlx5e_health_channel_eq_recover(sq->netdev, eq, sq->cq.ch_stats);
+ if (!err) {
+ to_ctx->status = 0; /* this sq recovered */
+- return err;
++ goto out;
+ }
+
+ mutex_lock(&priv->state_lock);
+@@ -147,7 +177,7 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx)
+ mutex_unlock(&priv->state_lock);
+ if (!err) {
+ to_ctx->status = 1; /* all channels recovered */
+- return err;
++ goto out;
+ }
+
+ to_ctx->status = err;
+@@ -155,7 +185,8 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx)
+ netdev_err(priv->netdev,
+ "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n",
+ err);
+-
++out:
++ netdev_unlock(sq->netdev);
+ return err;
+ }
+
+@@ -172,10 +203,22 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx)
+ return 0;
+
+ priv = ptpsq->txqsq.priv;
++ netdev = priv->netdev;
++
++ /* Recovering the PTP SQ means re-enabling NAPI, which requires the
++ * netdev instance lock. However, SQ closing has to wait for this work
++ * task to finish while also holding the same lock. So either get the
++ * lock or find that the SQ is no longer enabled and thus this work is
++ * not relevant anymore.
++ */
++ while (!netdev_trylock(netdev)) {
++ if (!test_bit(MLX5E_SQ_STATE_ENABLED, &ptpsq->txqsq.state))
++ return 0;
++ msleep(20);
++ }
+
+ mutex_lock(&priv->state_lock);
+ chs = &priv->channels;
+- netdev = priv->netdev;
+
+ carrier_ok = netif_carrier_ok(netdev);
+ netif_carrier_off(netdev);
+@@ -192,6 +235,7 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx)
+ netif_carrier_on(netdev);
+
+ mutex_unlock(&priv->state_lock);
++ netdev_unlock(netdev);
+
+ return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 4b2963bbe7ff4..e15e6fb4cd8ea 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -688,19 +688,7 @@ static void mlx5e_rq_timeout_work(struct work_struct *timeout_work)
+ struct mlx5e_rq,
+ rx_timeout_work);
+
+- /* Acquire netdev instance lock to synchronize with channel close and
+- * reopen flows. Either successfully obtain the lock, or detect that
+- * channels are closing for another reason, making this work no longer
+- * necessary.
+- */
+- while (!netdev_trylock(rq->netdev)) {
+- if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &rq->priv->state))
+- return;
+- msleep(20);
+- }
+-
+ mlx5e_reporter_rx_timeout(rq);
+- netdev_unlock(rq->netdev);
+ }
+
+ static int mlx5e_alloc_mpwqe_rq_drop_page(struct mlx5e_rq *rq)
+@@ -1997,20 +1985,7 @@ void mlx5e_tx_err_cqe_work(struct work_struct *recover_work)
+ struct mlx5e_txqsq *sq = container_of(recover_work, struct mlx5e_txqsq,
+ recover_work);
+
+- /* Recovering queues means re-enabling NAPI, which requires the netdev
+- * instance lock. However, SQ closing flows have to wait for work tasks
+- * to finish while also holding the netdev instance lock. So either get
+- * the lock or find that the SQ is no longer enabled and thus this work
+- * is not relevant anymore.
+- */
+- while (!netdev_trylock(sq->netdev)) {
+- if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state))
+- return;
+- msleep(20);
+- }
+-
+ mlx5e_reporter_tx_err_cqe(sq);
+- netdev_unlock(sq->netdev);
+ }
+
+ static struct dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode)
+@@ -5121,19 +5096,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work)
+ struct net_device *netdev = priv->netdev;
+ int i;
+
+- /* Recovering the TX queues implies re-enabling NAPI, which requires
+- * the netdev instance lock.
+- * However, channel closing flows have to wait for this work to finish
+- * while holding the same lock. So either get the lock or find that
+- * channels are being closed for other reason and this work is not
+- * relevant anymore.
+- */
+- while (!netdev_trylock(netdev)) {
+- if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state))
+- return;
+- msleep(20);
+- }
+-
+ for (i = 0; i < netdev->real_num_tx_queues; i++) {
+ struct netdev_queue *dev_queue =
+ netdev_get_tx_queue(netdev, i);
+@@ -5146,8 +5108,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work)
+ /* break if tried to reopened channels */
+ break;
+ }
+-
+- netdev_unlock(netdev);
+ }
+
+ static void mlx5e_tx_timeout(struct net_device *dev, unsigned int txqueue)
+--
+2.51.0
+
--- /dev/null
+From dd3f3086446e0cb06519b89e342bd30f68cd85c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:29:00 +0200
+Subject: net/mlx5e: Fix misidentification of ASO CQE during poll loop
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit ae3cb71e6c4dbda0c0b7c10475b744377813c7bd ]
+
+The ASO completion poll loop uses usleep_range() which can sleep much
+longer than requested due to scheduler latency. Under load, we witnessed
+a 20ms+ delay until the process was rescheduled, causing the jiffies
+based timeout to expire while the thread is sleeping.
+
+The original do-while loop structure (poll, sleep, check timeout) would
+exit without a final poll when waking after timeout, missing a CQE that
+arrived during sleep.
+
+Instead of the open-coded while loop, use the kernel's
+read_poll_timeout() which always performs an additional check after the
+sleep expiration, and is less error-prone.
+
+Note: read_poll_timeout() doesn't accept a sleep range, by passing 10
+sleep_us the sleep range effectively changes from 2-10 to 3-10 usecs.
+
+Fixes: 739cfa34518e ("net/mlx5: Make ASO poll CQ usable in atomic context")
+Fixes: 7e3fce82d945 ("net/mlx5e: Overcome slow response for first macsec ASO WQE")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-3-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c | 10 +++-------
+ .../net/ethernet/mellanox/mlx5/core/en_accel/macsec.c | 10 +++-------
+ 2 files changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c
+index 7819fb2972802..d5d9146efca67 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+ // Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+
++#include <linux/iopoll.h>
+ #include <linux/math64.h>
+ #include "lib/aso.h"
+ #include "en/tc/post_act.h"
+@@ -115,7 +116,6 @@ mlx5e_tc_meter_modify(struct mlx5_core_dev *mdev,
+ struct mlx5e_flow_meters *flow_meters;
+ u8 cir_man, cir_exp, cbs_man, cbs_exp;
+ struct mlx5_aso_wqe *aso_wqe;
+- unsigned long expires;
+ struct mlx5_aso *aso;
+ u64 rate, burst;
+ u8 ds_cnt;
+@@ -187,12 +187,8 @@ mlx5e_tc_meter_modify(struct mlx5_core_dev *mdev,
+ mlx5_aso_post_wqe(aso, true, &aso_wqe->ctrl);
+
+ /* With newer FW, the wait for the first ASO WQE is more than 2us, put the wait 10ms. */
+- expires = jiffies + msecs_to_jiffies(10);
+- do {
+- err = mlx5_aso_poll_cq(aso, true);
+- if (err)
+- usleep_range(2, 10);
+- } while (err && time_is_after_jiffies(expires));
++ read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC,
++ false, aso, true);
+ mutex_unlock(&flow_meters->aso_lock);
+
+ return err;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
+index 528b04d4de416..641cd3a2cdfab 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
+@@ -5,6 +5,7 @@
+ #include <linux/mlx5/mlx5_ifc.h>
+ #include <linux/xarray.h>
+ #include <linux/if_vlan.h>
++#include <linux/iopoll.h>
+
+ #include "en.h"
+ #include "lib/aso.h"
+@@ -1397,7 +1398,6 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac
+ struct mlx5e_macsec_aso *aso;
+ struct mlx5_aso_wqe *aso_wqe;
+ struct mlx5_aso *maso;
+- unsigned long expires;
+ int err;
+
+ aso = &macsec->aso;
+@@ -1411,12 +1411,8 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac
+ macsec_aso_build_wqe_ctrl_seg(aso, &aso_wqe->aso_ctrl, NULL);
+
+ mlx5_aso_post_wqe(maso, false, &aso_wqe->ctrl);
+- expires = jiffies + msecs_to_jiffies(10);
+- do {
+- err = mlx5_aso_poll_cq(maso, false);
+- if (err)
+- usleep_range(2, 10);
+- } while (err && time_is_after_jiffies(expires));
++ read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC,
++ false, maso, false);
+
+ if (err)
+ goto err_out;
+--
+2.51.0
+
--- /dev/null
+From d4ac37e80b0a0934dfd2d885807614043823c252 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:29:02 +0200
+Subject: net/mlx5e: MACsec, add ASO poll loop in macsec_aso_set_arm_event
+
+From: Gal Pressman <gal@nvidia.com>
+
+[ Upstream commit 9854b243ce4225328d0b32fdc998d35b6952d3f7 ]
+
+The macsec_aso_set_arm_event function calls mlx5_aso_poll_cq once
+without a retry loop. If the CQE is not immediately available after
+posting the WQE, the function fails unnecessarily.
+
+Use read_poll_timeout() to poll 3-10 usecs for CQE, consistent with
+other ASO polling code paths in the driver.
+
+Fixes: 739cfa34518e ("net/mlx5: Make ASO poll CQ usable in atomic context")
+Signed-off-by: Gal Pressman <gal@nvidia.com>
+Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-5-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
+index 641cd3a2cdfab..90b3bc5f9166f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
+@@ -1386,7 +1386,8 @@ static int macsec_aso_set_arm_event(struct mlx5_core_dev *mdev, struct mlx5e_mac
+ MLX5_ACCESS_ASO_OPC_MOD_MACSEC);
+ macsec_aso_build_ctrl(aso, &aso_wqe->aso_ctrl, in);
+ mlx5_aso_post_wqe(maso, false, &aso_wqe->ctrl);
+- err = mlx5_aso_poll_cq(maso, false);
++ read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC,
++ false, maso, false);
+ mutex_unlock(&aso->aso_lock);
+
+ return err;
+--
+2.51.0
+
--- /dev/null
+From 05e007304b5ffceaac011c53126b6e3019f5ee7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:29:04 +0200
+Subject: net/mlx5e: Use unsigned for mlx5e_get_max_num_channels
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Cosmin Ratiu <cratiu@nvidia.com>
+
+[ Upstream commit 57a94d4b22b0c6cc5d601e6b6238d78fb923d991 ]
+
+The max number of channels is always an unsigned int, use the correct
+type to fix compilation errors done with strict type checking, e.g.:
+
+error: call to ‘__compiletime_assert_1110’ declared with attribute
+ error: min(mlx5e_get_devlink_param_num_doorbells(mdev),
+ mlx5e_get_max_num_channels(mdev)) signedness error
+
+Fixes: 74a8dadac17e ("net/mlx5e: Preparations for supporting larger number of channels")
+Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
+Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-7-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+index ff4ab4691baf0..a06d08576fd4b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -179,7 +179,8 @@ static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size)
+ }
+
+ /* Use this function to get max num channels (rxqs/txqs) only to create netdev */
+-static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
++static inline unsigned int
++mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev)
+ {
+ return is_kdump_kernel() ?
+ MLX5E_MIN_NUM_CHANNELS :
+--
+2.51.0
+
--- /dev/null
+From 0b51c451393255c0595ecdca84e6fa322cd8ccb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:02 +0000
+Subject: net: mscc: ocelot: add missing lock protection in
+ ocelot_port_xmit_inj()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 026f6513c5880c2c89e38ad66bbec2868f978605 ]
+
+ocelot_port_xmit_inj() calls ocelot_can_inject() and
+ocelot_port_inject_frame() without holding the injection group lock.
+Both functions contain lockdep_assert_held() for the injection lock,
+and the correct caller felix_port_deferred_xmit() properly acquires
+the lock using ocelot_lock_inj_grp() before calling these functions.
+
+Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register
+injection path to fix the missing lock protection. The FDMA path is not
+affected as it uses its own locking mechanism.
+
+Fixes: c5e12ac3beb0 ("net: mscc: ocelot: serialize access to the injection/extraction groups")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-4-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index a7966c174b2e2..1b82693204640 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb,
+ int port = priv->port.index;
+ u32 rew_op = 0;
+
+- if (!ocelot_can_inject(ocelot, 0))
++ ocelot_lock_inj_grp(ocelot, 0);
++
++ if (!ocelot_can_inject(ocelot, 0)) {
++ ocelot_unlock_inj_grp(ocelot, 0);
+ return NETDEV_TX_BUSY;
++ }
+
+- if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) {
++ ocelot_unlock_inj_grp(ocelot, 0);
+ return NETDEV_TX_OK;
++ }
+
+ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
++ ocelot_unlock_inj_grp(ocelot, 0);
++
+ consume_skb(skb);
+
+ return NETDEV_TX_OK;
+--
+2.51.0
+
--- /dev/null
+From 9d464bc3152c8b046754165245286e9dae3b7a7e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:00 +0000
+Subject: net: mscc: ocelot: extract ocelot_xmit_timestamp() helper
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 29372f07f7969a2f0490793226ecf6c8c6bde0fa ]
+
+Extract the PTP timestamp handling logic from ocelot_port_xmit() into a
+separate ocelot_xmit_timestamp() helper function. This is a pure
+refactor with no behavioral change.
+
+The helper returns false if the skb was consumed (freed) due to a
+timestamp request failure, and true if the caller should continue with
+frame injection. The rew_op value is returned via pointer.
+
+This prepares for splitting ocelot_port_xmit() into separate FDMA and
+register injection paths in a subsequent patch.
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-2-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 36 ++++++++++++++++----------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index 469784d3a1a67..ef4a6c768de9b 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -551,33 +551,41 @@ static int ocelot_port_stop(struct net_device *dev)
+ return 0;
+ }
+
+-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port,
++ struct sk_buff *skb, u32 *rew_op)
+ {
+- struct ocelot_port_private *priv = netdev_priv(dev);
+- struct ocelot_port *ocelot_port = &priv->port;
+- struct ocelot *ocelot = ocelot_port->ocelot;
+- int port = priv->port.index;
+- u32 rew_op = 0;
+-
+- if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
+- !ocelot_can_inject(ocelot, 0))
+- return NETDEV_TX_BUSY;
+-
+- /* Check if timestamping is needed */
+ if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ struct sk_buff *clone = NULL;
+
+ if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) {
+ kfree_skb(skb);
+- return NETDEV_TX_OK;
++ return false;
+ }
+
+ if (clone)
+ OCELOT_SKB_CB(skb)->clone = clone;
+
+- rew_op = ocelot_ptp_rew_op(skb);
++ *rew_op = ocelot_ptp_rew_op(skb);
+ }
+
++ return true;
++}
++
++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ struct ocelot_port_private *priv = netdev_priv(dev);
++ struct ocelot_port *ocelot_port = &priv->port;
++ struct ocelot *ocelot = ocelot_port->ocelot;
++ int port = priv->port.index;
++ u32 rew_op = 0;
++
++ if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
++ !ocelot_can_inject(ocelot, 0))
++ return NETDEV_TX_BUSY;
++
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ return NETDEV_TX_OK;
++
+ if (static_branch_unlikely(&ocelot_fdma_enabled)) {
+ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
+ } else {
+--
+2.51.0
+
--- /dev/null
+From e6dc59b2a009d278e19f3b158045ad6daebc6cb2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:01 +0000
+Subject: net: mscc: ocelot: split xmit into FDMA and register injection paths
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 47f79b20e7fb885aa1623b759a68e8e27401ec4d ]
+
+Split ocelot_port_xmit() into two separate functions:
+- ocelot_port_xmit_fdma(): handles the FDMA injection path
+- ocelot_port_xmit_inj(): handles the register-based injection path
+
+The top-level ocelot_port_xmit() now dispatches to the appropriate
+function based on the ocelot_fdma_enabled static key.
+
+This is a pure refactor with no behavioral change. Separating the two
+code paths makes each one simpler and prepares for adding proper locking
+to the register injection path without affecting the FDMA path.
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-3-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 39 ++++++++++++++++++++------
+ 1 file changed, 30 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index ef4a6c768de9b..a7966c174b2e2 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -571,7 +571,25 @@ static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port,
+ return true;
+ }
+
+-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb,
++ struct net_device *dev)
++{
++ struct ocelot_port_private *priv = netdev_priv(dev);
++ struct ocelot_port *ocelot_port = &priv->port;
++ struct ocelot *ocelot = ocelot_port->ocelot;
++ int port = priv->port.index;
++ u32 rew_op = 0;
++
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ return NETDEV_TX_OK;
++
++ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
++
++ return NETDEV_TX_OK;
++}
++
++static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb,
++ struct net_device *dev)
+ {
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+@@ -579,24 +597,27 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
+ int port = priv->port.index;
+ u32 rew_op = 0;
+
+- if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
+- !ocelot_can_inject(ocelot, 0))
++ if (!ocelot_can_inject(ocelot, 0))
+ return NETDEV_TX_BUSY;
+
+ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
+ return NETDEV_TX_OK;
+
+- if (static_branch_unlikely(&ocelot_fdma_enabled)) {
+- ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
+- } else {
+- ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
++ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
+- consume_skb(skb);
+- }
++ consume_skb(skb);
+
+ return NETDEV_TX_OK;
+ }
+
++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ if (static_branch_unlikely(&ocelot_fdma_enabled))
++ return ocelot_port_xmit_fdma(skb, dev);
++
++ return ocelot_port_xmit_inj(skb, dev);
++}
++
+ enum ocelot_action_type {
+ OCELOT_MACT_LEARN,
+ OCELOT_MACT_FORGET,
+--
+2.51.0
+
--- /dev/null
+From abfd67c2ef742cc495495ba746b4ebac16be6b43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 11:54:54 +0100
+Subject: net: psp: select CONFIG_SKB_EXTENSIONS
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 6e980df452169f82674f2e650079c1fe0aee343d ]
+
+psp now uses skb extensions, failing to build when that is disabled:
+
+In file included from include/net/psp.h:7,
+ from net/psp/psp_sock.c:9:
+include/net/psp/functions.h: In function '__psp_skb_coalesce_diff':
+include/net/psp/functions.h:60:13: error: implicit declaration of function 'skb_ext_find'; did you mean 'skb_ext_copy'? [-Wimplicit-function-declaration]
+ 60 | a = skb_ext_find(one, SKB_EXT_PSP);
+ | ^~~~~~~~~~~~
+ | skb_ext_copy
+include/net/psp/functions.h:60:31: error: 'SKB_EXT_PSP' undeclared (first use in this function)
+ 60 | a = skb_ext_find(one, SKB_EXT_PSP);
+ | ^~~~~~~~~~~
+include/net/psp/functions.h:60:31: note: each undeclared identifier is reported only once for each function it appears in
+include/net/psp/functions.h: In function '__psp_sk_rx_policy_check':
+include/net/psp/functions.h:94:53: error: 'SKB_EXT_PSP' undeclared (first use in this function)
+ 94 | struct psp_skb_ext *pse = skb_ext_find(skb, SKB_EXT_PSP);
+ | ^~~~~~~~~~~
+net/psp/psp_sock.c: In function 'psp_sock_recv_queue_check':
+net/psp/psp_sock.c:164:41: error: 'SKB_EXT_PSP' undeclared (first use in this function)
+ 164 | pse = skb_ext_find(skb, SKB_EXT_PSP);
+ | ^~~~~~~~~~~
+
+Select the Kconfig symbol as we do from its other users.
+
+Fixes: 6b46ca260e22 ("net: psp: add socket security association code")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Daniel Zahka <daniel.zahka@gmail.com>
+Link: https://patch.msgid.link/20260216105500.2382181-1-arnd@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/psp/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/psp/Kconfig b/net/psp/Kconfig
+index 371e8771f3bd3..84d6b0f254606 100644
+--- a/net/psp/Kconfig
++++ b/net/psp/Kconfig
+@@ -6,6 +6,7 @@ config INET_PSP
+ bool "PSP Security Protocol support"
+ depends on INET
+ select SKB_DECRYPTED
++ select SKB_EXTENSIONS
+ select SOCK_VALIDATE_XMIT
+ help
+ Enable kernel support for the PSP Security Protocol (PSP).
+--
+2.51.0
+
--- /dev/null
+From 34a93041e44c9a70c80dbd9587e7ba466a428be5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:54:09 -0700
+Subject: net/rds: rds_sendmsg should not discard payload_len
+
+From: Allison Henderson <achender@kernel.org>
+
+[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ]
+
+Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with
+connection teardown") modifies rds_sendmsg to avoid enqueueing work
+while a tear down is in progress. However, it also changed the return
+value of rds_sendmsg to that of rds_send_xmit instead of the
+payload_len. This means the user may incorrectly receive errno values
+when it should have simply received a payload of 0 while the peer
+attempts a reconnections. So this patch corrects the teardown handling
+code to only use the out error path in that case, thus restoring the
+original payload_len return value.
+
+Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/send.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/rds/send.c b/net/rds/send.c
+index 0b3d0ef2f008b..071c5dca969a2 100644
+--- a/net/rds/send.c
++++ b/net/rds/send.c
+@@ -1382,9 +1382,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
+ else
+ queue_delayed_work(rds_wq, &cpath->cp_send_w, 1);
+ rcu_read_unlock();
++
++ if (ret)
++ goto out;
+ }
+- if (ret)
+- goto out;
++
+ rds_message_put(rm);
+
+ for (ind = 0; ind < vct.indx; ind++)
+--
+2.51.0
+
--- /dev/null
+From db79210d3cfdfb429354edceabb45545cbdf8129 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 12:56:39 +0100
+Subject: net: remove WARN_ON_ONCE when accessing forward path array
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ]
+
+Although unlikely, recent support for IPIP tunnels increases chances of
+reaching this WARN_ON_ONCE if userspace manages to build a sufficiently
+long forward path.
+
+Remove it.
+
+Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index ccef685023c29..f5e4040e08399 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -738,7 +738,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack)
+ {
+ int k = stack->num_paths++;
+
+- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX))
++ if (k >= NET_DEVICE_PATH_STACK_MAX)
+ return NULL;
+
+ return &stack->path[k];
+--
+2.51.0
+
--- /dev/null
+From 2d22b4b6af80acb6c3f2f1c15b5ed6c317c75da2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 14:44:01 +0100
+Subject: net: sparx5/lan969x: fix DWRR cost max to match hardware register
+ width
+
+From: Daniel Machon <daniel.machon@microchip.com>
+
+[ Upstream commit 6c28aa8dfdf24f554d4c5d4ff7d723a95360d94a ]
+
+DWRR (Deficit Weighted Round Robin) scheduling distributes bandwidth
+across traffic classes based on per-queue cost values, where lower cost
+means higher bandwidth share.
+
+The SPX5_DWRR_COST_MAX constant is 63 (6 bits) but the hardware
+register field HSCH_DWRR_ENTRY_DWRR_COST is GENMASK(24, 20), only
+5 bits wide (max 31). This causes sparx5_weight_to_hw_cost() to
+compute cost values that silently overflow via FIELD_PREP, resulting
+in incorrect scheduling weights.
+
+Set SPX5_DWRR_COST_MAX to 31 to match the hardware register width.
+
+Fixes: 211225428d65 ("net: microchip: sparx5: add support for offloading ets qdisc")
+Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260210-sparx5-fix-dwrr-cost-max-v1-1-58fbdbc25652@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
+index 1231a80335d7b..04f76f1e23f60 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
+@@ -35,7 +35,7 @@
+ #define SPX5_SE_BURST_UNIT 4096
+
+ /* Dwrr */
+-#define SPX5_DWRR_COST_MAX 63
++#define SPX5_DWRR_COST_MAX 31
+
+ struct sparx5_shaper {
+ u32 mode;
+--
+2.51.0
+
--- /dev/null
+From e02fc728c93e6dc41565ede185068699483d916b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 12:02:30 +0100
+Subject: net: sparx5/lan969x: fix PTP clock max_adj value
+
+From: Daniel Machon <daniel.machon@microchip.com>
+
+[ Upstream commit a49d2a2c37a6252c41cbdd505f9d1c58d5a3817a ]
+
+The max_adj field in ptp_clock_info tells userspace how much the PHC
+clock frequency can be adjusted. ptp4l reads this and will never request
+a correction larger than max_adj.
+
+On both sparx5 and lan969x the clock offset may never converge because
+the servo needs a frequency correction larger than the current max_adj
+of 200000 (200 ppm) allows. The servo rails at the max and the offset
+stays in the tens of microseconds.
+
+The hardware has no inherent max adjustment limit; frequency correction
+is done by writing a 64-bit clock period increment to CLK_PER_CFG, and
+the register has plenty of range. The 200000 value was just an overly
+conservative software limit. The max_adj is shared between sparx5 and
+lan969x, and the increased value is safe for both.
+
+Fix this by increasing max_adj to 10000000 (10000 ppm), giving the
+servo sufficient headroom.
+
+Fixes: 0933bd04047c ("net: sparx5: Add support for ptp clocks")
+Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260212-sparx5-ptp-max-adj-v2-v1-1-06b200e50ce3@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+index 2f168700f63c1..8b2e07821a950 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+@@ -576,7 +576,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+ static struct ptp_clock_info sparx5_ptp_clock_info = {
+ .owner = THIS_MODULE,
+ .name = "sparx5 ptp",
+- .max_adj = 200000,
++ .max_adj = 10000000,
+ .gettime64 = sparx5_ptp_gettime64,
+ .settime64 = sparx5_ptp_settime64,
+ .adjtime = sparx5_ptp_adjtime,
+--
+2.51.0
+
--- /dev/null
+From 69cf32f63b80b5e74681799a05e7ed0e00d274bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 17:50:32 -0500
+Subject: net: stmmac: fix oops when split header is enabled
+
+From: Jie Zhang <jzhang918@gmail.com>
+
+[ Upstream commit babab1b42ed68877ef669a08384becf281ad2582 ]
+
+For GMAC4, when split header is enabled, in some rare cases, the
+hardware does not fill buf2 of the first descriptor with payload.
+Thus we cannot assume buf2 is always fully filled if it is not
+the last descriptor. Otherwise, the length of buf2 of the second
+descriptor will be calculated wrong and cause an oops:
+
+Unable to handle kernel paging request at virtual address ffff00019246bfc0
+...
+x2 : 0000000000000040 x1 : ffff00019246bfc0 x0 : ffff00009246c000
+Call trace:
+ dcache_inval_poc+0x28/0x58 (P)
+ dma_direct_sync_single_for_cpu+0x38/0x6c
+ __dma_sync_single_for_cpu+0x34/0x6c
+ stmmac_napi_poll_rx+0x8f0/0xb60
+ __napi_poll.constprop.0+0x30/0x144
+ net_rx_action+0x160/0x274
+ handle_softirqs+0x1b8/0x1fc
+...
+
+To fix this, the PL bit-field in RDES3 register is used for all
+descriptors, whether it is the last descriptor or not.
+
+Fixes: ec222003bd94 ("net: stmmac: Prepare to add Split Header support")
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Jie Zhang <jie.zhang@analog.com>
+Link: https://patch.msgid.link/20260209225037.589130-1-jie.zhang@analog.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 ++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index a379221b96a34..f98fd254315f6 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5023,13 +5023,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv,
+ if (!priv->sph_active)
+ return 0;
+
+- /* Not last descriptor */
+- if (status & rx_not_ls)
++ /* For GMAC4, when split header is enabled, in some rare cases, the
++ * hardware does not fill buf2 of the first descriptor with payload.
++ * Thus we cannot assume buf2 is always fully filled if it is not
++ * the last descriptor. Otherwise, the length of buf2 of the second
++ * descriptor will be calculated wrong and cause an oops.
++ *
++ * If this is the last descriptor, 'plen' is the length of the
++ * received packet that was transferred to system memory.
++ * Otherwise, it is the accumulated number of bytes that have been
++ * transferred for the current packet.
++ *
++ * Thus 'plen - len' always gives the correct length of buf2.
++ */
++
++ /* Not GMAC4 and not last descriptor */
++ if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls))
+ return priv->dma_conf.dma_buf_sz;
+
++ /* GMAC4 or last descriptor */
+ plen = stmmac_get_rx_frame_len(priv, p, coe);
+
+- /* Last descriptor */
+ return plen - len;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 17faa6040df2fbe5ed71092774225b2360bd153f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 21:41:54 +0000
+Subject: net: usb: catc: enable basic endpoint checking
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ]
+
+catc_probe() fills three URBs with hardcoded endpoint pipes without
+verifying the endpoint descriptors:
+
+ - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX
+ - usb_rcvintpipe(usbdev, 2) for interrupt status
+
+A malformed USB device can present these endpoints with transfer types
+that differ from what the driver assumes.
+
+Add a catc_usb_ep enum for endpoint numbers, replacing magic constants
+throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints()
+calls after usb_set_interface() to verify endpoint types before use,
+rejecting devices with mismatched descriptors at probe time.
+
+Similar to
+- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking")
+which fixed the issue in rtl8150.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Suggested-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------
+ 1 file changed, 31 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
+index 6759388692f8e..3c824340ffb06 100644
+--- a/drivers/net/usb/catc.c
++++ b/drivers/net/usb/catc.c
+@@ -64,6 +64,16 @@ static const char driver_name[] = "catc";
+ #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */
+ #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */
+
++/*
++ * USB endpoints.
++ */
++
++enum catc_usb_ep {
++ CATC_USB_EP_CONTROL = 0,
++ CATC_USB_EP_BULK = 1,
++ CATC_USB_EP_INT_IN = 2,
++};
++
+ /*
+ * Control requests.
+ */
+@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ u8 broadcast[ETH_ALEN];
+ u8 *macbuf;
+ int pktsz, ret = -ENOMEM;
++ static const u8 bulk_ep_addr[] = {
++ CATC_USB_EP_BULK | USB_DIR_OUT,
++ CATC_USB_EP_BULK | USB_DIR_IN,
++ 0};
++ static const u8 int_ep_addr[] = {
++ CATC_USB_EP_INT_IN | USB_DIR_IN,
++ 0};
+
+ macbuf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if (!macbuf)
+@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ goto fail_mem;
+ }
+
++ /* Verify that all required endpoints are present */
++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
++ !usb_check_int_endpoints(intf, int_ep_addr)) {
++ dev_err(dev, "Missing or invalid endpoints\n");
++ ret = -ENODEV;
++ goto fail_mem;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct catc));
+ if (!netdev)
+ goto fail_mem;
+@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0),
+ NULL, NULL, 0, catc_ctrl_done, catc);
+
+- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1),
+- NULL, 0, catc_tx_done, catc);
++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK),
++ NULL, 0, catc_tx_done, catc);
+
+- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1),
+- catc->rx_buf, pktsz, catc_rx_done, catc);
++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK),
++ catc->rx_buf, pktsz, catc_rx_done, catc);
+
+- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2),
+- catc->irq_buf, 2, catc_irq_done, catc, 1);
++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN),
++ catc->irq_buf, 2, catc_irq_done, catc, 1);
+
+ if (!catc->is_f5u011) {
+ u32 *buf;
+--
+2.51.0
+
--- /dev/null
+From b5666a149bd8f8b8e83c2393102a0bf312b752a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 12:53:09 +0100
+Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ]
+
+Mihail Milev reports: Error: UNINIT (CWE-457):
+ net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl:
+ Declaring variable "tuple" without initializer.
+ net/netfilter/nf_conntrack_h323_main.c:1197:2:
+ uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find".
+ net/netfilter/nf_conntrack_expect.c:142:2:
+ read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash".
+
+ 1195| tuple.dst.protonum = IPPROTO_TCP;
+ 1196|
+ 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ 1198| if (exp && exp->master == ct)
+ 1199| return exp;
+
+Switch this to a C99 initialiser and set the l3num value.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_h323_main.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
+index 14f73872f6477..e35814d68ce30 100644
+--- a/net/netfilter/nf_conntrack_h323_main.c
++++ b/net/netfilter/nf_conntrack_h323_main.c
+@@ -1186,13 +1186,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
+ {
+ struct net *net = nf_ct_net(ct);
+ struct nf_conntrack_expect *exp;
+- struct nf_conntrack_tuple tuple;
++ struct nf_conntrack_tuple tuple = {
++ .src.l3num = nf_ct_l3num(ct),
++ .dst.protonum = IPPROTO_TCP,
++ .dst.u.tcp.port = port,
++ };
+
+- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3));
+- tuple.src.u.tcp.port = 0;
+ memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3));
+- tuple.dst.u.tcp.port = port;
+- tuple.dst.protonum = IPPROTO_TCP;
+
+ exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ if (exp && exp->master == ct)
+--
+2.51.0
+
--- /dev/null
+From dc2035a560ba3eab1ba1a2c9e9e9b5d7777e2062 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 21:14:40 +0900
+Subject: netfilter: nf_tables: fix use-after-free in nf_tables_addchain()
+
+From: Inseo An <y0un9sa@gmail.com>
+
+[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ]
+
+nf_tables_addchain() publishes the chain to table->chains via
+list_add_tail_rcu() (in nft_chain_add()) before registering hooks.
+If nf_tables_register_hook() then fails, the error path calls
+nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy()
+with no RCU grace period in between.
+
+This creates two use-after-free conditions:
+
+ 1) Control-plane: nf_tables_dump_chains() traverses table->chains
+ under rcu_read_lock(). A concurrent dump can still be walking
+ the chain when the error path frees it.
+
+ 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly
+ installs the IPv4 hook before IPv6 registration fails. Packets
+ entering nft_do_chain() via the transient IPv4 hook can still be
+ dereferencing chain->blob_gen_X when the error path frees the
+ chain.
+
+Add synchronize_rcu() between nft_chain_del() and the chain destroy
+so that all RCU readers -- both dump threads and in-flight packet
+evaluation -- have finished before the chain is freed.
+
+Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain")
+Signed-off-by: Inseo An <y0un9sa@gmail.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index f807183235e79..8dae197c7fafb 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -2822,6 +2822,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 policy,
+
+ err_register_hook:
+ nft_chain_del(chain);
++ synchronize_rcu();
+ err_chain_add:
+ nft_trans_destroy(trans);
+ err_trans:
+--
+2.51.0
+
--- /dev/null
+From 22620c07e4055d9be237d5edb1cf6d1413a0edc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 14:26:36 -0600
+Subject: netfilter: nf_tables: revert commit_mutex usage in reset path
+
+From: Brian Witte <brianwitte@mailfence.com>
+
+[ Upstream commit 7f261bb906bf527c4a6e2a646e2d5f3679f2a8bc ]
+
+It causes circular lock dependency between commit_mutex, nfnl_subsys_ipset
+and nlk_cb_mutex when nft reset, ipset list, and iptables-nft with '-m set'
+rule run at the same time.
+
+Previous patches made it safe to run individual reset handlers concurrently
+so commit_mutex is no longer required to prevent this.
+
+Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
+Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
+Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
+Link: https://lore.kernel.org/all/aUh_3mVRV8OrGsVo@strlen.de/
+Reported-by: <syzbot+ff16b505ec9152e5f448@syzkaller.appspotmail.com>
+Closes: https://syzkaller.appspot.com/bug?extid=ff16b505ec9152e5f448
+Signed-off-by: Brian Witte <brianwitte@mailfence.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 248 ++++++----------------------------
+ 1 file changed, 42 insertions(+), 206 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index daef07ee09427..f807183235e79 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -3900,23 +3900,6 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
+ return skb->len;
+ }
+
+-static int nf_tables_dumpreset_rules(struct sk_buff *skb,
+- struct netlink_callback *cb)
+-{
+- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
+- int ret;
+-
+- /* Mutex is held is to prevent that two concurrent dump-and-reset calls
+- * do not underrun counters and quotas. The commit_mutex is used for
+- * the lack a better lock, this is not transaction path.
+- */
+- mutex_lock(&nft_net->commit_mutex);
+- ret = nf_tables_dump_rules(skb, cb);
+- mutex_unlock(&nft_net->commit_mutex);
+-
+- return ret;
+-}
+-
+ static int nf_tables_dump_rules_start(struct netlink_callback *cb)
+ {
+ struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
+@@ -3936,16 +3919,10 @@ static int nf_tables_dump_rules_start(struct netlink_callback *cb)
+ return -ENOMEM;
+ }
+ }
+- return 0;
+-}
+-
+-static int nf_tables_dumpreset_rules_start(struct netlink_callback *cb)
+-{
+- struct nft_rule_dump_ctx *ctx = (void *)cb->ctx;
+-
+- ctx->reset = true;
++ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
++ ctx->reset = true;
+
+- return nf_tables_dump_rules_start(cb);
++ return 0;
+ }
+
+ static int nf_tables_dump_rules_done(struct netlink_callback *cb)
+@@ -4011,6 +3988,8 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
+ u32 portid = NETLINK_CB(skb).portid;
+ struct net *net = info->net;
+ struct sk_buff *skb2;
++ bool reset = false;
++ char *buf;
+
+ if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+ struct netlink_dump_control c = {
+@@ -4024,47 +4003,16 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
+ return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+ }
+
+- skb2 = nf_tables_getrule_single(portid, info, nla, false);
+- if (IS_ERR(skb2))
+- return PTR_ERR(skb2);
+-
+- return nfnetlink_unicast(skb2, net, portid);
+-}
+-
+-static int nf_tables_getrule_reset(struct sk_buff *skb,
+- const struct nfnl_info *info,
+- const struct nlattr * const nla[])
+-{
+- struct nftables_pernet *nft_net = nft_pernet(info->net);
+- u32 portid = NETLINK_CB(skb).portid;
+- struct net *net = info->net;
+- struct sk_buff *skb2;
+- char *buf;
+-
+- if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+- struct netlink_dump_control c = {
+- .start= nf_tables_dumpreset_rules_start,
+- .dump = nf_tables_dumpreset_rules,
+- .done = nf_tables_dump_rules_done,
+- .module = THIS_MODULE,
+- .data = (void *)nla,
+- };
+-
+- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+- }
+-
+- if (!try_module_get(THIS_MODULE))
+- return -EINVAL;
+- rcu_read_unlock();
+- mutex_lock(&nft_net->commit_mutex);
+- skb2 = nf_tables_getrule_single(portid, info, nla, true);
+- mutex_unlock(&nft_net->commit_mutex);
+- rcu_read_lock();
+- module_put(THIS_MODULE);
++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET)
++ reset = true;
+
++ skb2 = nf_tables_getrule_single(portid, info, nla, reset);
+ if (IS_ERR(skb2))
+ return PTR_ERR(skb2);
+
++ if (!reset)
++ return nfnetlink_unicast(skb2, net, portid);
++
+ buf = kasprintf(GFP_ATOMIC, "%.*s:%u",
+ nla_len(nla[NFTA_RULE_TABLE]),
+ (char *)nla_data(nla[NFTA_RULE_TABLE]),
+@@ -6323,6 +6271,10 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
+ nla_nest_end(skb, nest);
+ nlmsg_end(skb, nlh);
+
++ if (dump_ctx->reset && args.iter.count > args.iter.skip)
++ audit_log_nft_set_reset(table, cb->seq,
++ args.iter.count - args.iter.skip);
++
+ rcu_read_unlock();
+
+ if (args.iter.err && args.iter.err != -EMSGSIZE)
+@@ -6338,26 +6290,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
+ return -ENOSPC;
+ }
+
+-static int nf_tables_dumpreset_set(struct sk_buff *skb,
+- struct netlink_callback *cb)
+-{
+- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
+- struct nft_set_dump_ctx *dump_ctx = cb->data;
+- int ret, skip = cb->args[0];
+-
+- mutex_lock(&nft_net->commit_mutex);
+-
+- ret = nf_tables_dump_set(skb, cb);
+-
+- if (cb->args[0] > skip)
+- audit_log_nft_set_reset(dump_ctx->ctx.table, cb->seq,
+- cb->args[0] - skip);
+-
+- mutex_unlock(&nft_net->commit_mutex);
+-
+- return ret;
+-}
+-
+ static int nf_tables_dump_set_start(struct netlink_callback *cb)
+ {
+ struct nft_set_dump_ctx *dump_ctx = cb->data;
+@@ -6601,8 +6533,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ {
+ struct netlink_ext_ack *extack = info->extack;
+ struct nft_set_dump_ctx dump_ctx;
++ int rem, err = 0, nelems = 0;
++ struct net *net = info->net;
+ struct nlattr *attr;
+- int rem, err = 0;
++ bool reset = false;
++
++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETSETELEM_RESET)
++ reset = true;
+
+ if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+ struct netlink_dump_control c = {
+@@ -6612,7 +6549,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ .module = THIS_MODULE,
+ };
+
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false);
++ err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset);
+ if (err)
+ return err;
+
+@@ -6623,75 +6560,21 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
+ if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
+ return -EINVAL;
+
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false);
++ err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset);
+ if (err)
+ return err;
+
+ nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
+- err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, false);
+- if (err < 0) {
+- NL_SET_BAD_ATTR(extack, attr);
+- break;
+- }
+- }
+-
+- return err;
+-}
+-
+-static int nf_tables_getsetelem_reset(struct sk_buff *skb,
+- const struct nfnl_info *info,
+- const struct nlattr * const nla[])
+-{
+- struct nftables_pernet *nft_net = nft_pernet(info->net);
+- struct netlink_ext_ack *extack = info->extack;
+- struct nft_set_dump_ctx dump_ctx;
+- int rem, err = 0, nelems = 0;
+- struct nlattr *attr;
+-
+- if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+- struct netlink_dump_control c = {
+- .start = nf_tables_dump_set_start,
+- .dump = nf_tables_dumpreset_set,
+- .done = nf_tables_dump_set_done,
+- .module = THIS_MODULE,
+- };
+-
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true);
+- if (err)
+- return err;
+-
+- c.data = &dump_ctx;
+- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+- }
+-
+- if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
+- return -EINVAL;
+-
+- if (!try_module_get(THIS_MODULE))
+- return -EINVAL;
+- rcu_read_unlock();
+- mutex_lock(&nft_net->commit_mutex);
+- rcu_read_lock();
+-
+- err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true);
+- if (err)
+- goto out_unlock;
+-
+- nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
+- err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, true);
++ err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, reset);
+ if (err < 0) {
+ NL_SET_BAD_ATTR(extack, attr);
+ break;
+ }
+ nelems++;
+ }
+- audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(info->net), nelems);
+-
+-out_unlock:
+- rcu_read_unlock();
+- mutex_unlock(&nft_net->commit_mutex);
+- rcu_read_lock();
+- module_put(THIS_MODULE);
++ if (reset)
++ audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(net),
++ nelems);
+
+ return err;
+ }
+@@ -8562,19 +8445,6 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
+ return skb->len;
+ }
+
+-static int nf_tables_dumpreset_obj(struct sk_buff *skb,
+- struct netlink_callback *cb)
+-{
+- struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk));
+- int ret;
+-
+- mutex_lock(&nft_net->commit_mutex);
+- ret = nf_tables_dump_obj(skb, cb);
+- mutex_unlock(&nft_net->commit_mutex);
+-
+- return ret;
+-}
+-
+ static int nf_tables_dump_obj_start(struct netlink_callback *cb)
+ {
+ struct nft_obj_dump_ctx *ctx = (void *)cb->ctx;
+@@ -8591,16 +8461,10 @@ static int nf_tables_dump_obj_start(struct netlink_callback *cb)
+ if (nla[NFTA_OBJ_TYPE])
+ ctx->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
+
+- return 0;
+-}
+-
+-static int nf_tables_dumpreset_obj_start(struct netlink_callback *cb)
+-{
+- struct nft_obj_dump_ctx *ctx = (void *)cb->ctx;
+-
+- ctx->reset = true;
++ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
++ ctx->reset = true;
+
+- return nf_tables_dump_obj_start(cb);
++ return 0;
+ }
+
+ static int nf_tables_dump_obj_done(struct netlink_callback *cb)
+@@ -8662,42 +8526,16 @@ nf_tables_getobj_single(u32 portid, const struct nfnl_info *info,
+ static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info,
+ const struct nlattr * const nla[])
+ {
+- u32 portid = NETLINK_CB(skb).portid;
+- struct sk_buff *skb2;
+-
+- if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+- struct netlink_dump_control c = {
+- .start = nf_tables_dump_obj_start,
+- .dump = nf_tables_dump_obj,
+- .done = nf_tables_dump_obj_done,
+- .module = THIS_MODULE,
+- .data = (void *)nla,
+- };
+-
+- return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+- }
+-
+- skb2 = nf_tables_getobj_single(portid, info, nla, false);
+- if (IS_ERR(skb2))
+- return PTR_ERR(skb2);
+-
+- return nfnetlink_unicast(skb2, info->net, portid);
+-}
+-
+-static int nf_tables_getobj_reset(struct sk_buff *skb,
+- const struct nfnl_info *info,
+- const struct nlattr * const nla[])
+-{
+- struct nftables_pernet *nft_net = nft_pernet(info->net);
+ u32 portid = NETLINK_CB(skb).portid;
+ struct net *net = info->net;
+ struct sk_buff *skb2;
++ bool reset = false;
+ char *buf;
+
+ if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
+ struct netlink_dump_control c = {
+- .start = nf_tables_dumpreset_obj_start,
+- .dump = nf_tables_dumpreset_obj,
++ .start = nf_tables_dump_obj_start,
++ .dump = nf_tables_dump_obj,
+ .done = nf_tables_dump_obj_done,
+ .module = THIS_MODULE,
+ .data = (void *)nla,
+@@ -8706,18 +8544,16 @@ static int nf_tables_getobj_reset(struct sk_buff *skb,
+ return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c);
+ }
+
+- if (!try_module_get(THIS_MODULE))
+- return -EINVAL;
+- rcu_read_unlock();
+- mutex_lock(&nft_net->commit_mutex);
+- skb2 = nf_tables_getobj_single(portid, info, nla, true);
+- mutex_unlock(&nft_net->commit_mutex);
+- rcu_read_lock();
+- module_put(THIS_MODULE);
++ if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
++ reset = true;
+
++ skb2 = nf_tables_getobj_single(portid, info, nla, reset);
+ if (IS_ERR(skb2))
+ return PTR_ERR(skb2);
+
++ if (!reset)
++ return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
++
+ buf = kasprintf(GFP_ATOMIC, "%.*s:%u",
+ nla_len(nla[NFTA_OBJ_TABLE]),
+ (char *)nla_data(nla[NFTA_OBJ_TABLE]),
+@@ -10035,7 +9871,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
+ .policy = nft_rule_policy,
+ },
+ [NFT_MSG_GETRULE_RESET] = {
+- .call = nf_tables_getrule_reset,
++ .call = nf_tables_getrule,
+ .type = NFNL_CB_RCU,
+ .attr_count = NFTA_RULE_MAX,
+ .policy = nft_rule_policy,
+@@ -10089,7 +9925,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
+ .policy = nft_set_elem_list_policy,
+ },
+ [NFT_MSG_GETSETELEM_RESET] = {
+- .call = nf_tables_getsetelem_reset,
++ .call = nf_tables_getsetelem,
+ .type = NFNL_CB_RCU,
+ .attr_count = NFTA_SET_ELEM_LIST_MAX,
+ .policy = nft_set_elem_list_policy,
+@@ -10135,7 +9971,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
+ .policy = nft_obj_policy,
+ },
+ [NFT_MSG_GETOBJ_RESET] = {
+- .call = nf_tables_getobj_reset,
++ .call = nf_tables_getobj,
+ .type = NFNL_CB_RCU,
+ .attr_count = NFTA_OBJ_MAX,
+ .policy = nft_obj_policy,
+--
+2.51.0
+
--- /dev/null
+From 5839cc0233f39ee4170ec88e5062dbf952ddbee4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 14:26:37 -0600
+Subject: netfilter: nft_counter: serialize reset with spinlock
+
+From: Brian Witte <brianwitte@mailfence.com>
+
+[ Upstream commit 779c60a5190c42689534172f4b49e927c9959e4e ]
+
+Add a global static spinlock to serialize counter fetch+reset
+operations, preventing concurrent dump-and-reset from underrunning
+values.
+
+The lock is taken before fetching the total so that two parallel
+resets cannot both read the same counter values and then both
+subtract them.
+
+A global lock is used for simplicity since resets are infrequent.
+If this becomes a bottleneck, it can be replaced with a per-net
+lock later.
+
+Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
+Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
+Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
+Suggested-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Brian Witte <brianwitte@mailfence.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_counter.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
+index 0d70325280cc5..169ae93688bcc 100644
+--- a/net/netfilter/nft_counter.c
++++ b/net/netfilter/nft_counter.c
+@@ -32,6 +32,9 @@ struct nft_counter_percpu_priv {
+
+ static DEFINE_PER_CPU(struct u64_stats_sync, nft_counter_sync);
+
++/* control plane only: sync fetch+reset */
++static DEFINE_SPINLOCK(nft_counter_lock);
++
+ static inline void nft_counter_do_eval(struct nft_counter_percpu_priv *priv,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
+@@ -148,13 +151,25 @@ static void nft_counter_fetch(struct nft_counter_percpu_priv *priv,
+ }
+ }
+
++static void nft_counter_fetch_and_reset(struct nft_counter_percpu_priv *priv,
++ struct nft_counter_tot *total)
++{
++ spin_lock(&nft_counter_lock);
++ nft_counter_fetch(priv, total);
++ nft_counter_reset(priv, total);
++ spin_unlock(&nft_counter_lock);
++}
++
+ static int nft_counter_do_dump(struct sk_buff *skb,
+ struct nft_counter_percpu_priv *priv,
+ bool reset)
+ {
+ struct nft_counter_tot total;
+
+- nft_counter_fetch(priv, &total);
++ if (unlikely(reset))
++ nft_counter_fetch_and_reset(priv, &total);
++ else
++ nft_counter_fetch(priv, &total);
+
+ if (nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes),
+ NFTA_COUNTER_PAD) ||
+@@ -162,9 +177,6 @@ static int nft_counter_do_dump(struct sk_buff *skb,
+ NFTA_COUNTER_PAD))
+ goto nla_put_failure;
+
+- if (reset)
+- nft_counter_reset(priv, &total);
+-
+ return 0;
+
+ nla_put_failure:
+--
+2.51.0
+
--- /dev/null
+From 9489b2a10db3829805c9344dace56873d914a00d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 14:26:38 -0600
+Subject: netfilter: nft_quota: use atomic64_xchg for reset
+
+From: Brian Witte <brianwitte@mailfence.com>
+
+[ Upstream commit 30c4d7fb59ac4c8d7fa7937df11eed10b368fa11 ]
+
+Use atomic64_xchg() to atomically read and zero the consumed value
+on reset, which is simpler than the previous read+sub pattern and
+doesn't require lock serialization.
+
+Fixes: bd662c4218f9 ("netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests")
+Fixes: 3d483faa6663 ("netfilter: nf_tables: Add locking for NFT_MSG_GETSETELEM_RESET requests")
+Fixes: 3cb03edb4de3 ("netfilter: nf_tables: Add locking for NFT_MSG_GETRULE_RESET requests")
+Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Brian Witte <brianwitte@mailfence.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_quota.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c
+index df0798da2329b..cb6c0e04ff675 100644
+--- a/net/netfilter/nft_quota.c
++++ b/net/netfilter/nft_quota.c
+@@ -140,11 +140,16 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
+ u64 consumed, consumed_cap, quota;
+ u32 flags = priv->flags;
+
+- /* Since we inconditionally increment consumed quota for each packet
++ /* Since we unconditionally increment consumed quota for each packet
+ * that we see, don't go over the quota boundary in what we send to
+ * userspace.
+ */
+- consumed = atomic64_read(priv->consumed);
++ if (reset) {
++ consumed = atomic64_xchg(priv->consumed, 0);
++ clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
++ } else {
++ consumed = atomic64_read(priv->consumed);
++ }
+ quota = atomic64_read(&priv->quota);
+ if (consumed >= quota) {
+ consumed_cap = quota;
+@@ -160,10 +165,6 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
+ nla_put_be32(skb, NFTA_QUOTA_FLAGS, htonl(flags)))
+ goto nla_put_failure;
+
+- if (reset) {
+- atomic64_sub(consumed, priv->consumed);
+- clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
+- }
+ return 0;
+
+ nla_put_failure:
+--
+2.51.0
+
--- /dev/null
+From d261cc46e7d42d4a85a45f56a8b0b09a1509769d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 21:28:46 +0800
+Subject: objpool: fix the overestimation of object pooling metadata size
+
+From: zhouwenhao <zhouwenhao7600@gmail.com>
+
+[ Upstream commit 5ed4b6b37c647d168ae31035b3f61b705997e043 ]
+
+objpool uses struct objpool_head to store metadata information, and its
+cpu_slots member points to an array of pointers that store the addresses
+of the percpu ring arrays. However, the memory size allocated during the
+initialization of cpu_slots is nr_cpu_ids * sizeof(struct objpool_slot).
+On a 64-bit machine, the size of struct objpool_slot is 16 bytes, which is
+twice the size of the actual pointer required, and the extra memory is
+never be used, resulting in a waste of memory. Therefore, the memory size
+required for cpu_slots needs to be corrected.
+
+Link: https://lkml.kernel.org/r/20260202132846.68257-1-zhouwenhao7600@gmail.com
+Fixes: b4edb8d2d464 ("lib: objpool added: ring-array based lockless MPMC")
+Signed-off-by: zhouwenhao <zhouwenhao7600@gmail.com>
+Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
+Cc: Matt Wu <wuqiang.matt@bytedance.com>
+Cc: wuqiang.matt <wuqiang.matt@bytedance.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ lib/objpool.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/objpool.c b/lib/objpool.c
+index b998b720c7329..d98fadf1de169 100644
+--- a/lib/objpool.c
++++ b/lib/objpool.c
+@@ -142,7 +142,7 @@ int objpool_init(struct objpool_head *pool, int nr_objs, int object_size,
+ pool->gfp = gfp & ~__GFP_ZERO;
+ pool->context = context;
+ pool->release = release;
+- slot_size = nr_cpu_ids * sizeof(struct objpool_slot);
++ slot_size = nr_cpu_ids * sizeof(struct objpool_slot *);
+ pool->cpu_slots = kzalloc(slot_size, pool->gfp);
+ if (!pool->cpu_slots)
+ return -ENOMEM;
+--
+2.51.0
+
--- /dev/null
+From ecf24242b1500171589822cfce1a5ee8248f2f60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:33:38 +0530
+Subject: octeontx2-af: Fix default entries mcam entry action
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ]
+
+As per design, AF should update the default MCAM action only when
+mcam_index is -1. A bug in the previous patch caused default entries
+to be changed even when the request was not for them.
+
+Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++---------
+ 1 file changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+index c7c70429eb6c1..8658cb2143dfc 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+@@ -1042,32 +1042,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
+ rvu_write64(rvu, blkaddr,
+ NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action);
+
+- /* update the VF flow rule action with the VF default entry action */
+- if (mcam_index < 0)
+- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
+- *(u64 *)&action);
+-
+ /* update the action change in default rule */
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+ if (pfvf->def_ucast_rule)
+ pfvf->def_ucast_rule->rx_action = action;
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_PROMISC_ENTRY);
++ if (mcam_index < 0) {
++ /* update the VF flow rule action with the VF default
++ * entry action
++ */
++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
++ *(u64 *)&action);
+
+- /* If PF's promiscuous entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_PROMISC_ENTRY);
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_ALLMULTI_ENTRY);
+- /* If PF's allmulti entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ /* If PF's promiscuous entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_ALLMULTI_ENTRY);
++ /* If PF's allmulti entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++ }
+ }
+
+ void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc,
+--
+2.51.0
+
--- /dev/null
+From b6473ab1f0324021e57ca7140a52fa59c7d323db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jan 2026 18:32:49 +0100
+Subject: ovpn: fix possible use-after-free in ovpn_net_xmit
+
+From: Ralf Lici <ralf@mandelbit.com>
+
+[ Upstream commit a5ec7baa44ea3a1d6aa0ca31c0ad82edf9affe41 ]
+
+When building the skb_list in ovpn_net_xmit, skb_share_check will free
+the original skb if it is shared. The current implementation continues
+to use the stale skb pointer for subsequent operations:
+- peer lookup,
+- skb_dst_drop (even though all segments produced by skb_gso_segment
+ will have a dst attached),
+- ovpn_peer_stats_increment_tx.
+
+Fix this by moving the peer lookup and skb_dst_drop before segmentation
+so that the original skb is still valid when used. Return early if all
+segments fail skb_share_check and the list ends up empty.
+Also switch ovpn_peer_stats_increment_tx to use skb_list.next; the next
+patch fixes the stats logic.
+
+Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)")
+Signed-off-by: Ralf Lici <ralf@mandelbit.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ovpn/io.c | 52 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 31 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c
+index 3e9e7f8444b34..f70c58b10599b 100644
+--- a/drivers/net/ovpn/io.c
++++ b/drivers/net/ovpn/io.c
+@@ -365,7 +365,27 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
+ /* verify IP header size in network packet */
+ proto = ovpn_ip_check_protocol(skb);
+ if (unlikely(!proto || skb->protocol != proto))
+- goto drop;
++ goto drop_no_peer;
++
++ /* retrieve peer serving the destination IP of this packet */
++ peer = ovpn_peer_get_by_dst(ovpn, skb);
++ if (unlikely(!peer)) {
++ switch (skb->protocol) {
++ case htons(ETH_P_IP):
++ net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n",
++ netdev_name(ovpn->dev),
++ &ip_hdr(skb)->daddr);
++ break;
++ case htons(ETH_P_IPV6):
++ net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n",
++ netdev_name(ovpn->dev),
++ &ipv6_hdr(skb)->daddr);
++ break;
++ }
++ goto drop_no_peer;
++ }
++ /* dst was needed for peer selection - it can now be dropped */
++ skb_dst_drop(skb);
+
+ if (skb_is_gso(skb)) {
+ segments = skb_gso_segment(skb, 0);
+@@ -396,34 +416,24 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
+
+ __skb_queue_tail(&skb_list, curr);
+ }
+- skb_list.prev->next = NULL;
+
+- /* retrieve peer serving the destination IP of this packet */
+- peer = ovpn_peer_get_by_dst(ovpn, skb);
+- if (unlikely(!peer)) {
+- switch (skb->protocol) {
+- case htons(ETH_P_IP):
+- net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n",
+- netdev_name(ovpn->dev),
+- &ip_hdr(skb)->daddr);
+- break;
+- case htons(ETH_P_IPV6):
+- net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n",
+- netdev_name(ovpn->dev),
+- &ipv6_hdr(skb)->daddr);
+- break;
+- }
+- goto drop;
++ /* no segments survived: don't jump to 'drop' because we already
++ * incremented the counter for each failure in the loop
++ */
++ if (unlikely(skb_queue_empty(&skb_list))) {
++ ovpn_peer_put(peer);
++ return NETDEV_TX_OK;
+ }
+- /* dst was needed for peer selection - it can now be dropped */
+- skb_dst_drop(skb);
++ skb_list.prev->next = NULL;
+
+- ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb->len);
++ ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb_list.next->len);
+ ovpn_send(ovpn, skb_list.next, peer);
+
+ return NETDEV_TX_OK;
+
+ drop:
++ ovpn_peer_put(peer);
++drop_no_peer:
+ dev_dstats_tx_dropped(ovpn->dev);
+ skb_tx_error(skb);
+ kfree_skb_list(skb);
+--
+2.51.0
+
--- /dev/null
+From 400e71dc537e42d3e88e1f13111818754c694ca8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jan 2026 18:32:50 +0100
+Subject: ovpn: fix VPN TX bytes counting
+
+From: Ralf Lici <ralf@mandelbit.com>
+
+[ Upstream commit b660b13d4c6379ca6360f24aaef8c5807fefd237 ]
+
+In ovpn_net_xmit, after GSO segmentation and segment processing, the
+first segment on the list is used to increment VPN TX statistics, which
+fails to account for any subsequent segments in the chain.
+
+Fix this by accumulating the length of every segment that successfully
+passes skb_share_check into a tx_bytes variable. This ensures the peer
+statistics accurately reflect the total data volume sent, regardless of
+whether the original packet was segmented.
+
+Fixes: 04ca14955f9a ("ovpn: store tunnel and transport statistics")
+Signed-off-by: Ralf Lici <ralf@mandelbit.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ovpn/io.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c
+index f70c58b10599b..955c9a37e1f8d 100644
+--- a/drivers/net/ovpn/io.c
++++ b/drivers/net/ovpn/io.c
+@@ -355,6 +355,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
+ struct ovpn_priv *ovpn = netdev_priv(dev);
+ struct sk_buff *segments, *curr, *next;
+ struct sk_buff_head skb_list;
++ unsigned int tx_bytes = 0;
+ struct ovpn_peer *peer;
+ __be16 proto;
+ int ret;
+@@ -414,6 +415,8 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
+ continue;
+ }
+
++ /* only count what we actually send */
++ tx_bytes += curr->len;
+ __skb_queue_tail(&skb_list, curr);
+ }
+
+@@ -426,7 +429,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev)
+ }
+ skb_list.prev->next = NULL;
+
+- ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb_list.next->len);
++ ovpn_peer_stats_increment_tx(&peer->vpn_stats, tx_bytes);
+ ovpn_send(ovpn, skb_list.next, peer);
+
+ return NETDEV_TX_OK;
+--
+2.51.0
+
--- /dev/null
+From f864c078dd8e643075ec2421b5dbb18b7ab0df85 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 30 Jan 2026 18:32:48 +0100
+Subject: ovpn: set sk_user_data before overriding callbacks
+
+From: Ralf Lici <ralf@mandelbit.com>
+
+[ Upstream commit 93686c472eb7b09a51b97a096449e7092fefcd1f ]
+
+During initialization, we override socket callbacks and set sk_user_data
+to an ovpn_socket instance. Currently, these two operations are
+decoupled: callbacks are overridden before sk_user_data is set. While
+existing callbacks perform safety checks for NULL or non-ovpn
+sk_user_data, this condition causes a "half-formed" state where valid
+packets arriving during attachment trigger error logs (e.g., "invoked on
+non ovpn socket").
+
+Set sk_user_data before overriding the callbacks so that it can be
+accessed safely from them. Since we already check that the socket has no
+sk_user_data before setting it, this remains safe even if an interrupt
+accesses the socket after sk_user_data is set but before the callbacks
+are overridden.
+
+This also requires initializing all protocol-specific fields (such as
+tcp_tx_work and peer links) before calling ovpn_socket_attach, ensuring
+the ovpn_socket is fully formed before it becomes visible to any
+callback.
+
+Fixes: f6226ae7a0cd ("ovpn: introduce the ovpn_socket object")
+Signed-off-by: Ralf Lici <ralf@mandelbit.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ovpn/socket.c | 39 +++++++++++++++++++++------------------
+ drivers/net/ovpn/tcp.c | 9 +++++++--
+ drivers/net/ovpn/udp.c | 1 +
+ 3 files changed, 29 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/net/ovpn/socket.c b/drivers/net/ovpn/socket.c
+index 9750871ab65ce..448cee3b3f9fa 100644
+--- a/drivers/net/ovpn/socket.c
++++ b/drivers/net/ovpn/socket.c
+@@ -200,6 +200,22 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
+ ovpn_sock->sk = sk;
+ kref_init(&ovpn_sock->refcount);
+
++ /* TCP sockets are per-peer, therefore they are linked to their unique
++ * peer
++ */
++ if (sk->sk_protocol == IPPROTO_TCP) {
++ INIT_WORK(&ovpn_sock->tcp_tx_work, ovpn_tcp_tx_work);
++ ovpn_sock->peer = peer;
++ ovpn_peer_hold(peer);
++ } else if (sk->sk_protocol == IPPROTO_UDP) {
++ /* in UDP we only link the ovpn instance since the socket is
++ * shared among multiple peers
++ */
++ ovpn_sock->ovpn = peer->ovpn;
++ netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker,
++ GFP_KERNEL);
++ }
++
+ /* the newly created ovpn_socket is holding reference to sk,
+ * therefore we increase its refcounter.
+ *
+@@ -212,29 +228,16 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer)
+
+ ret = ovpn_socket_attach(ovpn_sock, sock, peer);
+ if (ret < 0) {
++ if (sk->sk_protocol == IPPROTO_TCP)
++ ovpn_peer_put(peer);
++ else if (sk->sk_protocol == IPPROTO_UDP)
++ netdev_put(peer->ovpn->dev, &ovpn_sock->dev_tracker);
++
+ sock_put(sk);
+ kfree(ovpn_sock);
+ ovpn_sock = ERR_PTR(ret);
+- goto sock_release;
+- }
+-
+- /* TCP sockets are per-peer, therefore they are linked to their unique
+- * peer
+- */
+- if (sk->sk_protocol == IPPROTO_TCP) {
+- INIT_WORK(&ovpn_sock->tcp_tx_work, ovpn_tcp_tx_work);
+- ovpn_sock->peer = peer;
+- ovpn_peer_hold(peer);
+- } else if (sk->sk_protocol == IPPROTO_UDP) {
+- /* in UDP we only link the ovpn instance since the socket is
+- * shared among multiple peers
+- */
+- ovpn_sock->ovpn = peer->ovpn;
+- netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker,
+- GFP_KERNEL);
+ }
+
+- rcu_assign_sk_user_data(sk, ovpn_sock);
+ sock_release:
+ release_sock(sk);
+ return ovpn_sock;
+diff --git a/drivers/net/ovpn/tcp.c b/drivers/net/ovpn/tcp.c
+index 0d7f30360d874..f0b4e07ba9245 100644
+--- a/drivers/net/ovpn/tcp.c
++++ b/drivers/net/ovpn/tcp.c
+@@ -487,6 +487,7 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock,
+ /* make sure no pre-existing encapsulation handler exists */
+ if (ovpn_sock->sk->sk_user_data)
+ return -EBUSY;
++ rcu_assign_sk_user_data(ovpn_sock->sk, ovpn_sock);
+
+ /* only a fully connected socket is expected. Connection should be
+ * handled in userspace
+@@ -495,13 +496,14 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock,
+ net_err_ratelimited("%s: provided TCP socket is not in ESTABLISHED state: %d\n",
+ netdev_name(peer->ovpn->dev),
+ ovpn_sock->sk->sk_state);
+- return -EINVAL;
++ ret = -EINVAL;
++ goto err;
+ }
+
+ ret = strp_init(&peer->tcp.strp, ovpn_sock->sk, &cb);
+ if (ret < 0) {
+ DEBUG_NET_WARN_ON_ONCE(1);
+- return ret;
++ goto err;
+ }
+
+ INIT_WORK(&peer->tcp.defer_del_work, ovpn_tcp_peer_del_work);
+@@ -536,6 +538,9 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock,
+ strp_check_rcv(&peer->tcp.strp);
+
+ return 0;
++err:
++ rcu_assign_sk_user_data(ovpn_sock->sk, NULL);
++ return ret;
+ }
+
+ static void ovpn_tcp_close(struct sock *sk, long timeout)
+diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c
+index d6a0f7a0b75d7..272b535ecaad4 100644
+--- a/drivers/net/ovpn/udp.c
++++ b/drivers/net/ovpn/udp.c
+@@ -386,6 +386,7 @@ int ovpn_udp_socket_attach(struct ovpn_socket *ovpn_sock, struct socket *sock,
+ struct ovpn_priv *ovpn)
+ {
+ struct udp_tunnel_sock_cfg cfg = {
++ .sk_user_data = ovpn_sock,
+ .encap_type = UDP_ENCAP_OVPNINUDP,
+ .encap_rcv = ovpn_udp_encap_recv,
+ .encap_destroy = ovpn_udp_encap_destroy,
+--
+2.51.0
+
--- /dev/null
+From f5f52610fc9ce71e30c47e50794616215653ea29 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 22:31:19 +0100
+Subject: ovpn: tcp - don't deref NULL sk_socket member after tcp_close()
+
+From: Antonio Quartulli <antonio@openvpn.net>
+
+[ Upstream commit 94560267d6c41b1ff3fafbab726e3f8a55a6af34 ]
+
+When deleting a peer in case of keepalive expiration, the peer is
+removed from the OpenVPN hashtable and is temporary inserted in a
+"release list" for further processing.
+
+This happens in:
+ovpn_peer_keepalive_work()
+ unlock_ovpn(release_list)
+
+This processing includes detaching from the socket being used to
+talk to this peer, by restoring its original proto and socket
+ops/callbacks.
+
+In case of TCP it may happen that, while the peer is sitting in
+the release list, userspace decides to close the socket.
+This will result in a concurrent execution of:
+
+tcp_close(sk)
+ __tcp_close(sk)
+ sock_orphan(sk)
+ sk_set_socket(sk, NULL)
+
+The last function call will set sk->sk_socket to NULL.
+
+When the releasing routine is resumed, ovpn_tcp_socket_detach()
+will attempt to dereference sk->sk_socket to restore its original
+ops member. This operation will crash due to sk->sk_socket being NULL.
+
+Fix this race condition by testing-and-accessing
+sk->sk_socket atomically under sk->sk_callback_lock.
+
+Link: https://lore.kernel.org/netdev/176996279620.3109699.15382994681575380467@eldamar.lan/
+Link: https://github.com/OpenVPN/ovpn-net-next/issues/29
+Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
+Fixes: 11851cbd60ea ("ovpn: implement TCP transport")
+Link: https://patch.msgid.link/20260212213130.11497-1-antonio@openvpn.net
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ovpn/tcp.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ovpn/tcp.c b/drivers/net/ovpn/tcp.c
+index f0b4e07ba9245..ec2bbc28c1966 100644
+--- a/drivers/net/ovpn/tcp.c
++++ b/drivers/net/ovpn/tcp.c
+@@ -199,7 +199,19 @@ void ovpn_tcp_socket_detach(struct ovpn_socket *ovpn_sock)
+ sk->sk_data_ready = peer->tcp.sk_cb.sk_data_ready;
+ sk->sk_write_space = peer->tcp.sk_cb.sk_write_space;
+ sk->sk_prot = peer->tcp.sk_cb.prot;
+- sk->sk_socket->ops = peer->tcp.sk_cb.ops;
++
++ /* tcp_close() may race this function and could set
++ * sk->sk_socket to NULL. It does so by invoking
++ * sock_orphan(), which holds sk_callback_lock before
++ * doing the assignment.
++ *
++ * For this reason we acquire the same lock to avoid
++ * sk_socket to disappear under our feet
++ */
++ write_lock_bh(&sk->sk_callback_lock);
++ if (sk->sk_socket)
++ sk->sk_socket->ops = peer->tcp.sk_cb.ops;
++ write_unlock_bh(&sk->sk_callback_lock);
+
+ rcu_assign_sk_user_data(sk, NULL);
+ }
+--
+2.51.0
+
--- /dev/null
+From 113694fb3a282b06e5ea7b58c61535612e45228f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 23:54:07 +0900
+Subject: PCI: dwc: ep: Always clear IB maps on BAR update
+
+From: Koichiro Den <den@valinux.co.jp>
+
+[ Upstream commit 8c746e22096579897d1f8f74dbb6b17a6862fb6d ]
+
+dw_pcie_ep_set_bar() currently tears down existing inbound mappings only
+when either the previous or the new struct pci_epf_bar uses submaps
+(num_submap != 0). If both the old and new mappings are BAR Match Mode,
+reprogramming the same ATU index is sufficient, so no explicit teardown
+was needed.
+
+However, some callers may reuse the same struct pci_epf_bar instance and
+update it in place before calling set_bar() again. In that case
+ep_func->epf_bar[bar] and the passed-in epf_bar can point to the same
+object, so we cannot reliably distinguish BAR Match Mode -> BAR Match Mode
+from Address Match Mode -> BAR Match Mode. As a result, the conditional
+teardown based on num_submap becomes unreliable and existing inbound maps
+may be left active.
+
+Call dw_pcie_ep_clear_ib_maps() unconditionally before reprogramming the
+BAR so that in-place updates are handled correctly.
+
+This introduces a behavioral change in a corner case: if a BAR
+reprogramming attempt fails (especially for the long-standing BAR Match
+Mode -> BAR Match Mode update case), the previously programmed inbound
+mapping will already have been torn down. This should be acceptable, since
+the caller observes the error and should not use the BAR for any real
+transactions in that case.
+
+While at it, document that the existing update parameter check is
+best-effort for in-place updates.
+
+Fixes: cc839bef7727 ("PCI: dwc: ep: Support BAR subrange inbound mapping via Address Match Mode iATU")
+Signed-off-by: Koichiro Den <den@valinux.co.jp>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Link: https://patch.msgid.link/20260202145407.503348-3-den@valinux.co.jp
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pcie-designware-ep.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
+index 6d3c35dd280f3..59fd6ebf01489 100644
+--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
+@@ -518,6 +518,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+ /*
+ * We can only dynamically change a BAR if the new BAR size and
+ * BAR flags do not differ from the existing configuration.
++ *
++ * Note: this safety check only works when the caller uses
++ * a new struct pci_epf_bar in the second set_bar() call.
++ * If the same instance is updated in place and passed in,
++ * we cannot reliably detect invalid barno/size/flags
++ * changes here.
+ */
+ if (ep_func->epf_bar[bar]->barno != bar ||
+ ep_func->epf_bar[bar]->size != size ||
+@@ -526,10 +532,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+
+ /*
+ * When dynamically changing a BAR, tear down any existing
+- * mappings before re-programming.
++ * mappings before re-programming. This is redundant when
++ * both the old and new mappings are BAR Match Mode, but
++ * required to handle in-place updates and match-mode
++ * changes reliably.
+ */
+- if (ep_func->epf_bar[bar]->num_submap || epf_bar->num_submap)
+- dw_pcie_ep_clear_ib_maps(ep, func_no, bar);
++ dw_pcie_ep_clear_ib_maps(ep, func_no, bar);
+
+ /*
+ * When dynamically changing a BAR, skip writing the BAR reg, as
+--
+2.51.0
+
--- /dev/null
+From 766b9730aa9fcb41bc00a0b1ad18799ab728a7bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 22:20:57 +0800
+Subject: PCI: Validate window resource type in pbus_select_window_for_type()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kai-Heng Feng <kaihengf@nvidia.com>
+
+[ Upstream commit e5f72cb9cea599dc9f5a9b80a33560a1d06f01cc ]
+
+After ebe091ad81e1 ("PCI: Use pbus_select_window_for_type() during IO
+window sizing") and ae88d0b9c57f ("PCI: Use pbus_select_window_for_type()
+during mem window sizing"), many bridge windows can't get resources
+assigned:
+
+ pci 0006:05:00.0: bridge window [??? 0x00001000-0x00001fff flags 0x20080000]: can't assign; no space
+ pci 0006:05:00.0: bridge window [??? 0x00001000-0x00001fff flags 0x20080000]: failed to assign
+
+Those commits replace find_bus_resource_of_type() with
+pbus_select_window_for_type(), and the latter lacks resource type
+validation.
+
+Add the resource type validation back to pbus_select_window_for_type() to
+match the original behavior.
+
+Fixes: 74afce3dfcba ("PCI: Add bridge window selection functions")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=221072
+Signed-off-by: Kai-Heng Feng <kaihengf@nvidia.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Link: https://patch.msgid.link/20260210142058.82701-1-kaihengf@nvidia.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/setup-bus.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
+index 902fdae73c232..09a28cfcd5b88 100644
+--- a/drivers/pci/setup-bus.c
++++ b/drivers/pci/setup-bus.c
+@@ -225,14 +225,21 @@ static struct resource *pbus_select_window_for_type(struct pci_bus *bus,
+
+ switch (iores_type) {
+ case IORESOURCE_IO:
+- return pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW);
++ win = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW);
++ if (win && (win->flags & IORESOURCE_IO))
++ return win;
++ return NULL;
+
+ case IORESOURCE_MEM:
+ mmio = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_MEM_WINDOW);
+ mmio_pref = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_PREF_MEM_WINDOW);
+
+- if (!(type & IORESOURCE_PREFETCH) ||
+- !(mmio_pref->flags & IORESOURCE_MEM))
++ if (mmio && !(mmio->flags & IORESOURCE_MEM))
++ mmio = NULL;
++ if (mmio_pref && !(mmio_pref->flags & IORESOURCE_MEM))
++ mmio_pref = NULL;
++
++ if (!(type & IORESOURCE_PREFETCH) || !mmio_pref)
+ return mmio;
+
+ if ((type & IORESOURCE_MEM_64) ||
+--
+2.51.0
+
--- /dev/null
+From 60075b54f79c6aca4b5816f6aeffc2ab3a8851c2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:01:49 +0000
+Subject: ping: annotate data-races in ping_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit ad5dfde2a5733aaf652ea3e40c8c5e071e935901 ]
+
+isk->inet_num, isk->inet_rcv_saddr and sk->sk_bound_dev_if
+are read locklessly in ping_lookup().
+
+Add READ_ONCE()/WRITE_ONCE() annotations.
+
+The race on isk->inet_rcv_saddr is probably coming from IPv6 support,
+but does not deserve a specific backport.
+
+Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216100149.3319315-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ping.c | 31 +++++++++++++++++++------------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index cfbd563498e85..0fec4e5645667 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -148,7 +148,7 @@ void ping_unhash(struct sock *sk)
+ pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+ spin_lock(&ping_table.lock);
+ if (sk_del_node_init_rcu(sk)) {
+- isk->inet_num = 0;
++ WRITE_ONCE(isk->inet_num, 0);
+ isk->inet_sport = 0;
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+ }
+@@ -181,31 +181,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ }
+
+ sk_for_each_rcu(sk, hslot) {
++ int bound_dev_if;
++
+ if (!net_eq(sock_net(sk), net))
+ continue;
+ isk = inet_sk(sk);
+
+ pr_debug("iterate\n");
+- if (isk->inet_num != ident)
++ if (READ_ONCE(isk->inet_num) != ident)
+ continue;
+
++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+ if (skb->protocol == htons(ETH_P_IP) &&
+ sk->sk_family == AF_INET) {
++ __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr);
++
+ pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk,
+- (int) isk->inet_num, &isk->inet_rcv_saddr,
+- sk->sk_bound_dev_if);
++ ident, &rcv_saddr,
++ bound_dev_if);
+
+- if (isk->inet_rcv_saddr &&
+- isk->inet_rcv_saddr != ip_hdr(skb)->daddr)
++ if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr)
+ continue;
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (skb->protocol == htons(ETH_P_IPV6) &&
+ sk->sk_family == AF_INET6) {
+
+ pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk,
+- (int) isk->inet_num,
++ ident,
+ &sk->sk_v6_rcv_saddr,
+- sk->sk_bound_dev_if);
++ bound_dev_if);
+
+ if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) &&
+ !ipv6_addr_equal(&sk->sk_v6_rcv_saddr,
+@@ -216,8 +220,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ continue;
+ }
+
+- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
+- sk->sk_bound_dev_if != sdif)
++ if (bound_dev_if && bound_dev_if != dif &&
++ bound_dev_if != sdif)
+ continue;
+
+ goto exit;
+@@ -392,7 +396,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr_unsized *saddr)
+ if (saddr->sa_family == AF_INET) {
+ struct inet_sock *isk = inet_sk(sk);
+ struct sockaddr_in *addr = (struct sockaddr_in *) saddr;
+- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
++
++ isk->inet_saddr = addr->sin_addr.s_addr;
++ WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr);
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (saddr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr;
+@@ -849,7 +855,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
+ struct sk_buff *skb;
+ int copied, err;
+
+- pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
++ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk,
++ READ_ONCE(isk->inet_num));
+
+ err = -EOPNOTSUPP;
+ if (flags & MSG_OOB)
+--
+2.51.0
+
--- /dev/null
+From a35cd3f77ee236f3e22335638dbab151f1a69461 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 15:43:09 -0800
+Subject: powercap: intel_rapl: Remove incorrect CPU check in PMU context
+
+From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+
+[ Upstream commit 7537bae8b6eb635583e0e6260f61d13ddbd52087 ]
+
+The RAPL MSR read path incorrectly validates CPU context when called
+from the PMU subsystem:
+
+ if (atomic) {
+ if (unlikely(smp_processor_id() != cpu))
+ return -EIO;
+ rdmsrq(ra->reg.msr, ra->value);
+ }
+
+This check fails for package-scoped MSRs like RAPL energy counters,
+which are readable from any CPU within the package.
+
+The perf tool avoids hitting this check by validating against
+/sys/bus/event_source/devices/power/cpumask before opening events.
+However, turbostat does not perform this validation and may attempt
+reads from non-lead CPUs, causing the check to fail and return zero
+power values.
+
+Since package-scoped MSRs are architecturally accessible from any CPU
+in the package, remove the CPU matching check.
+
+Also rename 'atomic' to 'pmu_ctx' to clarify this indicates PMU context
+where rdmsrq() can be used directly instead of rdmsrl_safe_on_cpu().
+
+Fixes: 748d6ba43afd ("powercap: intel_rapl: Enable MSR-based RAPL PMU support")
+Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Tested-by: Furquim Ulisses <ulisses.furquim@intel.com>
+Reviewed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Link: https://patch.msgid.link/20260209234310.1440722-2-sathyanarayanan.kuppuswamy@linux.intel.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/powercap/intel_rapl_common.c | 6 +++---
+ drivers/powercap/intel_rapl_msr.c | 12 +++++-------
+ include/linux/intel_rapl.h | 2 +-
+ 3 files changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
+index 3ff6da3bf4e63..3705d0608a0fb 100644
+--- a/drivers/powercap/intel_rapl_common.c
++++ b/drivers/powercap/intel_rapl_common.c
+@@ -254,7 +254,7 @@ static void rapl_init_domains(struct rapl_package *rp);
+ static int rapl_read_data_raw(struct rapl_domain *rd,
+ enum rapl_primitives prim,
+ bool xlate, u64 *data,
+- bool atomic);
++ bool pmu_ctx);
+ static int rapl_write_data_raw(struct rapl_domain *rd,
+ enum rapl_primitives prim,
+ unsigned long long value);
+@@ -832,7 +832,7 @@ prim_fixups(struct rapl_domain *rd, enum rapl_primitives prim)
+ */
+ static int rapl_read_data_raw(struct rapl_domain *rd,
+ enum rapl_primitives prim, bool xlate, u64 *data,
+- bool atomic)
++ bool pmu_ctx)
+ {
+ u64 value;
+ enum rapl_primitives prim_fixed = prim_fixups(rd, prim);
+@@ -854,7 +854,7 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
+
+ ra.mask = rpi->mask;
+
+- if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra, atomic)) {
++ if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra, pmu_ctx)) {
+ pr_debug("failed to read reg 0x%llx for %s:%s\n", ra.reg.val, rd->rp->name, rd->name);
+ return -EIO;
+ }
+diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c
+index 9a7e150b3536b..152893dca5653 100644
+--- a/drivers/powercap/intel_rapl_msr.c
++++ b/drivers/powercap/intel_rapl_msr.c
+@@ -110,16 +110,14 @@ static int rapl_cpu_down_prep(unsigned int cpu)
+ return 0;
+ }
+
+-static int rapl_msr_read_raw(int cpu, struct reg_action *ra, bool atomic)
++static int rapl_msr_read_raw(int cpu, struct reg_action *ra, bool pmu_ctx)
+ {
+ /*
+- * When called from atomic-context (eg PMU event handler)
+- * perform MSR read directly using rdmsrq().
++ * When called from PMU context, perform MSR read directly using
++ * rdmsrq() without IPI overhead. Package-scoped MSRs are readable
++ * from any CPU in the package.
+ */
+- if (atomic) {
+- if (unlikely(smp_processor_id() != cpu))
+- return -EIO;
+-
++ if (pmu_ctx) {
+ rdmsrq(ra->reg.msr, ra->value);
+ goto out;
+ }
+diff --git a/include/linux/intel_rapl.h b/include/linux/intel_rapl.h
+index f479ef5b3341c..fa1f328d67120 100644
+--- a/include/linux/intel_rapl.h
++++ b/include/linux/intel_rapl.h
+@@ -152,7 +152,7 @@ struct rapl_if_priv {
+ union rapl_reg reg_unit;
+ union rapl_reg regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX];
+ int limits[RAPL_DOMAIN_MAX];
+- int (*read_raw)(int id, struct reg_action *ra, bool atomic);
++ int (*read_raw)(int id, struct reg_action *ra, bool pmu_ctx);
+ int (*write_raw)(int id, struct reg_action *ra);
+ void *defaults;
+ void *rpi;
+--
+2.51.0
+
--- /dev/null
+From e7545381464ebd49da70e9d12c4c97cd09becdad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 14:34:01 -0800
+Subject: powercap: intel_rapl_tpmi: Remove FW_BUG from invalid version check
+
+From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+
+[ Upstream commit c7d54dafa042cf379859dba265fe5afef6fa8770 ]
+
+On partitioned systems, multiple TPMI instances may exist per package,
+but RAPL registers are only valid on one instance since RAPL has
+package-scope control. Other instances return invalid versions during
+domain parsing, which is expected behavior on such systems.
+
+Currently this generates a firmware bug warning:
+
+ intel_rapl_tpmi: [Firmware Bug]: Invalid version
+
+Remove the FW_BUG tag, downgrade to pr_debug(), and update the message
+to clarify that invalid versions are expected on partitioned systems
+where only one instance can be valid.
+
+Fixes: 9eef7f9da928 ("powercap: intel_rapl: Introduce RAPL TPMI interface driver")
+Reported-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Reviewed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Link: https://patch.msgid.link/20260211223401.1575776-1-sathyanarayanan.kuppuswamy@linux.intel.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/powercap/intel_rapl_tpmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/powercap/intel_rapl_tpmi.c b/drivers/powercap/intel_rapl_tpmi.c
+index 0a0b85f4528b1..0f8abdc592bc1 100644
+--- a/drivers/powercap/intel_rapl_tpmi.c
++++ b/drivers/powercap/intel_rapl_tpmi.c
+@@ -157,7 +157,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
+ tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff;
+
+ if (tpmi_domain_version == TPMI_VERSION_INVALID) {
+- pr_warn(FW_BUG "Invalid version\n");
++ pr_debug("Invalid version, other instances may be valid\n");
+ return -ENODEV;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From b626cebd592eda9eb476a4b82eef4c3590ff8693 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 23:37:04 -0600
+Subject: regulator: mt6363: Fix interrmittent timeout
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit 1a4b0c999101b2532723f9bd9818b70ffa7580f4 ]
+
+Sometimes, the mt6363 regulator would fail to initialize and return with
+a TIMEOUT error, so add an extra instruction to wake up the bus before
+issuing the commands.
+
+Fixes: 3c36965df808 ("regulator: Add support for MediaTek MT6363 SPMI PMIC Regulators")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Link: https://patch.msgid.link/20260210053708.17239-4-aford173@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/mt6363-regulator.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/regulator/mt6363-regulator.c b/drivers/regulator/mt6363-regulator.c
+index e0fbf92e76851..03af5fa536007 100644
+--- a/drivers/regulator/mt6363-regulator.c
++++ b/drivers/regulator/mt6363-regulator.c
+@@ -861,7 +861,7 @@ static int mt6363_regulator_probe(struct platform_device *pdev)
+ struct irq_domain *domain;
+ struct irq_fwspec fwspec;
+ struct spmi_device *sdev;
+- int i, ret;
++ int i, ret, val;
+
+ config.regmap = mt6363_spmi_register_regmap(dev);
+ if (IS_ERR(config.regmap))
+@@ -870,6 +870,13 @@ static int mt6363_regulator_probe(struct platform_device *pdev)
+ config.dev = dev;
+ sdev = to_spmi_device(dev->parent);
+
++ /*
++ * The first read may fail if the bootloader sets sleep mode: wake up
++ * this PMIC with W/R on the SPMI bus and ignore the first result.
++ * This matches the MT6373 driver behavior.
++ */
++ regmap_read(config.regmap, MT6363_TOP_TRAP, &val);
++
+ interrupt_parent = of_irq_find_parent(dev->of_node);
+ if (!interrupt_parent)
+ return dev_err_probe(dev, -EINVAL, "Cannot find IRQ parent\n");
+--
+2.51.0
+
--- /dev/null
+From 335e23a0b9d1e1ba17548158f50e566448859464 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 07:29:16 +0100
+Subject: s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n
+
+From: Alexander Egorenkov <egorenar@linux.ibm.com>
+
+[ Upstream commit dd3411959b57df6e05a3ccbac67b0a836871c0c4 ]
+
+The commit c8424e776b09 ("MODSIGN: Export module signature definitions")
+replaced the dependency of KEXEC_SIG on SYSTEM_DATA_VERIFICATION with the
+dependency on MODULE_SIG_FORMAT. This change disables KEXEC_SIG in s390
+kernels built with MODULES=n if nothing else selects MODULE_SIG_FORMAT.
+
+Furthermore, the signature verification in s390 kexec does not require
+MODULE_SIG_FORMAT because it requires only the struct module_signature and,
+therefore, does not depend on code in kernel/module_signature.c.
+
+But making ARCH_SUPPORTS_KEXEC_SIG depend on SYSTEM_DATA_VERIFICATION is
+also incorrect because it makes KEXEC_SIG available on s390 only if some
+other arbitrary option (for instance a file system or device driver)
+selects it directly or indirectly.
+
+To properly make KEXEC_SIG available for s390 kernels built with MODULES=y
+as well as MODULES=n _and_ also not depend on arbitrary options selecting
+SYSTEM_DATA_VERIFICATION, set ARCH_SUPPORTS_KEXEC_SIG=y for s390 and select
+SYSTEM_DATA_VERIFICATION when KEXEC_SIG=y.
+
+Fixes: c8424e776b09 ("MODSIGN: Export module signature definitions")
+Suggested-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 0e5fad5f06ca1..783be50f38f2b 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -275,6 +275,7 @@ config S390
+ select SPARSE_IRQ
+ select SWIOTLB
+ select SYSCTL_EXCEPTION_TRACE
++ select SYSTEM_DATA_VERIFICATION if KEXEC_SIG
+ select THREAD_INFO_IN_TASK
+ select TRACE_IRQFLAGS_SUPPORT
+ select TTY
+@@ -301,7 +302,7 @@ config ARCH_SUPPORTS_KEXEC_FILE
+ def_bool y
+
+ config ARCH_SUPPORTS_KEXEC_SIG
+- def_bool MODULE_SIG_FORMAT
++ def_bool y
+
+ config ARCH_SUPPORTS_KEXEC_PURGATORY
+ def_bool y
+--
+2.51.0
+
--- /dev/null
+From e4d85c9e23570a6255e1d75aa2ab8285c3fd61e9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:07 +0000
+Subject: selftests: forwarding: fix pedit tests failure with br_netfilter
+ enabled
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit a8c198d16c64cdf57f481a4cd3e769502802369e ]
+
+The tests use the tc pedit action to modify the IPv4 source address
+("pedit ex munge ip src set"), but the IP header checksum is not
+recalculated after the modification. As a result, the modified packet
+fails sanity checks in br_netfilter after bridging and is dropped,
+which causes the test to fail.
+
+Fix this by ensuring net.bridge.bridge-nf-call-iptables is set to 0
+during the test execution. This prevents the bridge from passing
+L2 traffic to netfilter, bypassing the checksum validation that
+causes the test failure.
+
+Fixes: 92ad3828944e ("selftests: forwarding: Add a test for pedit munge SIP and DIP")
+Fixes: 226657ba2389 ("selftests: forwarding: Add a forwarding test for pedit munge dsfield")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-4-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/pedit_dsfield.sh | 8 ++++++++
+ tools/testing/selftests/net/forwarding/pedit_ip.sh | 8 ++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/tools/testing/selftests/net/forwarding/pedit_dsfield.sh b/tools/testing/selftests/net/forwarding/pedit_dsfield.sh
+index af008fbf2725e..eb2d8034de9c7 100755
+--- a/tools/testing/selftests/net/forwarding/pedit_dsfield.sh
++++ b/tools/testing/selftests/net/forwarding/pedit_dsfield.sh
+@@ -98,12 +98,20 @@ setup_prepare()
+ h1_create
+ h2_create
+ switch_create
++
++ if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then
++ sysctl_set net.bridge.bridge-nf-call-iptables 0
++ fi
+ }
+
+ cleanup()
+ {
+ pre_cleanup
+
++ if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then
++ sysctl_restore net.bridge.bridge-nf-call-iptables
++ fi
++
+ switch_destroy
+ h2_destroy
+ h1_destroy
+diff --git a/tools/testing/selftests/net/forwarding/pedit_ip.sh b/tools/testing/selftests/net/forwarding/pedit_ip.sh
+index d14efb2d23b2e..9235674627abd 100755
+--- a/tools/testing/selftests/net/forwarding/pedit_ip.sh
++++ b/tools/testing/selftests/net/forwarding/pedit_ip.sh
+@@ -91,12 +91,20 @@ setup_prepare()
+ h1_create
+ h2_create
+ switch_create
++
++ if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then
++ sysctl_set net.bridge.bridge-nf-call-iptables 0
++ fi
+ }
+
+ cleanup()
+ {
+ pre_cleanup
+
++ if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then
++ sysctl_restore net.bridge.bridge-nf-call-iptables
++ fi
++
+ switch_destroy
+ h2_destroy
+ h1_destroy
+--
+2.51.0
+
--- /dev/null
+From eb4e8f11e531c95486cae258b4d9c476ab37c9ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:05 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with
+ br_netfilter enabled
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv4 packet contains a zero IP header checksum. After VXLAN
+decapsulation, such packets do not pass sanity checks in br_netfilter
+and are dropped, which causes the test to fail.
+
+Fix this by calculating and setting a valid IPv4 header checksum for the
+encapsulated packet generated by mausezahn, so that the packet is accepted
+by br_netfilter. Fixed by using the payload_template_calc_checksum() /
+payload_template_expand_checksum() helpers that are only available
+in v6.3 and newer kernels.
+
+Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++-------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+index b43816dd998ca..457f41d5e584b 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+@@ -567,6 +567,21 @@ vxlan_encapped_ping_do()
+ local inner_tos=$1; shift
+ local outer_tos=$1; shift
+
++ local ipv4hdr=$(:
++ )"45:"$( : IP version + IHL
++ )"$inner_tos:"$( : IP TOS
++ )"00:54:"$( : IP total length
++ )"99:83:"$( : IP identification
++ )"40:00:"$( : IP flags + frag off
++ )"40:"$( : IP TTL
++ )"01:"$( : IP proto
++ )"CHECKSUM:"$( : IP header csum
++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1
++ )
++ local checksum=$(payload_template_calc_checksum "$ipv4hdr")
++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum)
++
+ $MZ $dev -c $count -d 100msec -q \
+ -b $next_hop_mac -B $dest_ip \
+ -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(:
+@@ -577,16 +592,7 @@ vxlan_encapped_ping_do()
+ )"$dest_mac:"$( : ETH daddr
+ )"$(mac_get w2):"$( : ETH saddr
+ )"08:00:"$( : ETH type
+- )"45:"$( : IP version + IHL
+- )"$inner_tos:"$( : IP TOS
+- )"00:54:"$( : IP total length
+- )"99:83:"$( : IP identification
+- )"40:00:"$( : IP flags + frag off
+- )"40:"$( : IP TTL
+- )"01:"$( : IP proto
+- )"00:00:"$( : IP header csum
+- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
+- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1
++ )"$ipv4hdr:"$( : IPv4 header
+ )"08:"$( : ICMP type
+ )"00:"$( : ICMP code
+ )"8b:f2:"$( : ICMP csum
+--
+2.51.0
+
--- /dev/null
+From 50b5b2278c7f8f3f7c16af7a857a086f299a71d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:06 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with
+ br_netfilter enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit ce9f6aec0fb780dafc1dfc5f47c688422aff464a ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv6 packet has an incorrect payload length set in the IPv6 header.
+After VXLAN decapsulation, such packets do not pass sanity checks in
+br_netfilter and are dropped, which causes the test to fail.
+
+Fix this by setting the correct IPv6 payload length for the encapsulated
+packet generated by mausezahn, so that the packet is accepted
+by br_netfilter.
+
+tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+lines 698-706
+
+ )"00:03:"$( : Payload length
+ )"3a:"$( : Next header
+ )"04:"$( : Hop limit
+ )"$saddr:"$( : IP saddr
+ )"$daddr:"$( : IP daddr
+ )"80:"$( : ICMPv6.type
+ )"00:"$( : ICMPv6.code
+ )"00:"$( : ICMPv6.checksum
+ )
+
+Data after IPv6 header:
+• 80: — 1 byte (ICMPv6 type)
+• 00: — 1 byte (ICMPv6 code)
+• 00: — 1 byte (ICMPv6 checksum, truncated)
+
+Total: 3 bytes → 00:03 is correct. The old value 00:08 did not match
+the actual payload size.
+
+Fixes: b07e9957f220 ("selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for IPv6")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-3-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+index a603f7b0a08f0..e642feeada0e7 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+@@ -695,7 +695,7 @@ vxlan_encapped_ping_do()
+ )"6"$( : IP version
+ )"$inner_tos"$( : Traffic class
+ )"0:00:00:"$( : Flow label
+- )"00:08:"$( : Payload length
++ )"00:03:"$( : Payload length
+ )"3a:"$( : Next header
+ )"04:"$( : Hop limit
+ )"$saddr:"$( : IP saddr
+--
+2.51.0
+
--- /dev/null
+From 37cf61e710eeb0369586c7c0e23e068d504dbab5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 09:38:05 -0500
+Subject: selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT
+
+From: Aristeu Rozanski <aris@redhat.com>
+
+[ Upstream commit b24335521de92fd2ee22460072b75367ca8860b0 ]
+
+selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT
+
+In order to synchronize new processes to test inheritance of memfd_noexec
+sysctl, memfd_test sets up the sysctl with a value before creating the new
+process. The new process then sends itself a SIGSTOP in order to wait for
+the parent to flip the sysctl value and send a SIGCONT signal.
+
+This would work as intended if it wasn't the fact that the new process is
+being created with CLONE_NEWPID, which creates a new PID namespace and the
+new process has PID 1 in this namespace. There're restrictions on sending
+signals to PID 1 and, although it's relaxed for other than root PID
+namespace, it's biting us here. In this specific case the SIGSTOP sent by
+the new process is ignored (no error to kill() is returned) and it never
+stops its execution. This is usually not noticiable as the parent usually
+manages to set the new sysctl value before the child has a chance to run
+and the test succeeds. But if you run the test in a loop, it eventually
+reproduces:
+
+ while [ 1 ]; do ./memfd_test >log 2>&1 || break; done; cat log
+
+So this patch replaces the SIGSTOP/SIGCONT synchronization with IPC
+semaphore.
+
+Link: https://lkml.kernel.org/r/a7776389-b3d6-4b18-b438-0b0e3ed1fd3b@work
+Fixes: 6469b66e3f5a ("selftests: improve vm.memfd_noexec sysctl tests")
+Signed-off-by: Aristeu Rozanski <aris@redhat.com>
+Cc: Aleksa Sarai <cyphar@cyphar.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: liuye <liuye@kylinos.cn>
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/memfd/memfd_test.c | 113 +++++++++++++++++++--
+ 1 file changed, 105 insertions(+), 8 deletions(-)
+
+diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c
+index 5b993924cc3f5..2ca07ea7202a5 100644
+--- a/tools/testing/selftests/memfd/memfd_test.c
++++ b/tools/testing/selftests/memfd/memfd_test.c
+@@ -18,6 +18,9 @@
+ #include <sys/stat.h>
+ #include <sys/syscall.h>
+ #include <sys/wait.h>
++#include <sys/types.h>
++#include <sys/ipc.h>
++#include <sys/sem.h>
+ #include <unistd.h>
+ #include <ctype.h>
+
+@@ -39,6 +42,20 @@
+ F_SEAL_EXEC)
+
+ #define MFD_NOEXEC_SEAL 0x0008U
++union semun {
++ int val;
++ struct semid_ds *buf;
++ unsigned short int *array;
++ struct seminfo *__buf;
++};
++
++/*
++ * we use semaphores on nested wait tasks due the use of CLONE_NEWPID: the
++ * child will be PID 1 and can't send SIGSTOP to themselves due special
++ * treatment of the init task, so the SIGSTOP/SIGCONT synchronization
++ * approach can't be used here.
++ */
++#define SEM_KEY 0xdeadbeef
+
+ /*
+ * Default is not to test hugetlbfs
+@@ -1333,8 +1350,22 @@ static int sysctl_nested(void *arg)
+
+ static int sysctl_nested_wait(void *arg)
+ {
+- /* Wait for a SIGCONT. */
+- kill(getpid(), SIGSTOP);
++ int sem = semget(SEM_KEY, 1, 0600);
++ struct sembuf sembuf;
++
++ if (sem < 0) {
++ perror("semget:");
++ abort();
++ }
++ sembuf.sem_num = 0;
++ sembuf.sem_flg = 0;
++ sembuf.sem_op = 0;
++
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ abort();
++ }
++
+ return sysctl_nested(arg);
+ }
+
+@@ -1355,7 +1386,9 @@ static void test_sysctl_sysctl2_failset(void)
+
+ static int sysctl_nested_child(void *arg)
+ {
+- int pid;
++ int pid, sem;
++ union semun semun;
++ struct sembuf sembuf;
+
+ printf("%s nested sysctl 0\n", memfd_str);
+ sysctl_assert_write("0");
+@@ -1389,23 +1422,53 @@ static int sysctl_nested_child(void *arg)
+ test_sysctl_sysctl2_failset);
+ join_thread(pid);
+
++ sem = semget(SEM_KEY, 1, IPC_CREAT | 0600);
++ if (sem < 0) {
++ perror("semget:");
++ return 1;
++ }
++ semun.val = 1;
++ sembuf.sem_op = -1;
++ sembuf.sem_flg = 0;
++ sembuf.sem_num = 0;
++
+ /* Verify that the rules are actually inherited after fork. */
+ printf("%s nested sysctl 0 -> 1 after fork\n", memfd_str);
+ sysctl_assert_write("0");
+
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl1_failset);
+ sysctl_assert_write("1");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 0 -> 2 after fork\n", memfd_str);
+ sysctl_assert_write("0");
+
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2_failset);
+ sysctl_assert_write("2");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ /*
+@@ -1415,28 +1478,62 @@ static int sysctl_nested_child(void *arg)
+ */
+ printf("%s nested sysctl 2 -> 1 after fork\n", memfd_str);
+ sysctl_assert_write("2");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2);
+ sysctl_assert_write("1");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 2 -> 0 after fork\n", memfd_str);
+ sysctl_assert_write("2");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2);
+ sysctl_assert_write("0");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 1 -> 0 after fork\n", memfd_str);
+ sysctl_assert_write("1");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl1);
+ sysctl_assert_write("0");
+- kill(pid, SIGCONT);
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
++ semctl(sem, 0, IPC_RMID);
++
+ return 0;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 3c6f9d11c952846f78b7127f119a561e49297623 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 14:53:53 +0100
+Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ]
+
+As explained in [1], iproute2 started rejecting tc-police burst sizes
+that result in an overflow. This can happen when the burst size is high
+enough and the rate is low enough.
+
+A couple of test cases specify such configurations, resulting in
+iproute2 errors and test failure.
+
+Fix by reducing the burst size so that the test will pass with both new
+and old iproute2 versions.
+
+[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/
+
+Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+index 0441a18f098b1..aac8ef490feb8 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+@@ -317,7 +317,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 0.5kbit burst 1m conform-exceed drop/ok
++ action police rate 0.5kbit burst 2k conform-exceed drop/ok
+ check_fail $? "Incorrect success to add police action with too low rate"
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+@@ -327,7 +327,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 1.5kbit burst 1m conform-exceed drop/ok
++ action police rate 1.5kbit burst 2k conform-exceed drop/ok
+ check_err $? "Failed to add police action with low rate"
+
+ tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
+--
+2.51.0
+
--- /dev/null
+From b166222df84adc71c41438f934a0348cc2a2e93b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 10:21:46 +0800
+Subject: selftests: net: lib: Fix jq parsing error
+
+From: Yue Haibing <yuehaibing@huawei.com>
+
+[ Upstream commit 10ec0fc0ccc525abc807b0ca8ad5a26a0bd56361 ]
+
+The testcase failed as below:
+$./vlan_bridge_binding.sh
+...
++ adf_ip_link_set_up d1
++ local name=d1
++ shift
++ ip_link_is_up d1
++ ip_link_has_flag d1 UP
++ local name=d1
++ shift
++ local flag=UP
++ shift
+++ ip -j link show d1
+++ jq --arg flag UP 'any(.[].flags.[]; . == $flag)'
+jq: error: syntax error, unexpected '[', expecting FORMAT or QQSTRING_START
+ (Unix shell quoting issues?) at <top-level>, line 1:
+any(.[].flags.[]; . == $flag)
+jq: 1 compile error
+
+Remove the extra dot (.) after flags array to fix this.
+
+Fixes: 4baa1d3a5080 ("selftests: net: lib: Add ip_link_has_flag()")
+Signed-off-by: Yue Haibing <yuehaibing@huawei.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/20260211022146.190948-1-yuehaibing@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/lib.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh
+index 0ec131b339bc4..b40694573f4c7 100644
+--- a/tools/testing/selftests/net/lib.sh
++++ b/tools/testing/selftests/net/lib.sh
+@@ -577,7 +577,7 @@ ip_link_has_flag()
+ local flag=$1; shift
+
+ local state=$(ip -j link show "$name" |
+- jq --arg flag "$flag" 'any(.[].flags.[]; . == $flag)')
++ jq --arg flag "$flag" 'any(.[].flags[]; . == $flag)')
+ [[ $state == true ]]
+ }
+
+--
+2.51.0
+
--- /dev/null
+From dacaaa52341b932faa1ee8fcb28cb64cbba4f711 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 16:59:36 -0800
+Subject: selftests: netconsole: Increase port listening timeout
+
+From: Pin-yen Lin <treapking@google.com>
+
+[ Upstream commit a68a9bd086c2822d0c629443bd16ad1317afe501 ]
+
+wait_for_port() can wait up to 2 seconds with the sleep and the polling
+in wait_local_port_listen() combined. So, in netcons_basic.sh, the socat
+process could die before the test writes to the netconsole.
+
+Increase the timeout to 3 seconds to make netcons_basic.sh pass
+consistently.
+
+Fixes: 3dc6c76391cb ("selftests: net: Add IPv6 support to netconsole basic tests")
+Signed-off-by: Pin-yen Lin <treapking@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260210005939.3230550-1-treapking@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
+index ae8abff4be409..64d3941576d5d 100644
+--- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
++++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
+@@ -247,8 +247,8 @@ function listen_port_and_save_to() {
+ SOCAT_MODE="UDP6-LISTEN"
+ fi
+
+- # Just wait for 2 seconds
+- timeout 2 ip netns exec "${NAMESPACE}" \
++ # Just wait for 3 seconds
++ timeout 3 ip netns exec "${NAMESPACE}" \
+ socat "${SOCAT_MODE}":"${PORT}",fork "${OUTPUT}" 2> /dev/null
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 137d243f07b7208c07597994004462380dd0d0cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 19:51:59 -0800
+Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ]
+
+Since we started running selftests in NIPA we have been seeing
+tc_actions.sh generate a soft lockup warning on ~20% of the runs.
+On the pre-netdev foundation setup it was actually a missed irq
+splat from the console. Now it's either that or a lockup.
+
+I initially suspected a socket locking issue since the test
+is exercising local loopback with act_mirred.
+After hours of staring at this I noticed in strace that ncat
+when -o $file is specified _both_ saves the output to the file
+and still prints it to stdout. Because the file being sent
+is constructed with:
+
+ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred
+ ^^^^^^^^^
+
+the data printed is all \0. Most terminals don't display nul
+characters (and neither does vng output capture save them).
+But QEMU's serial console still has to poke them thru which
+is very slow and causes the lockup (if the file is >600kB).
+
+Replace the '-o $file' with '> $file'. This speeds the test up
+from 2m20s to 18s on debug kernels, and prevents the warnings.
+
+Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index ea89e558672db..86edbc7e2489b 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -223,7 +223,7 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 &
+ local rpid=$!
+ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+--
+2.51.0
+
block-allow-ioc_pr_read_-ioctls-with-blk_open_read.patch
io_uring-delay-sqarray-static-branch-disablement.patch
io_uring-cancel-de-unionize-file-and-user_data-in-st.patch
+fs-ntfs3-initialize-new-folios-before-use.patch
+fs-ntfs3-fix-ntfs_mount_options-leak-in-ntfs_fill_su.patch
+fs-ntfs3-rename-ni_readpage_cmpr-into-ni_read_folio_.patch
+fs-ntfs3-fix-deadlock-in-ni_read_folio_cmpr.patch
+fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch
+fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch
+tools-power-turbostat-amd-msr-offset-0x611-read-fail.patch
+tools-power-turbostat-harden-against-unexpected-valu.patch
+powercap-intel_rapl-remove-incorrect-cpu-check-in-pm.patch
+acpi-button-adjust-event-notification-routines.patch
+acpi-button-convert-the-driver-to-a-platform-one.patch
+acpi-button-call-device_init_wakeup-earlier-during-p.patch
+acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch
+powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch
+kbuild-add-objtool-to-top-level-clean-target.patch
+smb-client-fix-regression-with-mount-options-parsing.patch
+selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch
+objpool-fix-the-overestimation-of-object-pooling-met.patch
+acpi-pm-add-unused-power-resource-quirk-for-thundero.patch
+cpuidle-skip-governor-when-only-one-idle-state-is-av.patch
+ovpn-set-sk_user_data-before-overriding-callbacks.patch
+ovpn-fix-possible-use-after-free-in-ovpn_net_xmit.patch
+ovpn-fix-vpn-tx-bytes-counting.patch
+net-mctp-ensure-our-nlmsg-responses-are-initialised.patch
+selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch
+selftests-net-lib-fix-jq-parsing-error.patch
+net-stmmac-fix-oops-when-split-header-is-enabled.patch
+net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch
+net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch
+net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch
+net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch
+selftests-netconsole-increase-port-listening-timeout.patch
+ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch
+net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch
+fbnic-close-fw_log-race-between-users-and-teardown.patch
+libbpf-fix-invalid-write-loop-logic-in-bpf_linker__a.patch
+bpf-fix-a-potential-use-after-free-of-btf-object.patch
+bpf-add-a-map-btf-from-a-fd-array-more-consistently.patch
+eth-fbnic-set-fbnic_queue_rde_ctl0_en_hdr_split-on-r.patch
+eth-fbnic-increase-fbnic_hdr_bytes_min-from-128-to-2.patch
+eth-fbnic-set-dma_hint_l4-for-all-flows.patch
+ovpn-tcp-don-t-deref-null-sk_socket-member-after-tcp.patch
+net-usb-catc-enable-basic-endpoint-checking.patch
+xen-netback-reject-zero-queue-configuration-from-gue.patch
+net-rds-rds_sendmsg-should-not-discard-payload_len.patch
+net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch
+selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch
+selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch
+selftests-forwarding-fix-pedit-tests-failure-with-br.patch
+netfilter-nft_counter-serialize-reset-with-spinlock.patch
+netfilter-nft_quota-use-atomic64_xchg-for-reset.patch
+netfilter-nf_tables-revert-commit_mutex-usage-in-res.patch
+netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch
+ipvs-skip-ipv6-extension-headers-for-csum-checks.patch
+ipvs-do-not-keep-dest_dst-if-dev-is-going-down.patch
+net-remove-warn_on_once-when-accessing-forward-path-.patch
+netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch
+ipv6-fix-a-race-in-ip6_sock_set_v6only.patch
+bpftool-fix-truncated-netlink-dumps.patch
+net-psp-select-config_skb_extensions.patch
+net-do-not-delay-zero-copy-skbs-in-skb_attempt_defer.patch
+dpll-zl3073x-fix-ref-frequency-setting.patch
+ping-annotate-data-races-in-ping_lookup.patch
+selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch
+macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch
+eth-fbnic-add-validation-for-mtu-changes.patch
+icmp-prevent-possible-overflow-in-icmp_global_allow.patch
+inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch
+ipv6-icmp-remove-obsolete-code-in-icmpv6_xrlim_allow.patch
+octeontx2-af-fix-default-entries-mcam-entry-action.patch
+eth-fbnic-advertise-supported-xdp-features.patch
+bnge-fix-reserving-resources-from-fw.patch
+bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch
+net-mlx5-fix-multiport-device-check-over-light-sfs.patch
+net-mlx5e-fix-misidentification-of-aso-cqe-during-po.patch
+net-mlx5-fix-misidentification-of-write-combining-cq.patch
+net-mlx5e-macsec-add-aso-poll-loop-in-macsec_aso_set.patch
+net-mlx5e-fix-deadlocks-between-devlink-and-netdev-i.patch
+net-mlx5e-use-unsigned-for-mlx5e_get_max_num_channel.patch
+apparmor-fix-null-pointer-dereference-in-__unix_need.patch
+apparmor-fix-null-sock-in-aa_sock_file_perm.patch
+apparmor-allow-apparmor-to-handle-unaligned-dfa-tabl.patch
+apparmor-fix-optimize-table-creation-from-possibly-u.patch
+apparmor-return-enomem-in-unpack_perms_table-upon-al.patch
+apparmor-fix-boolean-argument-in-apparmor_mmap_file.patch
+apparmor-drop-in_atomic-flag-in-common_mmap-and-comm.patch
+apparmor-account-for-in_atomic-removal-in-common_fil.patch
+apparmor-move-check-for-aa_null-file-to-cover-all-ca.patch
+apparmor-fix-rlimit-for-posix-cpu-timers.patch
+apparmor-remove-apply_modes_to_perms-from-label_matc.patch
+apparmor-make-label_match-return-a-consistent-value.patch
+apparmor-avoid-per-cpu-hold-underflow-in-aa_get_buff.patch
+apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch
+apparmor-fix-aa_label-to-return-state-from-compount-.patch
+drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch
+drm-amdgpu-use-kvfree-instead-of-kfree-in-amdgpu_gmc.patch
+drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch
+drm-amdgpu-sdma5-enable-queue-resets-unconditionally.patch
+drm-amdgpu-sdma5.2-enable-queue-resets-unconditional.patch
+drm-amdgpu-sdma6-enable-queue-resets-unconditionally.patch
+drm-amdgpu-clean-up-the-amdgpu_cs_parser_bos.patch
+mshv-fix-srcu-protection-in-irqfd-resampler-ack-hand.patch
+regulator-mt6363-fix-interrmittent-timeout.patch
+asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch
+drm-i915-acpi-free-_dsm-package-when-no-connectors.patch
+asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch
+pci-validate-window-resource-type-in-pbus_select_win.patch
+drm-amd-display-fix-dc_link-null-handling-in-hpd-ini.patch
+drm-amdgpu-fix-missing-unwind-in-amdgpu_ib_schedule-.patch
+drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch
+drm-amd-display-reject-cursor-plane-on-dce-when-scal.patch
+drm-amd-display-fix-out-of-bounds-stream-encoder-ind.patch
+spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch
+gpio-cdev-avoid-null-dereference-in-linehandle_creat.patch
+s390-kexec-make-kexec_sig-available-when-config_modu.patch
+drm-xe-pf-fix-sysfs-initialization.patch
+drm-xe-configfs-fix-parameter-name-omitted-errors.patch
+drm-xe-mmio-avoid-double-adjust-in-64-bit-reads.patch
+drm-xe-xe2_hpg-fix-handling-of-wa_14019988906-wa_140.patch
+drm-xe-vf-avoid-reading-media-version-when-media-gt-.patch
+drm-xe-make-xe_modparam.force_vram_bar_size-signed.patch
+drm-xe-bo-redirect-faults-to-dummy-page-for-wedged-d.patch
+gpio-amd-fch-ionly-return-allowed-values-from-amd_fc.patch
+efi-fix-reservation-of-unaccepted-memory-table.patch
+btrfs-reset-block-group-size-class-when-it-becomes-e.patch
+btrfs-use-the-correct-type-to-initialize-block-reser.patch
+btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch
+drm-amd-display-use-dce-6-link-encoder-for-dce-6-ana.patch
+drm-amd-display-only-use-analog-link-encoder-with-an.patch
+drm-amd-display-only-use-analog-stream-encoder-with-.patch
+x86-hyperv-fix-error-pointer-dereference.patch
+asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch
+drm-amd-display-use-same-max-plane-scaling-limits-fo.patch
+drm-amd-display-don-t-call-find_analog_engine-twice.patch
+drm-amd-display-turn-off-dac-in-dce-link-encoder-usi.patch
+drm-amd-display-initialize-dac-in-dce-link-encoder-u.patch
+drm-amd-display-set-crtc-source-for-dac-using-regist.patch
+drm-amd-display-enable-dac-in-dce-link-encoder.patch
+pci-dwc-ep-always-clear-ib-maps-on-bar-update.patch
--- /dev/null
+From 5a81cb90d9490b67febd9f7017010edd0dacd112 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 01:10:07 -0300
+Subject: smb: client: fix regression with mount options parsing
+
+From: Paulo Alcantara <pc@manguebit.org>
+
+[ Upstream commit 72f4d48034864b93700d1d23fc418d90fa28d7ae ]
+
+After commit 1ef15fbe6771 ("cifs: client: enforce consistent handling
+of multichannel and max_channels"), invalid mount options started to
+be ignored, allowing cifs.ko to proceed with the mount instead of
+baling out.
+
+The problem was related to smb3_handle_conflicting_options() being
+called even when an invalid parameter had been parsed, overwriting the
+return value of vfs_parse_fs_string() in
+smb3_fs_context_parse_monolithic().
+
+Fix this by calling smb3_handle_conflicting_options() only when a
+valid mount option has been passed.
+
+Reproducer:
+
+$ mount.cifs //srv/share /mnt -o ${opts}
+$ mount -o remount,foo,${opts} /mnt # must fail
+
+Fixes: 1ef15fbe6771 ("cifs: client: enforce consistent handling of multichannel and max_channels")
+Reported-by: Xiaoli Feng <xifeng@redhat.com>
+Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
+Cc: David Howells <dhowells@redhat.com>
+Cc: linux-cifs@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/fs_context.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
+index d4291d3a9a485..2527d2d29f190 100644
+--- a/fs/smb/client/fs_context.c
++++ b/fs/smb/client/fs_context.c
+@@ -826,9 +826,7 @@ static int smb3_fs_context_parse_monolithic(struct fs_context *fc,
+ if (ret < 0)
+ break;
+ }
+- ret = smb3_handle_conflicting_options(fc);
+-
+- return ret;
++ return ret ?: smb3_handle_conflicting_options(fc);
+ }
+
+ /*
+--
+2.51.0
+
--- /dev/null
+From 13116967c2bef46ab490f332fd6b29e036ac6b07 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:41:40 +0800
+Subject: spi: wpcm-fiu: Fix potential NULL pointer dereference in
+ wpcm_fiu_probe()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Felix Gu <ustc.gu@gmail.com>
+
+[ Upstream commit 888a0a802c467bbe34a42167bdf9d7331333440a ]
+
+platform_get_resource_byname() can return NULL, which would cause a crash
+when passed the pointer to resource_size().
+
+Move the fiu->memory_size assignment after the error check for
+devm_ioremap_resource() to prevent the potential NULL pointer dereference.
+
+Fixes: 9838c182471e ("spi: wpcm-fiu: Add direct map support")
+Signed-off-by: Felix Gu <ustc.gu@gmail.com>
+Reviewed-by: J. Neuschäfer <j.ne@posteo.net>
+Link: https://patch.msgid.link/20260212-wpcm-v1-1-5b7c4f526aac@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-wpcm-fiu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c
+index a9aee2a6c7dcb..c47b56f0933f1 100644
+--- a/drivers/spi/spi-wpcm-fiu.c
++++ b/drivers/spi/spi-wpcm-fiu.c
+@@ -459,11 +459,11 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
+ fiu->memory = devm_ioremap_resource(dev, res);
+- fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+ if (IS_ERR(fiu->memory))
+ return dev_err_probe(dev, PTR_ERR(fiu->memory),
+ "Failed to map flash memory window\n");
+
++ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+ fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm");
+
+ wpcm_fiu_hw_init(fiu);
+--
+2.51.0
+
--- /dev/null
+From d566a9b82361571b0f47556cc4851ef8b8faa474 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 14:41:53 -0600
+Subject: tools/power turbostat: AMD: msr offset 0x611 read failed:
+ Input/output error
+
+From: Len Brown <len.brown@intel.com>
+
+[ Upstream commit 16cc8f249c702b7cbb4c2c2be7cd8f4fdd5d1d0c ]
+
+Turbostat exits during RAPL probe with:
+
+turbostat: cpu0: msr offset 0x611 read failed: Input/output error
+
+A binary with this bug can be used successfully with
+the option "--no-msr"
+
+Fix this regression by trusting the static AMD RAPL MSR offset.
+
+Fixes: 19476a592bf2 ("tools/power turbostat: Validate RAPL MSRs for AWS Nitro Hypervisor")
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/power/x86/turbostat/turbostat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
+index 5ad45c2ac5bd8..c4c8b6315fd26 100644
+--- a/tools/power/x86/turbostat/turbostat.c
++++ b/tools/power/x86/turbostat/turbostat.c
+@@ -2135,7 +2135,7 @@ off_t idx_to_offset(int idx)
+
+ switch (idx) {
+ case IDX_PKG_ENERGY:
+- if (valid_rapl_msrs & RAPL_AMD_F17H)
++ if (platform->plat_rapl_msrs & RAPL_AMD_F17H)
+ offset = MSR_PKG_ENERGY_STAT;
+ else
+ offset = MSR_PKG_ENERGY_STATUS;
+--
+2.51.0
+
--- /dev/null
+From 018510cb4c7a95a41294cc538ac54937c493c4f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Dec 2025 10:01:04 -0500
+Subject: tools/power turbostat: Harden against unexpected values
+
+From: Len Brown <len.brown@intel.com>
+
+[ Upstream commit d0f7093ad5e4aa37405da2669bca1a62d22b7025 ]
+
+Divide-by-zero resulted if LLC references == 0
+
+Pull the percentage division into pct() to centralize sanity checks there.
+
+Fixes: 8808292799b0 ("tools/power turbostat: Print "nan" for out of range percentages")
+
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/power/x86/turbostat/turbostat.c | 94 +++++++++++++++------------
+ 1 file changed, 51 insertions(+), 43 deletions(-)
+
+diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
+index c4c8b6315fd26..1b26d94c373fb 100644
+--- a/tools/power/x86/turbostat/turbostat.c
++++ b/tools/power/x86/turbostat/turbostat.c
+@@ -3001,22 +3001,30 @@ void print_header(char *delim)
+ }
+
+ /*
+- * pct()
++ * pct(numerator, denominator)
+ *
+- * If absolute value is < 1.1, return percentage
+- * otherwise, return nan
++ * Return sanity checked percentage (100.0 * numerator/denominotor)
+ *
+- * return value is appropriate for printing percentages with %f
+- * while flagging some obvious erroneous values.
++ * n < 0: nan
++ * d <= 0: nan
++ * n/d > 1.1: nan
+ */
+-double pct(double d)
++double pct(double numerator, double denominator)
+ {
++ double retval;
+
+- double abs = fabs(d);
++ if (numerator < 0)
++ return nan("");
+
+- if (abs < 1.10)
+- return (100.0 * d);
+- return nan("");
++ if (denominator <= 0)
++ return nan("");
++
++ retval = 100.0 * numerator / denominator;
++
++ if (retval > 110.0)
++ return nan("");
++
++ return retval;
+ }
+
+ int dump_counters(PER_THREAD_PARAMS)
+@@ -3046,7 +3054,7 @@ int dump_counters(PER_THREAD_PARAMS)
+
+ outp += sprintf(outp, "LLC refs: %lld", t->llc.references);
+ outp += sprintf(outp, "LLC miss: %lld", t->llc.misses);
+- outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses) / t->llc.references));
++ outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses), t->llc.references));
+
+ for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
+ outp += sprintf(outp, "tADDED [%d] %8s msr0x%x: %08llX %s\n", i, mp->name, mp->msr_num, t->counter[i], mp->sp->path);
+@@ -3261,7 +3269,7 @@ int format_counters(PER_THREAD_PARAMS)
+ outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 / units * t->aperf / interval_float);
+
+ if (DO_BIC(BIC_Busy))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf, tsc));
+
+ if (DO_BIC(BIC_Bzy_MHz)) {
+ if (has_base_hz)
+@@ -3302,7 +3310,7 @@ int format_counters(PER_THREAD_PARAMS)
+ outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), t->llc.references / interval_float / 1000);
+
+ if (DO_BIC(BIC_LLC_HIT))
+- outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses) / t->llc.references));
++ outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses), t->llc.references));
+ }
+
+ /* Added Thread Counters */
+@@ -3315,7 +3323,7 @@ int format_counters(PER_THREAD_PARAMS)
+ if (mp->type == COUNTER_USEC)
+ outp += print_float_value(&printed, delim, t->counter[i] / interval_float / 10000);
+ else
+- outp += print_float_value(&printed, delim, pct(t->counter[i] / tsc));
++ outp += print_float_value(&printed, delim, pct(t->counter[i], tsc));
+ }
+ }
+
+@@ -3329,7 +3337,7 @@ int format_counters(PER_THREAD_PARAMS)
+ if (pp->type == COUNTER_USEC)
+ outp += print_float_value(&printed, delim, t->perf_counter[i] / interval_float / 10000);
+ else
+- outp += print_float_value(&printed, delim, pct(t->perf_counter[i] / tsc));
++ outp += print_float_value(&printed, delim, pct(t->perf_counter[i], tsc));
+ }
+ }
+
+@@ -3343,34 +3351,34 @@ int format_counters(PER_THREAD_PARAMS)
+ break;
+
+ case PMT_TYPE_XTAL_TIME:
+- value_converted = pct(value_raw / crystal_hz / interval_float);
++ value_converted = pct(value_raw / crystal_hz, interval_float);
+ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
+ break;
+
+ case PMT_TYPE_TCORE_CLOCK:
+- value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float);
++ value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float);
+ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
+ }
+ }
+
+ /* C1 */
+ if (DO_BIC(BIC_CPU_c1))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1, tsc));
+
+ /* print per-core data only for 1st thread in core */
+ if (!is_cpu_first_thread_in_core(t, c))
+ goto done;
+
+ if (DO_BIC(BIC_CPU_c3))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3, tsc));
+ if (DO_BIC(BIC_CPU_c6))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6, tsc));
+ if (DO_BIC(BIC_CPU_c7))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7, tsc));
+
+ /* Mod%c6 */
+ if (DO_BIC(BIC_Mod_c6))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us, tsc));
+
+ if (DO_BIC(BIC_CoreTmp))
+ outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c);
+@@ -3386,7 +3394,7 @@ int format_counters(PER_THREAD_PARAMS)
+ else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
+ outp += print_decimal_value(mp->width, &printed, delim, c->counter[i]);
+ else if (mp->format == FORMAT_PERCENT)
+- outp += print_float_value(&printed, delim, pct(c->counter[i] / tsc));
++ outp += print_float_value(&printed, delim, pct(c->counter[i], tsc));
+ }
+
+ /* Added perf Core counters */
+@@ -3396,7 +3404,7 @@ int format_counters(PER_THREAD_PARAMS)
+ else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
+ outp += print_decimal_value(pp->width, &printed, delim, c->perf_counter[i]);
+ else if (pp->format == FORMAT_PERCENT)
+- outp += print_float_value(&printed, delim, pct(c->perf_counter[i] / tsc));
++ outp += print_float_value(&printed, delim, pct(c->perf_counter[i], tsc));
+ }
+
+ /* Added PMT Core counters */
+@@ -3409,12 +3417,12 @@ int format_counters(PER_THREAD_PARAMS)
+ break;
+
+ case PMT_TYPE_XTAL_TIME:
+- value_converted = pct(value_raw / crystal_hz / interval_float);
++ value_converted = pct(value_raw / crystal_hz, interval_float);
+ outp += print_float_value(&printed, delim, value_converted);
+ break;
+
+ case PMT_TYPE_TCORE_CLOCK:
+- value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float);
++ value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float);
+ outp += print_float_value(&printed, delim, value_converted);
+ }
+ }
+@@ -3470,39 +3478,39 @@ int format_counters(PER_THREAD_PARAMS)
+ if (DO_BIC(BIC_Totl_c0))
+ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100 * p->pkg_wtd_core_c0 / tsc); /* can exceed 100% */
+ if (DO_BIC(BIC_Any_c0))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0, tsc));
+ if (DO_BIC(BIC_GFX_c0))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0, tsc));
+ if (DO_BIC(BIC_CPUGFX))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0, tsc));
+
+ if (DO_BIC(BIC_Pkgpc2))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2, tsc));
+ if (DO_BIC(BIC_Pkgpc3))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3, tsc));
+ if (DO_BIC(BIC_Pkgpc6))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6, tsc));
+ if (DO_BIC(BIC_Pkgpc7))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7, tsc));
+ if (DO_BIC(BIC_Pkgpc8))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8, tsc));
+ if (DO_BIC(BIC_Pkgpc9))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9, tsc));
+ if (DO_BIC(BIC_Pkgpc10))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10 / tsc));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10, tsc));
+
+ if (DO_BIC(BIC_Diec6))
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz / interval_float));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz, interval_float));
+
+ if (DO_BIC(BIC_CPU_LPI)) {
+ if (p->cpu_lpi >= 0)
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0 / interval_float));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0, interval_float));
+ else
+ outp += sprintf(outp, "%s(neg)", (printed++ ? delim : ""));
+ }
+ if (DO_BIC(BIC_SYS_LPI)) {
+ if (p->sys_lpi >= 0)
+- outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0 / interval_float));
++ outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0, interval_float));
+ else
+ outp += sprintf(outp, "%s(neg)", (printed++ ? delim : ""));
+ }
+@@ -3542,7 +3550,7 @@ int format_counters(PER_THREAD_PARAMS)
+ else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
+ outp += print_decimal_value(mp->width, &printed, delim, p->counter[i]);
+ else if (mp->format == FORMAT_PERCENT)
+- outp += print_float_value(&printed, delim, pct(p->counter[i] / tsc));
++ outp += print_float_value(&printed, delim, pct(p->counter[i], tsc));
+ }
+
+ /* Added perf Package Counters */
+@@ -3554,7 +3562,7 @@ int format_counters(PER_THREAD_PARAMS)
+ else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE)
+ outp += print_decimal_value(pp->width, &printed, delim, p->perf_counter[i]);
+ else if (pp->format == FORMAT_PERCENT)
+- outp += print_float_value(&printed, delim, pct(p->perf_counter[i] / tsc));
++ outp += print_float_value(&printed, delim, pct(p->perf_counter[i], tsc));
+ }
+
+ /* Added PMT Package Counters */
+@@ -3567,12 +3575,12 @@ int format_counters(PER_THREAD_PARAMS)
+ break;
+
+ case PMT_TYPE_XTAL_TIME:
+- value_converted = pct(value_raw / crystal_hz / interval_float);
++ value_converted = pct(value_raw / crystal_hz, interval_float);
+ outp += print_float_value(&printed, delim, value_converted);
+ break;
+
+ case PMT_TYPE_TCORE_CLOCK:
+- value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float);
++ value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float);
+ outp += print_float_value(&printed, delim, value_converted);
+ }
+ }
+--
+2.51.0
+
--- /dev/null
+From 69474501fded49350ca3b03ee04bbb481926ea15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 13:09:03 -0600
+Subject: x86/hyperv: Fix error pointer dereference
+
+From: Ethan Tidmore <ethantidmore06@gmail.com>
+
+[ Upstream commit 705d01c8d78121ee1634bfc602ac4b0ad1438fab ]
+
+The function idle_thread_get() can return an error pointer and is not
+checked for it. Add check for error pointer.
+
+Detected by Smatch:
+arch/x86/hyperv/hv_vtl.c:126 hv_vtl_bringup_vcpu() error:
+'idle' dereferencing possible ERR_PTR()
+
+Fixes: 2b4b90e053a29 ("x86/hyperv: Use per cpu initial stack for vtl context")
+Signed-off-by: Ethan Tidmore <ethantidmore06@gmail.com>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/hyperv/hv_vtl.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c
+index c0edaed0efb30..9b6a9bc4ab760 100644
+--- a/arch/x86/hyperv/hv_vtl.c
++++ b/arch/x86/hyperv/hv_vtl.c
+@@ -110,7 +110,7 @@ static void hv_vtl_ap_entry(void)
+
+ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
+ {
+- u64 status;
++ u64 status, rsp, rip;
+ int ret = 0;
+ struct hv_enable_vp_vtl *input;
+ unsigned long irq_flags;
+@@ -123,9 +123,11 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
+ struct desc_struct *gdt;
+
+ struct task_struct *idle = idle_thread_get(cpu);
+- u64 rsp = (unsigned long)idle->thread.sp;
++ if (IS_ERR(idle))
++ return PTR_ERR(idle);
+
+- u64 rip = (u64)&hv_vtl_ap_entry;
++ rsp = (unsigned long)idle->thread.sp;
++ rip = (u64)&hv_vtl_ap_entry;
+
+ native_store_gdt(&gdt_ptr);
+ store_idt(&idt_ptr);
+--
+2.51.0
+
--- /dev/null
+From 622160f4a69e3b04099d0b7d7052d037897026a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 22:40:40 +0000
+Subject: xen-netback: reject zero-queue configuration from guest
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ]
+
+A malicious or buggy Xen guest can write "0" to the xenbus key
+"multi-queue-num-queues". The connect() function in the backend only
+validates the upper bound (requested_num_queues > xenvif_max_queues)
+but not zero, allowing requested_num_queues=0 to reach
+vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers
+WARN_ON_ONCE(!size) in __vmalloc_node_range().
+
+On systems with panic_on_warn=1, this allows a guest-to-host denial
+of service.
+
+The Xen network interface specification requires
+the queue count to be "greater than zero".
+
+Add a zero check to match the validation already present
+in xen-blkback, which has included this
+guard since its multi-queue support was added.
+
+Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/xen-netback/xenbus.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
+index a78a25b872409..61b547aab286a 100644
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -735,10 +735,11 @@ static void connect(struct backend_info *be)
+ */
+ requested_num_queues = xenbus_read_unsigned(dev->otherend,
+ "multi-queue-num-queues", 1);
+- if (requested_num_queues > xenvif_max_queues) {
++ if (requested_num_queues > xenvif_max_queues ||
++ requested_num_queues == 0) {
+ /* buggy or malicious guest */
+ xenbus_dev_fatal(dev, -EINVAL,
+- "guest requested %u queues, exceeding the maximum of %u.",
++ "guest requested %u queues, but valid range is 1 - %u.",
+ requested_num_queues, xenvif_max_queues);
+ return;
+ }
+--
+2.51.0
+
--- /dev/null
+From 9fa64217bad4ee164ebcbc2ee5a79285aa0f1910 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 21:22:54 +0000
+Subject: ACPI: CPPC: Fix remaining for_each_possible_cpu() to use online CPUs
+
+From: Sean V Kelley <skelley@nvidia.com>
+
+[ Upstream commit 56eb0c0ed345da7815274aa821a8546a073d7e97 ]
+
+per_cpu(cpc_desc_ptr, cpu) object is initialized for only the online
+CPUs via acpi_soft_cpu_online() --> __acpi_processor_start() -->
+acpi_cppc_processor_probe().
+
+However, send_pcc_cmd() and acpi_get_psd_map() still iterate over all
+possible CPUs. In acpi_get_psd_map(), encountering an offline CPU
+returns -EFAULT, causing cppc_cpufreq initialization to fail.
+
+This breaks systems booted with "nosmt" or "nosmt=force".
+
+Fix by using for_each_online_cpu() in both functions.
+
+Fixes: 80b8286aeec0 ("ACPI / CPPC: support for batching CPPC requests")
+Signed-off-by: Sean V Kelley <skelley@nvidia.com>
+Link: https://patch.msgid.link/20260211212254.30190-1-skelley@nvidia.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/cppc_acpi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
+index 16ac219ae6fe5..0bf3861cf79b1 100644
+--- a/drivers/acpi/cppc_acpi.c
++++ b/drivers/acpi/cppc_acpi.c
+@@ -347,7 +347,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd)
+ end:
+ if (cmd == CMD_WRITE) {
+ if (unlikely(ret)) {
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i);
+
+ if (!desc)
+@@ -509,7 +509,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data)
+ else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
+ cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+
+- for_each_possible_cpu(i) {
++ for_each_online_cpu(i) {
+ if (i == cpu)
+ continue;
+
+--
+2.51.0
+
--- /dev/null
+From 8896cecee33e47f81c0e59e2edfd2dbb2d72c1f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 15 Feb 2026 00:14:52 +0800
+Subject: ACPI: PM: Add unused power resource quirk for THUNDEROBOT ZERO
+
+From: Zhai Can <bczhc0@126.com>
+
+[ Upstream commit cd7ef20ba8c6e936dba133b4136537a8ada22976 ]
+
+On the THUNDEROBOT ZERO laptop, the second NVMe slot and the discrete
+NVIDIA GPU are both controlled by power-resource PXP. Due to the SSDT table
+bug (lack of reference), PXP will be shut dow as an "unused" power resource
+during initialization, making the NVMe slot #2 + NVIDIA both inaccessible.
+
+This issue was introduced by commit a1224f34d72a ("ACPI: PM: Check
+states of power resources during initialization"). Here are test
+results on the three consecutive commits:
+
+(bad again!) a1224f34d72a ACPI: PM: Check states of power resources during initialization
+(good) bc2836859643 ACPI: PM: Do not turn off power resources in unknown state
+(bad) 519d81956ee2 Linux 5.15-rc6
+
+On commit bc2836859643 ("ACPI: PM: Do not turn off power resources in
+unknown state") this was not an issue because the power resource state
+left UNKNOWN thus being ignored.
+
+See also commit 9b04d99788cf ("ACPI: PM: Do not turn of unused power
+resources on the Toshiba Click Mini") which is another almost identical
+case to this one.
+
+Fixes: a1224f34d72a ("ACPI: PM: Check states of power resources during initialization")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221087
+Signed-off-by: Zhai Can <bczhc0@126.com>
+Link: https://patch.msgid.link/20260214161452.2849346-1-bczhc0@126.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/power.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
+index c2c70139c4f1d..ff5fcd541e50f 100644
+--- a/drivers/acpi/power.c
++++ b/drivers/acpi/power.c
+@@ -1035,6 +1035,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
+ },
+ },
++ {
++ /*
++ * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power
++ * resource 'PXP' will be shut down on initialization, making
++ * the NVMe #2 and the NVIDIA dGPU both unavailable (they're
++ * both controlled by 'PXP').
++ */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"),
++ }
++
++ },
+ {}
+ };
+
+--
+2.51.0
+
--- /dev/null
+From 643db385c6725bc167f935c7a34ea25a73fe69e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 04:12:02 -0800
+Subject: apparmor: fix aa_label to return state from compount and component
+ match
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 9058798652c8bc0584ed1fb0766a1015046c06e8 ]
+
+aa-label_match is not correctly returning the state in all cases.
+The only reason this didn't cause a error is that all callers currently
+ignore the return value.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202602020631.wXgZosyU-lkp@intel.com/
+Fixes: a4c9efa4dbad6 ("apparmor: make label_match return a consistent value")
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 7289712df2414..d64c838f5d84e 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1344,7 +1344,7 @@ static int label_compound_match(struct aa_profile *profile,
+ * @request: permissions to request
+ * @perms: an initialized perms struct to add accumulation to
+ *
+- * Returns: 0 on success else ERROR
++ * Returns: the state the match finished in, may be the none matching state
+ *
+ * For the label A//&B//&C this does the perm match for each of A and B and C
+ * @perms should be preinitialized with allperms OR a previous permission
+@@ -1372,7 +1372,7 @@ static int label_components_match(struct aa_profile *profile,
+ }
+
+ /* no subcomponents visible - no change in perms */
+- return 0;
++ return state;
+
+ next:
+ tmp = *aa_lookup_perms(rules->policy, state);
+@@ -1388,13 +1388,13 @@ static int label_components_match(struct aa_profile *profile,
+ }
+
+ if ((perms->allow & request) != request)
+- return -EACCES;
++ return DFA_NOMATCH;
+
+- return 0;
++ return state;
+
+ fail:
+ *perms = nullperms;
+- return -EACCES;
++ return DFA_NOMATCH;
+ }
+
+ /**
+@@ -1416,7 +1416,7 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns,
+ request, perms);
+ if ((perms->allow & request) == request)
+- return 0;
++ return tmp;
+
+ /* failed compound_match try component matches */
+ *perms = allperms;
+--
+2.51.0
+
--- /dev/null
+From 99b9e2ab549a5b1d68637949be3c5b9c1c51c0a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 15:58:45 -0300
+Subject: apparmor: fix invalid deref of rawdata when export_binary is unset
+
+From: Georgia Garcia <georgia.garcia@canonical.com>
+
+[ Upstream commit df9ac55abd18628bd8cff687ea043660532a3654 ]
+
+If the export_binary parameter is disabled on runtime, profiles that
+were loaded before that will still have their rawdata stored in
+apparmorfs, with a symbolic link to the rawdata on the policy
+directory. When one of those profiles are replaced, the rawdata is set
+to NULL, but when trying to resolve the symbolic links to rawdata for
+that profile, it will try to dereference profile->rawdata->name when
+profile->rawdata is now NULL causing an oops. Fix it by checking if
+rawdata is set.
+
+[ 168.653080] BUG: kernel NULL pointer dereference, address: 0000000000000088
+[ 168.657420] #PF: supervisor read access in kernel mode
+[ 168.660619] #PF: error_code(0x0000) - not-present page
+[ 168.663613] PGD 0 P4D 0
+[ 168.665450] Oops: Oops: 0000 [#1] SMP NOPTI
+[ 168.667836] CPU: 1 UID: 0 PID: 1729 Comm: ls Not tainted 6.19.0-rc7+ #3 PREEMPT(voluntary)
+[ 168.672308] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+[ 168.679327] RIP: 0010:rawdata_get_link_base.isra.0+0x23/0x330
+[ 168.682768] Code: 90 90 90 90 90 90 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 18 48 89 55 d0 48 85 ff 0f 84 e3 01 00 00 <48> 83 3c 25 88 00 00 00 00 0f 84 d4 01 00 00 49 89 f6 49 89 cc e8
+[ 168.689818] RSP: 0018:ffffcdcb8200fb80 EFLAGS: 00010282
+[ 168.690871] RAX: ffffffffaee74ec0 RBX: 0000000000000000 RCX: ffffffffb0120158
+[ 168.692251] RDX: ffffcdcb8200fbe0 RSI: ffff88c187c9fa80 RDI: ffff88c186c98a80
+[ 168.693593] RBP: ffffcdcb8200fbc0 R08: 0000000000000000 R09: 0000000000000000
+[ 168.694941] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88c186c98a80
+[ 168.696289] R13: 00007fff005aaa20 R14: 0000000000000080 R15: ffff88c188f4fce0
+[ 168.697637] FS: 0000790e81c58280(0000) GS:ffff88c20a957000(0000) knlGS:0000000000000000
+[ 168.699227] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 168.700349] CR2: 0000000000000088 CR3: 000000012fd3e000 CR4: 0000000000350ef0
+[ 168.701696] Call Trace:
+[ 168.702325] <TASK>
+[ 168.702995] rawdata_get_link_data+0x1c/0x30
+[ 168.704145] vfs_readlink+0xd4/0x160
+[ 168.705152] do_readlinkat+0x114/0x180
+[ 168.706214] __x64_sys_readlink+0x1e/0x30
+[ 168.708653] x64_sys_call+0x1d77/0x26b0
+[ 168.709525] do_syscall_64+0x81/0x500
+[ 168.710348] ? do_statx+0x72/0xb0
+[ 168.711109] ? putname+0x3e/0x80
+[ 168.711845] ? __x64_sys_statx+0xb7/0x100
+[ 168.712711] ? x64_sys_call+0x10fc/0x26b0
+[ 168.713577] ? do_syscall_64+0xbf/0x500
+[ 168.714412] ? do_user_addr_fault+0x1d2/0x8d0
+[ 168.715404] ? irqentry_exit+0xb2/0x740
+[ 168.716359] ? exc_page_fault+0x90/0x1b0
+[ 168.717307] entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+Fixes: 1180b4c757aab ("apparmor: fix dangling symlinks to policy rawdata after replacement")
+Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/apparmorfs.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index c2a09056c7014..6885ecd4afddc 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -1637,6 +1637,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry,
+
+ label = aa_get_label_rcu(&proxy->label);
+ profile = labels_profile(label);
++
++ /* rawdata can be null when aa_g_export_binary is unset during
++ * runtime and a profile is replaced
++ */
++ if (!profile->rawdata) {
++ aa_put_label(label);
++ return ERR_PTR(-ENOENT);
++ }
++
+ depth = profile_depth(profile);
+ target = gen_symlink_name(depth, profile->rawdata->name, name);
+ aa_put_label(label);
+--
+2.51.0
+
--- /dev/null
+From 0698ba1162cd3c5d337887992f51b36f7f07edb8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Nov 2025 15:07:42 -0800
+Subject: apparmor: fix NULL sock in aa_sock_file_perm
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 00b67657535dfea56e84d11492f5c0f61d0af297 ]
+
+Deal with the potential that sock and sock-sk can be NULL during
+socket setup or teardown. This could lead to an oops. The fix for NULL
+pointer dereference in __unix_needs_revalidation shows this is at
+least possible for af_unix sockets. While the fix for af_unix sockets
+applies for newer mediation this is still the fall back path for older
+af_unix mediation and other sockets, so ensure it is covered.
+
+Fixes: 56974a6fcfef6 ("apparmor: add base infastructure for socket mediation")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/net.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index 704c171232ab4..814e8319d43e0 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -190,8 +190,10 @@ int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label,
+ const char *op, u32 request, struct socket *sock)
+ {
+ AA_BUG(!label);
+- AA_BUG(!sock);
+- AA_BUG(!sock->sk);
++
++ /* sock && sock->sk can be NULL for sockets being set up or torn down */
++ if (!sock || !sock->sk)
++ return 0;
+
+ return aa_label_sk_perm(subj_cred, label, op, request, sock->sk);
+ }
+--
+2.51.0
+
--- /dev/null
+From 3258003c56b414c36cf171bcff15ce1f1597cf59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Nov 2025 14:16:54 -0800
+Subject: apparmor: fix rlimit for posix cpu timers
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 6ca56813f4a589f536adceb42882855d91fb1125 ]
+
+Posix cpu timers requires an additional step beyond setting the rlimit.
+Refactor the code so its clear when what code is setting the
+limit and conditionally update the posix cpu timers when appropriate.
+
+Fixes: baa73d9e478ff ("posix-timers: Make them configurable")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/resource.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index dcc94c3153d51..a7eee815f1215 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -201,6 +201,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l)
+ rules->rlimits.limits[j].rlim_max);
+ /* soft limit should not exceed hard limit */
+ rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max);
++ if (j == RLIMIT_CPU &&
++ rlim->rlim_cur != RLIM_INFINITY &&
++ IS_ENABLED(CONFIG_POSIX_TIMERS))
++ (void) update_rlimit_cpu(current->group_leader,
++ rlim->rlim_cur);
+ }
+ }
+ }
+--
+2.51.0
+
--- /dev/null
+From 089edea40e0661221ad1fb6787d985e522d4636c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Nov 2025 23:59:38 -0800
+Subject: apparmor: make label_match return a consistent value
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit a4c9efa4dbad6dacad6e8b274e30e814c8353097 ]
+
+compound match is inconsistent in returning a state or an integer error
+this is problemati if the error is ever used as a state in the state
+machine
+
+Fixes: f1bd904175e81 ("apparmor: add the base fns() for domain labels")
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 217bd6709023f..7289712df2414 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1288,7 +1288,7 @@ static inline aa_state_t match_component(struct aa_profile *profile,
+ * @request: permissions to request
+ * @perms: perms struct to set
+ *
+- * Returns: 0 on success else ERROR
++ * Returns: state match stopped at or DFA_NOMATCH if aborted early
+ *
+ * For the label A//&B//&C this does the perm match for A//&B//&C
+ * @perms should be preinitialized with allperms OR a previous permission
+@@ -1315,7 +1315,7 @@ static int label_compound_match(struct aa_profile *profile,
+
+ /* no component visible */
+ *perms = allperms;
+- return 0;
++ return state;
+
+ next:
+ label_for_each_cont(i, label, tp) {
+@@ -1327,14 +1327,11 @@ static int label_compound_match(struct aa_profile *profile,
+ goto fail;
+ }
+ *perms = *aa_lookup_perms(rules->policy, state);
+- if ((perms->allow & request) != request)
+- return -EACCES;
+-
+- return 0;
++ return state;
+
+ fail:
+ *perms = nullperms;
+- return state;
++ return DFA_NOMATCH;
+ }
+
+ /**
+@@ -1416,11 +1413,12 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+ struct aa_label *label, aa_state_t state, bool subns,
+ u32 request, struct aa_perms *perms)
+ {
+- int error = label_compound_match(profile, rules, label, state, subns,
+- request, perms);
+- if (!error)
+- return error;
++ aa_state_t tmp = label_compound_match(profile, rules, label, state, subns,
++ request, perms);
++ if ((perms->allow & request) == request)
++ return 0;
+
++ /* failed compound_match try component matches */
+ *perms = allperms;
+ return label_components_match(profile, rules, label, state, subns,
+ request, perms);
+--
+2.51.0
+
--- /dev/null
+From bc18bf3c0d991a851a98a34f930955a4522cffb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Apr 2023 03:27:36 -0700
+Subject: apparmor: provide separate audit messages for file and policy checks
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 75c77e9e0713fddbe99a21a036aa6482402f9e34 ]
+
+Improve policy load failure messages by identifying which dfa the
+verification check failed in.
+
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy_unpack.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index a1de48c2d826b..cefda5e5b6ed0 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -1249,12 +1249,18 @@ static int verify_profile(struct aa_profile *profile)
+ if (!rules)
+ return 0;
+
+- if ((rules->file.dfa && !verify_dfa_accept_index(rules->file.dfa,
+- rules->file.size)) ||
+- (rules->policy.dfa &&
+- !verify_dfa_accept_index(rules->policy.dfa, rules->policy.size))) {
++ if (rules->file.dfa && !verify_dfa_accept_index(rules->file.dfa,
++ rules->file.size)) {
+ audit_iface(profile, NULL, NULL,
+- "Unpack: Invalid named transition", NULL, -EPROTO);
++ "Unpack: file Invalid named transition", NULL,
++ -EPROTO);
++ return -EPROTO;
++ }
++ if (rules->policy.dfa &&
++ !verify_dfa_accept_index(rules->policy.dfa, rules->policy.size)) {
++ audit_iface(profile, NULL, NULL,
++ "Unpack: policy Invalid named transition", NULL,
++ -EPROTO);
+ return -EPROTO;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From b90954646faa93d31283dca73b609d1ea4b282c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Apr 2023 05:32:52 -0700
+Subject: apparmor: refcount the pdb
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 98b824ff8984fd523fc264fbb13208098ab09da3 ]
+
+With the move to permission tables the dfa is no longer a stand
+alone entity when used, needing a minimum of a permission table.
+However it still could be shared among different pdbs each using
+a different permission table.
+
+Instead of duping the permission table when sharing a pdb, add a
+refcount to the pdb so it can be easily shared.
+
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/apparmorfs.c | 18 ++---
+ security/apparmor/domain.c | 60 ++++++++--------
+ security/apparmor/file.c | 12 ++--
+ security/apparmor/include/lib.h | 2 +
+ security/apparmor/include/match.h | 6 --
+ security/apparmor/include/policy.h | 49 +++++++++----
+ security/apparmor/ipc.c | 4 +-
+ security/apparmor/label.c | 18 ++---
+ security/apparmor/lib.c | 4 +-
+ security/apparmor/lsm.c | 63 +++++++++++++++++
+ security/apparmor/match.c | 44 ------------
+ security/apparmor/mount.c | 20 +++---
+ security/apparmor/net.c | 4 +-
+ security/apparmor/policy.c | 58 +++++++++++-----
+ security/apparmor/policy_unpack.c | 108 +++++++++++++----------------
+ 15 files changed, 260 insertions(+), 210 deletions(-)
+
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index 23b2853ce3c42..c2a09056c7014 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -619,23 +619,23 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
+
+ if (profile_unconfined(profile))
+ return;
+- if (rules->file.dfa && *match_str == AA_CLASS_FILE) {
+- state = aa_dfa_match_len(rules->file.dfa,
+- rules->file.start[AA_CLASS_FILE],
++ if (rules->file->dfa && *match_str == AA_CLASS_FILE) {
++ state = aa_dfa_match_len(rules->file->dfa,
++ rules->file->start[AA_CLASS_FILE],
+ match_str + 1, match_len - 1);
+ if (state) {
+ struct path_cond cond = { };
+
+- tmp = *(aa_lookup_fperms(&(rules->file), state, &cond));
++ tmp = *(aa_lookup_fperms(rules->file, state, &cond));
+ }
+- } else if (rules->policy.dfa) {
++ } else if (rules->policy->dfa) {
+ if (!RULE_MEDIATES(rules, *match_str))
+ return; /* no change to current perms */
+- state = aa_dfa_match_len(rules->policy.dfa,
+- rules->policy.start[0],
++ state = aa_dfa_match_len(rules->policy->dfa,
++ rules->policy->start[0],
+ match_str, match_len);
+ if (state)
+- tmp = *aa_lookup_perms(&rules->policy, state);
++ tmp = *aa_lookup_perms(rules->policy, state);
+ }
+ aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum_raw(perms, &tmp);
+@@ -1096,7 +1096,7 @@ static int seq_profile_attach_show(struct seq_file *seq, void *v)
+ struct aa_profile *profile = labels_profile(label);
+ if (profile->attach.xmatch_str)
+ seq_printf(seq, "%s\n", profile->attach.xmatch_str);
+- else if (profile->attach.xmatch.dfa)
++ else if (profile->attach.xmatch->dfa)
+ seq_puts(seq, "<unknown>\n");
+ else
+ seq_printf(seq, "%s\n", profile->base.name);
+diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
+index 543105cf7e334..d6500ec4f6b63 100644
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -77,7 +77,7 @@ static int may_change_ptraced_domain(const struct cred *to_cred,
+ /**** TODO: dedup to aa_label_match - needs perm and dfa, merging
+ * specifically this is an exact copy of aa_label_match except
+ * aa_compute_perms is replaced with aa_compute_fperms
+- * and policy.dfa with file.dfa
++ * and policy->dfa with file->dfa
+ ****/
+ /* match a profile and its associated ns component if needed
+ * Assumes visibility test has already been done.
+@@ -93,16 +93,16 @@ static inline aa_state_t match_component(struct aa_profile *profile,
+ const char *ns_name;
+
+ if (stack)
+- state = aa_dfa_match(rules->file.dfa, state, "&");
++ state = aa_dfa_match(rules->file->dfa, state, "&");
+ if (profile->ns == tp->ns)
+- return aa_dfa_match(rules->file.dfa, state, tp->base.hname);
++ return aa_dfa_match(rules->file->dfa, state, tp->base.hname);
+
+ /* try matching with namespace name and then profile */
+ ns_name = aa_ns_name(profile->ns, tp->ns, true);
+- state = aa_dfa_match_len(rules->file.dfa, state, ":", 1);
+- state = aa_dfa_match(rules->file.dfa, state, ns_name);
+- state = aa_dfa_match_len(rules->file.dfa, state, ":", 1);
+- return aa_dfa_match(rules->file.dfa, state, tp->base.hname);
++ state = aa_dfa_match_len(rules->file->dfa, state, ":", 1);
++ state = aa_dfa_match(rules->file->dfa, state, ns_name);
++ state = aa_dfa_match_len(rules->file->dfa, state, ":", 1);
++ return aa_dfa_match(rules->file->dfa, state, tp->base.hname);
+ }
+
+ /**
+@@ -150,12 +150,12 @@ static int label_compound_match(struct aa_profile *profile,
+ label_for_each_cont(i, label, tp) {
+ if (!aa_ns_visible(profile->ns, tp->ns, subns))
+ continue;
+- state = aa_dfa_match(rules->file.dfa, state, "//&");
++ state = aa_dfa_match(rules->file->dfa, state, "//&");
+ state = match_component(profile, tp, false, state);
+ if (!state)
+ goto fail;
+ }
+- *perms = *(aa_lookup_fperms(&(rules->file), state, &cond));
++ *perms = *(aa_lookup_fperms(rules->file, state, &cond));
+ aa_apply_modes_to_perms(profile, perms);
+ if ((perms->allow & request) != request)
+ return -EACCES;
+@@ -210,7 +210,7 @@ static int label_components_match(struct aa_profile *profile,
+ return 0;
+
+ next:
+- tmp = *(aa_lookup_fperms(&(rules->file), state, &cond));
++ tmp = *(aa_lookup_fperms(rules->file, state, &cond));
+ aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ label_for_each_cont(i, label, tp) {
+@@ -219,7 +219,7 @@ static int label_components_match(struct aa_profile *profile,
+ state = match_component(profile, tp, stack, start);
+ if (!state)
+ goto fail;
+- tmp = *(aa_lookup_fperms(&(rules->file), state, &cond));
++ tmp = *(aa_lookup_fperms(rules->file, state, &cond));
+ aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ }
+@@ -316,7 +316,7 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
+ might_sleep();
+
+ /* transition from exec match to xattr set */
+- state = aa_dfa_outofband_transition(attach->xmatch.dfa, state);
++ state = aa_dfa_outofband_transition(attach->xmatch->dfa, state);
+ d = bprm->file->f_path.dentry;
+
+ for (i = 0; i < attach->xattr_count; i++) {
+@@ -330,20 +330,20 @@ static int aa_xattrs_match(const struct linux_binprm *bprm,
+ * that not present xattr can be distinguished from a 0
+ * length value or rule that matches any value
+ */
+- state = aa_dfa_null_transition(attach->xmatch.dfa,
++ state = aa_dfa_null_transition(attach->xmatch->dfa,
+ state);
+ /* Check xattr value */
+- state = aa_dfa_match_len(attach->xmatch.dfa, state,
++ state = aa_dfa_match_len(attach->xmatch->dfa, state,
+ value, size);
+- index = ACCEPT_TABLE(attach->xmatch.dfa)[state];
+- perm = attach->xmatch.perms[index].allow;
++ index = ACCEPT_TABLE(attach->xmatch->dfa)[state];
++ perm = attach->xmatch->perms[index].allow;
+ if (!(perm & MAY_EXEC)) {
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+ /* transition to next element */
+- state = aa_dfa_outofband_transition(attach->xmatch.dfa, state);
++ state = aa_dfa_outofband_transition(attach->xmatch->dfa, state);
+ if (size < 0) {
+ /*
+ * No xattr match, so verify if transition to
+@@ -412,16 +412,16 @@ static struct aa_label *find_attach(const struct linux_binprm *bprm,
+ * as another profile, signal a conflict and refuse to
+ * match.
+ */
+- if (attach->xmatch.dfa) {
++ if (attach->xmatch->dfa) {
+ unsigned int count;
+ aa_state_t state;
+ u32 index, perm;
+
+- state = aa_dfa_leftmatch(attach->xmatch.dfa,
+- attach->xmatch.start[AA_CLASS_XMATCH],
++ state = aa_dfa_leftmatch(attach->xmatch->dfa,
++ attach->xmatch->start[AA_CLASS_XMATCH],
+ name, &count);
+- index = ACCEPT_TABLE(attach->xmatch.dfa)[state];
+- perm = attach->xmatch.perms[index].allow;
++ index = ACCEPT_TABLE(attach->xmatch->dfa)[state];
++ perm = attach->xmatch->perms[index].allow;
+ /* any accepting state means a valid match. */
+ if (perm & MAY_EXEC) {
+ int ret = 0;
+@@ -524,7 +524,7 @@ struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
+ /* TODO: move lookup parsing to unpack time so this is a straight
+ * index into the resultant label
+ */
+- for (*name = rules->file.trans.table[index]; !label && *name;
++ for (*name = rules->file->trans.table[index]; !label && *name;
+ *name = next_name(xtype, *name)) {
+ if (xindex & AA_X_CHILD) {
+ struct aa_profile *new_profile;
+@@ -577,7 +577,7 @@ static struct aa_label *x_to_label(struct aa_profile *profile,
+ break;
+ case AA_X_TABLE:
+ /* TODO: fix when perm mapping done at unload */
+- stack = rules->file.trans.table[xindex & AA_X_INDEX_MASK];
++ stack = rules->file->trans.table[xindex & AA_X_INDEX_MASK];
+ if (*stack != '&') {
+ /* released by caller */
+ new = x_table_lookup(profile, xindex, lookupname);
+@@ -636,7 +636,7 @@ static struct aa_label *profile_transition(const struct cred *subj_cred,
+ typeof(*rules), list);
+ struct aa_label *new = NULL;
+ const char *info = NULL, *name = NULL, *target = NULL;
+- aa_state_t state = rules->file.start[AA_CLASS_FILE];
++ aa_state_t state = rules->file->start[AA_CLASS_FILE];
+ struct aa_perms perms = {};
+ bool nonewprivs = false;
+ int error = 0;
+@@ -670,7 +670,7 @@ static struct aa_label *profile_transition(const struct cred *subj_cred,
+ }
+
+ /* find exec permissions for name */
+- state = aa_str_perms(&(rules->file), state, name, cond, &perms);
++ state = aa_str_perms(rules->file, state, name, cond, &perms);
+ if (perms.allow & MAY_EXEC) {
+ /* exec permission determine how to transition */
+ new = x_to_label(profile, bprm, name, perms.xindex, &target,
+@@ -736,7 +736,7 @@ static int profile_onexec(const struct cred *subj_cred,
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
+- aa_state_t state = rules->file.start[AA_CLASS_FILE];
++ aa_state_t state = rules->file->start[AA_CLASS_FILE];
+ struct aa_perms perms = {};
+ const char *xname = NULL, *info = "change_profile onexec";
+ int error = -EACCES;
+@@ -769,7 +769,7 @@ static int profile_onexec(const struct cred *subj_cred,
+ }
+
+ /* find exec permissions for name */
+- state = aa_str_perms(&(rules->file), state, xname, cond, &perms);
++ state = aa_str_perms(rules->file, state, xname, cond, &perms);
+ if (!(perms.allow & AA_MAY_ONEXEC)) {
+ info = "no change_onexec valid for executable";
+ goto audit;
+@@ -778,7 +778,7 @@ static int profile_onexec(const struct cred *subj_cred,
+ * onexec permission is linked to exec with a standard pairing
+ * exec\0change_profile
+ */
+- state = aa_dfa_null_transition(rules->file.dfa, state);
++ state = aa_dfa_null_transition(rules->file->dfa, state);
+ error = change_profile_perms(profile, onexec, stack, AA_MAY_ONEXEC,
+ state, &perms);
+ if (error) {
+@@ -1298,7 +1298,7 @@ static int change_profile_perms_wrapper(const char *op, const char *name,
+
+ if (!error)
+ error = change_profile_perms(profile, target, stack, request,
+- rules->file.start[AA_CLASS_FILE],
++ rules->file->start[AA_CLASS_FILE],
+ perms);
+ if (error)
+ error = aa_audit_file(subj_cred, profile, perms, op, request,
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
+index a51b83cf69689..e9e71d7bdcb6e 100644
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -236,7 +236,7 @@ static int __aa_path_perm(const char *op, const struct cred *subj_cred,
+
+ if (profile_unconfined(profile))
+ return 0;
+- aa_str_perms(&(rules->file), rules->file.start[AA_CLASS_FILE],
++ aa_str_perms(rules->file, rules->file->start[AA_CLASS_FILE],
+ name, cond, perms);
+ if (request & ~perms->allow)
+ e = -EACCES;
+@@ -353,16 +353,16 @@ static int profile_path_link(const struct cred *subj_cred,
+
+ error = -EACCES;
+ /* aa_str_perms - handles the case of the dfa being NULL */
+- state = aa_str_perms(&(rules->file),
+- rules->file.start[AA_CLASS_FILE], lname,
++ state = aa_str_perms(rules->file,
++ rules->file->start[AA_CLASS_FILE], lname,
+ cond, &lperms);
+
+ if (!(lperms.allow & AA_MAY_LINK))
+ goto audit;
+
+ /* test to see if target can be paired with link */
+- state = aa_dfa_null_transition(rules->file.dfa, state);
+- aa_str_perms(&(rules->file), state, tname, cond, &perms);
++ state = aa_dfa_null_transition(rules->file->dfa, state);
++ aa_str_perms(rules->file, state, tname, cond, &perms);
+
+ /* force audit/quiet masks for link are stored in the second entry
+ * in the link pair.
+@@ -384,7 +384,7 @@ static int profile_path_link(const struct cred *subj_cred,
+ /* Do link perm subset test requiring allowed permission on link are
+ * a subset of the allowed permissions on target.
+ */
+- aa_str_perms(&(rules->file), rules->file.start[AA_CLASS_FILE],
++ aa_str_perms(rules->file, rules->file->start[AA_CLASS_FILE],
+ tname, cond, &perms);
+
+ /* AA_MAY_LINK is not considered in the subset test */
+diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h
+index 6e88e99da80f6..1ec00113a056f 100644
+--- a/security/apparmor/include/lib.h
++++ b/security/apparmor/include/lib.h
+@@ -16,6 +16,8 @@
+
+ #include "match.h"
+
++extern struct aa_dfa *stacksplitdfa;
++
+ /*
+ * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
+ * which is not related to profile accesses.
+diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h
+index e59305abb85a3..ae31a8a631fc6 100644
+--- a/security/apparmor/include/match.h
++++ b/security/apparmor/include/match.h
+@@ -102,9 +102,6 @@ struct aa_dfa {
+ struct table_header *tables[YYTD_ID_TSIZE];
+ };
+
+-extern struct aa_dfa *nulldfa;
+-extern struct aa_dfa *stacksplitdfa;
+-
+ #define byte_to_byte(X) (X)
+
+ #define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX) \
+@@ -122,9 +119,6 @@ static inline size_t table_size(size_t len, size_t el_size)
+ return ALIGN(sizeof(struct table_header) + len * el_size, 8);
+ }
+
+-int aa_setup_dfa_engine(void);
+-void aa_teardown_dfa_engine(void);
+-
+ #define aa_state_t unsigned int
+
+ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags);
+diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
+index fa15a5c7febb8..bb682d5134129 100644
+--- a/security/apparmor/include/policy.h
++++ b/security/apparmor/include/policy.h
+@@ -74,12 +74,14 @@ enum profile_mode {
+
+
+ /* struct aa_policydb - match engine for a policy
++ * count: refcount for the pdb
+ * dfa: dfa pattern match
+ * perms: table of permissions
+ * strs: table of strings, index by x
+ * start: set of start states for the different classes of data
+ */
+ struct aa_policydb {
++ struct kref count;
+ struct aa_dfa *dfa;
+ struct {
+ struct aa_perms *perms;
+@@ -89,13 +91,36 @@ struct aa_policydb {
+ aa_state_t start[AA_CLASS_LAST + 1];
+ };
+
+-static inline void aa_destroy_policydb(struct aa_policydb *policy)
++extern struct aa_policydb *nullpdb;
++
++struct aa_policydb *aa_alloc_pdb(gfp_t gfp);
++void aa_pdb_free_kref(struct kref *kref);
++
++/**
++ * aa_get_pdb - increment refcount on @pdb
++ * @pdb: policydb (MAYBE NULL)
++ *
++ * Returns: pointer to @pdb if @pdb is NULL will return NULL
++ * Requires: @pdb must be held with valid refcount when called
++ */
++static inline struct aa_policydb *aa_get_pdb(struct aa_policydb *pdb)
+ {
+- aa_put_dfa(policy->dfa);
+- if (policy->perms)
+- kvfree(policy->perms);
+- aa_free_str_table(&policy->trans);
++ if (pdb)
++ kref_get(&(pdb->count));
+
++ return pdb;
++}
++
++/**
++ * aa_put_pdb - put a pdb refcount
++ * @pdb: pdb to put refcount (MAYBE NULL)
++ *
++ * Requires: if @pdb != NULL that a valid refcount be held
++ */
++static inline void aa_put_pdb(struct aa_policydb *pdb)
++{
++ if (pdb)
++ kref_put(&pdb->count, aa_pdb_free_kref);
+ }
+
+ static inline struct aa_perms *aa_lookup_perms(struct aa_policydb *policy,
+@@ -139,8 +164,8 @@ struct aa_ruleset {
+ int size;
+
+ /* TODO: merge policy and file */
+- struct aa_policydb policy;
+- struct aa_policydb file;
++ struct aa_policydb *policy;
++ struct aa_policydb *file;
+ struct aa_caps caps;
+
+ struct aa_rlimit rlimits;
+@@ -159,7 +184,7 @@ struct aa_ruleset {
+ */
+ struct aa_attachment {
+ const char *xmatch_str;
+- struct aa_policydb xmatch;
++ struct aa_policydb *xmatch;
+ unsigned int xmatch_len;
+ int xattr_count;
+ char **xattrs;
+@@ -276,10 +301,10 @@ static inline aa_state_t RULE_MEDIATES(struct aa_ruleset *rules,
+ unsigned char class)
+ {
+ if (class <= AA_CLASS_LAST)
+- return rules->policy.start[class];
++ return rules->policy->start[class];
+ else
+- return aa_dfa_match_len(rules->policy.dfa,
+- rules->policy.start[0], &class, 1);
++ return aa_dfa_match_len(rules->policy->dfa,
++ rules->policy->start[0], &class, 1);
+ }
+
+ static inline aa_state_t RULE_MEDIATES_AF(struct aa_ruleset *rules, u16 AF)
+@@ -289,7 +314,7 @@ static inline aa_state_t RULE_MEDIATES_AF(struct aa_ruleset *rules, u16 AF)
+
+ if (!state)
+ return DFA_NOMATCH;
+- return aa_dfa_match_len(rules->policy.dfa, state, (char *) &be_af, 2);
++ return aa_dfa_match_len(rules->policy->dfa, state, (char *) &be_af, 2);
+ }
+
+ static inline aa_state_t ANY_RULE_MEDIATES(struct list_head *head,
+diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
+index c0d0dbd7b4c4b..0cdf4340b02d5 100644
+--- a/security/apparmor/ipc.c
++++ b/security/apparmor/ipc.c
+@@ -92,8 +92,8 @@ static int profile_signal_perm(const struct cred *cred,
+ ad->subj_cred = cred;
+ ad->peer = peer;
+ /* TODO: secondary cache check <profile, profile, perm> */
+- state = aa_dfa_next(rules->policy.dfa,
+- rules->policy.start[AA_CLASS_SIGNAL],
++ state = aa_dfa_next(rules->policy->dfa,
++ rules->policy->start[AA_CLASS_SIGNAL],
+ ad->signal);
+ aa_label_match(profile, rules, peer, state, false, request, &perms);
+ aa_apply_modes_to_perms(profile, &perms);
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 8a2af96f4da57..178eca800ddaf 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1269,14 +1269,14 @@ static inline aa_state_t match_component(struct aa_profile *profile,
+ const char *ns_name;
+
+ if (profile->ns == tp->ns)
+- return aa_dfa_match(rules->policy.dfa, state, tp->base.hname);
++ return aa_dfa_match(rules->policy->dfa, state, tp->base.hname);
+
+ /* try matching with namespace name and then profile */
+ ns_name = aa_ns_name(profile->ns, tp->ns, true);
+- state = aa_dfa_match_len(rules->policy.dfa, state, ":", 1);
+- state = aa_dfa_match(rules->policy.dfa, state, ns_name);
+- state = aa_dfa_match_len(rules->policy.dfa, state, ":", 1);
+- return aa_dfa_match(rules->policy.dfa, state, tp->base.hname);
++ state = aa_dfa_match_len(rules->policy->dfa, state, ":", 1);
++ state = aa_dfa_match(rules->policy->dfa, state, ns_name);
++ state = aa_dfa_match_len(rules->policy->dfa, state, ":", 1);
++ return aa_dfa_match(rules->policy->dfa, state, tp->base.hname);
+ }
+
+ /**
+@@ -1321,12 +1321,12 @@ static int label_compound_match(struct aa_profile *profile,
+ label_for_each_cont(i, label, tp) {
+ if (!aa_ns_visible(profile->ns, tp->ns, subns))
+ continue;
+- state = aa_dfa_match(rules->policy.dfa, state, "//&");
++ state = aa_dfa_match(rules->policy->dfa, state, "//&");
+ state = match_component(profile, rules, tp, state);
+ if (!state)
+ goto fail;
+ }
+- *perms = *aa_lookup_perms(&rules->policy, state);
++ *perms = *aa_lookup_perms(rules->policy, state);
+ aa_apply_modes_to_perms(profile, perms);
+ if ((perms->allow & request) != request)
+ return -EACCES;
+@@ -1379,7 +1379,7 @@ static int label_components_match(struct aa_profile *profile,
+ return 0;
+
+ next:
+- tmp = *aa_lookup_perms(&rules->policy, state);
++ tmp = *aa_lookup_perms(rules->policy, state);
+ aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ label_for_each_cont(i, label, tp) {
+@@ -1388,7 +1388,7 @@ static int label_components_match(struct aa_profile *profile,
+ state = match_component(profile, rules, tp, start);
+ if (!state)
+ goto fail;
+- tmp = *aa_lookup_perms(&rules->policy, state);
++ tmp = *aa_lookup_perms(rules->policy, state);
+ aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ }
+diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
+index 7182a8b821fbd..cd569fbbfe36d 100644
+--- a/security/apparmor/lib.c
++++ b/security/apparmor/lib.c
+@@ -342,8 +342,8 @@ void aa_profile_match_label(struct aa_profile *profile,
+ /* TODO: doesn't yet handle extended types */
+ aa_state_t state;
+
+- state = aa_dfa_next(rules->policy.dfa,
+- rules->policy.start[AA_CLASS_LABEL],
++ state = aa_dfa_next(rules->policy->dfa,
++ rules->policy->start[AA_CLASS_LABEL],
+ type);
+ aa_label_match(profile, rules, label, state, false, request, perms);
+ }
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index 5303a51eff9c1..641f6510d7cb0 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -1909,6 +1909,69 @@ static int __init apparmor_nf_ip_init(void)
+ __initcall(apparmor_nf_ip_init);
+ #endif
+
++static char nulldfa_src[] = {
++ #include "nulldfa.in"
++};
++struct aa_dfa *nulldfa;
++
++static char stacksplitdfa_src[] = {
++ #include "stacksplitdfa.in"
++};
++struct aa_dfa *stacksplitdfa;
++struct aa_policydb *nullpdb;
++
++static int __init aa_setup_dfa_engine(void)
++{
++ int error = -ENOMEM;
++
++ nullpdb = aa_alloc_pdb(GFP_KERNEL);
++ if (!nullpdb)
++ return -ENOMEM;
++
++ nulldfa = aa_dfa_unpack(nulldfa_src, sizeof(nulldfa_src),
++ TO_ACCEPT1_FLAG(YYTD_DATA32) |
++ TO_ACCEPT2_FLAG(YYTD_DATA32));
++ if (IS_ERR(nulldfa)) {
++ error = PTR_ERR(nulldfa);
++ goto fail;
++ }
++ nullpdb->dfa = aa_get_dfa(nulldfa);
++ nullpdb->perms = kcalloc(2, sizeof(struct aa_perms), GFP_KERNEL);
++ if (!nullpdb->perms)
++ goto fail;
++ nullpdb->size = 2;
++
++ stacksplitdfa = aa_dfa_unpack(stacksplitdfa_src,
++ sizeof(stacksplitdfa_src),
++ TO_ACCEPT1_FLAG(YYTD_DATA32) |
++ TO_ACCEPT2_FLAG(YYTD_DATA32));
++ if (IS_ERR(stacksplitdfa)) {
++ error = PTR_ERR(stacksplitdfa);
++ goto fail;
++ }
++
++ return 0;
++
++fail:
++ aa_put_pdb(nullpdb);
++ aa_put_dfa(nulldfa);
++ nullpdb = NULL;
++ nulldfa = NULL;
++ stacksplitdfa = NULL;
++
++ return error;
++}
++
++static void __init aa_teardown_dfa_engine(void)
++{
++ aa_put_dfa(stacksplitdfa);
++ aa_put_dfa(nulldfa);
++ aa_put_pdb(nullpdb);
++ nullpdb = NULL;
++ stacksplitdfa = NULL;
++ nulldfa = NULL;
++}
++
+ static int __init apparmor_init(void)
+ {
+ int error;
+diff --git a/security/apparmor/match.c b/security/apparmor/match.c
+index 3667b79e9366b..6f6cdb86f32b5 100644
+--- a/security/apparmor/match.c
++++ b/security/apparmor/match.c
+@@ -21,50 +21,6 @@
+
+ #define base_idx(X) ((X) & 0xffffff)
+
+-static char nulldfa_src[] = {
+- #include "nulldfa.in"
+-};
+-struct aa_dfa *nulldfa;
+-
+-static char stacksplitdfa_src[] = {
+- #include "stacksplitdfa.in"
+-};
+-struct aa_dfa *stacksplitdfa;
+-
+-int __init aa_setup_dfa_engine(void)
+-{
+- int error;
+-
+- nulldfa = aa_dfa_unpack(nulldfa_src, sizeof(nulldfa_src),
+- TO_ACCEPT1_FLAG(YYTD_DATA32) |
+- TO_ACCEPT2_FLAG(YYTD_DATA32));
+- if (IS_ERR(nulldfa)) {
+- error = PTR_ERR(nulldfa);
+- nulldfa = NULL;
+- return error;
+- }
+-
+- stacksplitdfa = aa_dfa_unpack(stacksplitdfa_src,
+- sizeof(stacksplitdfa_src),
+- TO_ACCEPT1_FLAG(YYTD_DATA32) |
+- TO_ACCEPT2_FLAG(YYTD_DATA32));
+- if (IS_ERR(stacksplitdfa)) {
+- aa_put_dfa(nulldfa);
+- nulldfa = NULL;
+- error = PTR_ERR(stacksplitdfa);
+- stacksplitdfa = NULL;
+- return error;
+- }
+-
+- return 0;
+-}
+-
+-void __init aa_teardown_dfa_engine(void)
+-{
+- aa_put_dfa(stacksplitdfa);
+- aa_put_dfa(nulldfa);
+-}
+-
+ /**
+ * unpack_table - unpack a dfa table (one of accept, default, base, next check)
+ * @blob: data to unpack (NOT NULL)
+diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
+index cb0fdbdb82d94..49fe8da6fea45 100644
+--- a/security/apparmor/mount.c
++++ b/security/apparmor/mount.c
+@@ -332,8 +332,8 @@ static int match_mnt_path_str(const struct cred *subj_cred,
+ }
+
+ error = -EACCES;
+- pos = do_match_mnt(&rules->policy,
+- rules->policy.start[AA_CLASS_MOUNT],
++ pos = do_match_mnt(rules->policy,
++ rules->policy->start[AA_CLASS_MOUNT],
+ mntpnt, devname, type, flags, data, binary, &perms);
+ if (pos) {
+ info = mnt_info_table[pos];
+@@ -620,10 +620,10 @@ static int profile_umount(const struct cred *subj_cred,
+ if (error)
+ goto audit;
+
+- state = aa_dfa_match(rules->policy.dfa,
+- rules->policy.start[AA_CLASS_MOUNT],
++ state = aa_dfa_match(rules->policy->dfa,
++ rules->policy->start[AA_CLASS_MOUNT],
+ name);
+- perms = *aa_lookup_perms(&rules->policy, state);
++ perms = *aa_lookup_perms(rules->policy, state);
+ if (AA_MAY_UMOUNT & ~perms.allow)
+ error = -EACCES;
+
+@@ -694,12 +694,12 @@ static struct aa_label *build_pivotroot(const struct cred *subj_cred,
+ goto audit;
+
+ error = -EACCES;
+- state = aa_dfa_match(rules->policy.dfa,
+- rules->policy.start[AA_CLASS_MOUNT],
++ state = aa_dfa_match(rules->policy->dfa,
++ rules->policy->start[AA_CLASS_MOUNT],
+ new_name);
+- state = aa_dfa_null_transition(rules->policy.dfa, state);
+- state = aa_dfa_match(rules->policy.dfa, state, old_name);
+- perms = *aa_lookup_perms(&rules->policy, state);
++ state = aa_dfa_null_transition(rules->policy->dfa, state);
++ state = aa_dfa_match(rules->policy->dfa, state, old_name);
++ perms = *aa_lookup_perms(rules->policy, state);
+
+ if (AA_MAY_PIVOTROOT & perms.allow)
+ error = 0;
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index 814e8319d43e0..3e632700d06fb 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -127,9 +127,9 @@ int aa_profile_af_perm(struct aa_profile *profile,
+
+ buffer[0] = cpu_to_be16(family);
+ buffer[1] = cpu_to_be16((u16) type);
+- state = aa_dfa_match_len(rules->policy.dfa, state, (char *) &buffer,
++ state = aa_dfa_match_len(rules->policy->dfa, state, (char *) &buffer,
+ 4);
+- perms = *aa_lookup_perms(&rules->policy, state);
++ perms = *aa_lookup_perms(rules->policy, state);
+ aa_apply_modes_to_perms(profile, &perms);
+
+ return aa_check_perms(profile, &perms, request, ad, audit_net_cb);
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index adf38e592bd4b..009fa7cfb6688 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -98,6 +98,41 @@ const char *const aa_profile_mode_names[] = {
+ };
+
+
++static void aa_free_pdb(struct aa_policydb *policy)
++{
++ if (policy) {
++ aa_put_dfa(policy->dfa);
++ if (policy->perms)
++ kvfree(policy->perms);
++ aa_free_str_table(&policy->trans);
++ }
++}
++
++/**
++ * aa_pdb_free_kref - free aa_policydb by kref (called by aa_put_pdb)
++ * @kr: kref callback for freeing of a dfa (NOT NULL)
++ */
++void aa_pdb_free_kref(struct kref *kref)
++{
++ struct aa_policydb *pdb = container_of(kref, struct aa_policydb, count);
++
++ aa_free_pdb(pdb);
++}
++
++
++struct aa_policydb *aa_alloc_pdb(gfp_t gfp)
++{
++ struct aa_policydb *pdb = kzalloc(sizeof(struct aa_policydb), gfp);
++
++ if (!pdb)
++ return NULL;
++
++ kref_init(&pdb->count);
++
++ return pdb;
++}
++
++
+ /**
+ * __add_profile - add a profiles to list and label tree
+ * @list: list to add it to (NOT NULL)
+@@ -200,15 +235,15 @@ static void free_attachment(struct aa_attachment *attach)
+ for (i = 0; i < attach->xattr_count; i++)
+ kfree_sensitive(attach->xattrs[i]);
+ kfree_sensitive(attach->xattrs);
+- aa_destroy_policydb(&attach->xmatch);
++ aa_put_pdb(attach->xmatch);
+ }
+
+ static void free_ruleset(struct aa_ruleset *rules)
+ {
+ int i;
+
+- aa_destroy_policydb(&rules->file);
+- aa_destroy_policydb(&rules->policy);
++ aa_put_pdb(rules->file);
++ aa_put_pdb(rules->policy);
+ aa_free_cap_rules(&rules->caps);
+ aa_free_rlimit_rules(&rules->rlimits);
+
+@@ -590,16 +625,8 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name,
+ /* TODO: ideally we should inherit abi from parent */
+ profile->label.flags |= FLAG_NULL;
+ rules = list_first_entry(&profile->rules, typeof(*rules), list);
+- rules->file.dfa = aa_get_dfa(nulldfa);
+- rules->file.perms = kcalloc(2, sizeof(struct aa_perms), gfp);
+- if (!rules->file.perms)
+- goto fail;
+- rules->file.size = 2;
+- rules->policy.dfa = aa_get_dfa(nulldfa);
+- rules->policy.perms = kcalloc(2, sizeof(struct aa_perms), gfp);
+- if (!rules->policy.perms)
+- goto fail;
+- rules->policy.size = 2;
++ rules->file = aa_get_pdb(nullpdb);
++ rules->policy = aa_get_pdb(nullpdb);
+
+ if (parent) {
+ profile->path_flags = parent->path_flags;
+@@ -610,11 +637,6 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name,
+ }
+
+ return profile;
+-
+-fail:
+- aa_free_profile(profile);
+-
+- return NULL;
+ }
+
+ /**
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index cefda5e5b6ed0..9b25624285e67 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -707,24 +707,29 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms)
+ return -EPROTO;
+ }
+
+-static int unpack_pdb(struct aa_ext *e, struct aa_policydb *policy,
++static int unpack_pdb(struct aa_ext *e, struct aa_policydb **policy,
+ bool required_dfa, bool required_trans,
+ const char **info)
+ {
++ struct aa_policydb *pdb;
+ void *pos = e->pos;
+ int i, flags, error = -EPROTO;
+ ssize_t size;
+
+- size = unpack_perms_table(e, &policy->perms);
++ pdb = aa_alloc_pdb(GFP_KERNEL);
++ if (!pdb)
++ return -ENOMEM;
++
++ size = unpack_perms_table(e, &pdb->perms);
+ if (size < 0) {
+ error = size;
+- policy->perms = NULL;
++ pdb->perms = NULL;
+ *info = "failed to unpack - perms";
+ goto fail;
+ }
+- policy->size = size;
++ pdb->size = size;
+
+- if (policy->perms) {
++ if (pdb->perms) {
+ /* perms table present accept is index */
+ flags = TO_ACCEPT1_FLAG(YYTD_DATA32);
+ } else {
+@@ -733,13 +738,13 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb *policy,
+ TO_ACCEPT2_FLAG(YYTD_DATA32);
+ }
+
+- policy->dfa = unpack_dfa(e, flags);
+- if (IS_ERR(policy->dfa)) {
+- error = PTR_ERR(policy->dfa);
+- policy->dfa = NULL;
++ pdb->dfa = unpack_dfa(e, flags);
++ if (IS_ERR(pdb->dfa)) {
++ error = PTR_ERR(pdb->dfa);
++ pdb->dfa = NULL;
+ *info = "failed to unpack - dfa";
+ goto fail;
+- } else if (!policy->dfa) {
++ } else if (!pdb->dfa) {
+ if (required_dfa) {
+ *info = "missing required dfa";
+ goto fail;
+@@ -753,18 +758,18 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb *policy,
+ * sadly start was given different names for file and policydb
+ * but since it is optional we can try both
+ */
+- if (!aa_unpack_u32(e, &policy->start[0], "start"))
++ if (!aa_unpack_u32(e, &pdb->start[0], "start"))
+ /* default start state */
+- policy->start[0] = DFA_START;
+- if (!aa_unpack_u32(e, &policy->start[AA_CLASS_FILE], "dfa_start")) {
++ pdb->start[0] = DFA_START;
++ if (!aa_unpack_u32(e, &pdb->start[AA_CLASS_FILE], "dfa_start")) {
+ /* default start state for xmatch and file dfa */
+- policy->start[AA_CLASS_FILE] = DFA_START;
++ pdb->start[AA_CLASS_FILE] = DFA_START;
+ } /* setup class index */
+ for (i = AA_CLASS_FILE + 1; i <= AA_CLASS_LAST; i++) {
+- policy->start[i] = aa_dfa_next(policy->dfa, policy->start[0],
++ pdb->start[i] = aa_dfa_next(pdb->dfa, pdb->start[0],
+ i);
+ }
+- if (!unpack_trans_table(e, &policy->trans) && required_trans) {
++ if (!unpack_trans_table(e, &pdb->trans) && required_trans) {
+ *info = "failed to unpack profile transition table";
+ goto fail;
+ }
+@@ -772,9 +777,11 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb *policy,
+ /* TODO: move compat mapping here, requires dfa merging first */
+ /* TODO: move verify here, it has to be done after compat mappings */
+ out:
++ *policy = pdb;
+ return 0;
+
+ fail:
++ aa_put_pdb(pdb);
+ e->pos = pos;
+ return error;
+ }
+@@ -862,15 +869,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
+ }
+
+ /* neither xmatch_len not xmatch_perms are optional if xmatch is set */
+- if (profile->attach.xmatch.dfa) {
++ if (profile->attach.xmatch->dfa) {
+ if (!aa_unpack_u32(e, &tmp, NULL)) {
+ info = "missing xmatch len";
+ goto fail;
+ }
+ profile->attach.xmatch_len = tmp;
+- profile->attach.xmatch.start[AA_CLASS_XMATCH] = DFA_START;
+- if (!profile->attach.xmatch.perms) {
+- error = aa_compat_map_xmatch(&profile->attach.xmatch);
++ profile->attach.xmatch->start[AA_CLASS_XMATCH] = DFA_START;
++ if (!profile->attach.xmatch->perms) {
++ error = aa_compat_map_xmatch(profile->attach.xmatch);
+ if (error) {
+ info = "failed to convert xmatch permission table";
+ goto fail;
+@@ -987,16 +994,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
+ if (error)
+ goto fail;
+ /* Fixup: drop when we get rid of start array */
+- if (aa_dfa_next(rules->policy.dfa, rules->policy.start[0],
++ if (aa_dfa_next(rules->policy->dfa, rules->policy->start[0],
+ AA_CLASS_FILE))
+- rules->policy.start[AA_CLASS_FILE] =
+- aa_dfa_next(rules->policy.dfa,
+- rules->policy.start[0],
++ rules->policy->start[AA_CLASS_FILE] =
++ aa_dfa_next(rules->policy->dfa,
++ rules->policy->start[0],
+ AA_CLASS_FILE);
+ if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
+ goto fail;
+- if (!rules->policy.perms) {
+- error = aa_compat_map_policy(&rules->policy,
++ if (!rules->policy->perms) {
++ error = aa_compat_map_policy(rules->policy,
+ e->version);
+ if (error) {
+ info = "failed to remap policydb permission table";
+@@ -1004,44 +1011,25 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
+ }
+ }
+ } else {
+- rules->policy.dfa = aa_get_dfa(nulldfa);
+- rules->policy.perms = kcalloc(2, sizeof(struct aa_perms),
+- GFP_KERNEL);
+- if (!rules->policy.perms)
+- goto fail;
+- rules->policy.size = 2;
++ rules->policy = aa_get_pdb(nullpdb);
+ }
+ /* get file rules */
+ error = unpack_pdb(e, &rules->file, false, true, &info);
+ if (error) {
+ goto fail;
+- } else if (rules->file.dfa) {
+- if (!rules->file.perms) {
+- error = aa_compat_map_file(&rules->file);
++ } else if (rules->file->dfa) {
++ if (!rules->file->perms) {
++ error = aa_compat_map_file(rules->file);
+ if (error) {
+ info = "failed to remap file permission table";
+ goto fail;
+ }
+ }
+- } else if (rules->policy.dfa &&
+- rules->policy.start[AA_CLASS_FILE]) {
+- rules->file.dfa = aa_get_dfa(rules->policy.dfa);
+- rules->file.start[AA_CLASS_FILE] = rules->policy.start[AA_CLASS_FILE];
+- rules->file.perms = kcalloc(rules->policy.size,
+- sizeof(struct aa_perms),
+- GFP_KERNEL);
+- if (!rules->file.perms)
+- goto fail;
+- memcpy(rules->file.perms, rules->policy.perms,
+- rules->policy.size * sizeof(struct aa_perms));
+- rules->file.size = rules->policy.size;
++ } else if (rules->policy->dfa &&
++ rules->policy->start[AA_CLASS_FILE]) {
++ rules->file = aa_get_pdb(rules->policy);
+ } else {
+- rules->file.dfa = aa_get_dfa(nulldfa);
+- rules->file.perms = kcalloc(2, sizeof(struct aa_perms),
+- GFP_KERNEL);
+- if (!rules->file.perms)
+- goto fail;
+- rules->file.size = 2;
++ rules->file = aa_get_pdb(nullpdb);
+ }
+ error = -EPROTO;
+ if (aa_unpack_nameX(e, AA_STRUCT, "data")) {
+@@ -1249,32 +1237,32 @@ static int verify_profile(struct aa_profile *profile)
+ if (!rules)
+ return 0;
+
+- if (rules->file.dfa && !verify_dfa_accept_index(rules->file.dfa,
+- rules->file.size)) {
++ if (rules->file->dfa && !verify_dfa_accept_index(rules->file->dfa,
++ rules->file->size)) {
+ audit_iface(profile, NULL, NULL,
+ "Unpack: file Invalid named transition", NULL,
+ -EPROTO);
+ return -EPROTO;
+ }
+- if (rules->policy.dfa &&
+- !verify_dfa_accept_index(rules->policy.dfa, rules->policy.size)) {
++ if (rules->policy->dfa &&
++ !verify_dfa_accept_index(rules->policy->dfa, rules->policy->size)) {
+ audit_iface(profile, NULL, NULL,
+ "Unpack: policy Invalid named transition", NULL,
+ -EPROTO);
+ return -EPROTO;
+ }
+
+- if (!verify_perms(&rules->file)) {
++ if (!verify_perms(rules->file)) {
+ audit_iface(profile, NULL, NULL,
+ "Unpack: Invalid perm index", NULL, -EPROTO);
+ return -EPROTO;
+ }
+- if (!verify_perms(&rules->policy)) {
++ if (!verify_perms(rules->policy)) {
+ audit_iface(profile, NULL, NULL,
+ "Unpack: Invalid perm index", NULL, -EPROTO);
+ return -EPROTO;
+ }
+- if (!verify_perms(&profile->attach.xmatch)) {
++ if (!verify_perms(profile->attach.xmatch)) {
+ audit_iface(profile, NULL, NULL,
+ "Unpack: Invalid perm index", NULL, -EPROTO);
+ return -EPROTO;
+--
+2.51.0
+
--- /dev/null
+From e5e786ec71fa9e7ef2e76340eba31e06f66dbaf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Nov 2025 00:14:36 -0800
+Subject: apparmor: remove apply_modes_to_perms from label_match
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit b2e27be2948f2f8c38421cd554b5fc9383215648 ]
+
+The modes shouldn't be applied at the point of label match, it just
+results in them being applied multiple times. Instead they should be
+applied after which is already being done by all callers so it can
+just be dropped from label_match.
+
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/label.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 178eca800ddaf..217bd6709023f 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -1327,7 +1327,6 @@ static int label_compound_match(struct aa_profile *profile,
+ goto fail;
+ }
+ *perms = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, perms);
+ if ((perms->allow & request) != request)
+ return -EACCES;
+
+@@ -1380,7 +1379,6 @@ static int label_components_match(struct aa_profile *profile,
+
+ next:
+ tmp = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ label_for_each_cont(i, label, tp) {
+ if (!aa_ns_visible(profile->ns, tp->ns, subns))
+@@ -1389,7 +1387,6 @@ static int label_components_match(struct aa_profile *profile,
+ if (!state)
+ goto fail;
+ tmp = *aa_lookup_perms(rules->policy, state);
+- aa_apply_modes_to_perms(profile, &tmp);
+ aa_perms_accum(perms, &tmp);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 6fab80771ba41f414c7aa0f4ebaaf0a024cab4fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jan 2026 09:35:57 -0800
+Subject: apparmor: return -ENOMEM in unpack_perms_table upon alloc failure
+
+From: Ryan Lee <ryan.lee@canonical.com>
+
+[ Upstream commit 74b7105e53e80a4072bd3e1a50be7aa15e3f0a01 ]
+
+In policy_unpack.c:unpack_perms_table, the perms struct is allocated via
+kcalloc, with the position being reset if the allocation fails. However,
+the error path results in -EPROTO being retured instead of -ENOMEM. Fix
+this to return the correct error code.
+
+Reported-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
+Fixes: fd1b2b95a2117 ("apparmor: add the ability for policy to specify a permission table")
+Reviewed-by: Tyler Hicks <code@tyhicks.com>
+Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy_unpack.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index d752bfa9b3f37..a1de48c2d826b 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -683,8 +683,10 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms)
+ if (!aa_unpack_array(e, NULL, &size))
+ goto fail_reset;
+ *perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL);
+- if (!*perms)
+- goto fail_reset;
++ if (!*perms) {
++ e->pos = pos;
++ return -ENOMEM;
++ }
+ for (i = 0; i < size; i++) {
+ if (!unpack_perm(e, version, &(*perms)[i]))
+ goto fail;
+--
+2.51.0
+
--- /dev/null
+From 68d2bfabc7dd14f889d5868067f64d2de93523ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Jun 2023 16:02:04 +0300
+Subject: apparmor: use passed in gfp flags in aa_alloc_null()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit afad53575a938ceb557227ecfeb0dda59d668d4e ]
+
+These allocations should use the gfp flags from the caller instead of
+GFP_KERNEL. But from what I can see, all the callers pass in GFP_KERNEL
+so this does not affect runtime.
+
+Fixes: e31dd6e412f7 ("apparmor: fix: kzalloc perms tables for shared dfas")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: a4c9efa4dbad ("apparmor: make label_match return a consistent value")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index d9d3b3d776e11..adf38e592bd4b 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -591,12 +591,12 @@ struct aa_profile *aa_alloc_null(struct aa_profile *parent, const char *name,
+ profile->label.flags |= FLAG_NULL;
+ rules = list_first_entry(&profile->rules, typeof(*rules), list);
+ rules->file.dfa = aa_get_dfa(nulldfa);
+- rules->file.perms = kcalloc(2, sizeof(struct aa_perms), GFP_KERNEL);
++ rules->file.perms = kcalloc(2, sizeof(struct aa_perms), gfp);
+ if (!rules->file.perms)
+ goto fail;
+ rules->file.size = 2;
+ rules->policy.dfa = aa_get_dfa(nulldfa);
+- rules->policy.perms = kcalloc(2, sizeof(struct aa_perms), GFP_KERNEL);
++ rules->policy.perms = kcalloc(2, sizeof(struct aa_perms), gfp);
+ if (!rules->policy.perms)
+ goto fail;
+ rules->policy.size = 2;
+--
+2.51.0
+
--- /dev/null
+From a7671d73ab3201f7f0ea4bd3559afd488d25a22b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 11:27:32 +0100
+Subject: ASoC: codecs: aw88261: Fix erroneous bitmask logic in Awinic init
+
+From: Alexandre Ferrieux <alexandre.ferrieux@orange.com>
+
+[ Upstream commit b82fa9b0c26eeb2fde6017f7de2c3c544484efef ]
+
+The aw88261_dev_reg_update() function sets the Awinic registers in a
+rather nonuniform way:
+ - most registers get directly overwritten from the firmware blob
+ - but a handful of them need more delicate logic to preserve
+ some bits from their current value, according to a register-
+ specific mask
+For the latter, the logic is basically
+ NEW = (OLD & MASK) | (VAL & ~MASK)
+However, the ~MASK value is hand-computed, and in the specific case
+of the SYSCTRL register, in a buggy way.
+This patch restores the proper ~MASK value.
+
+Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver")
+Signed-off-by: Alexandre Ferrieux <alexandre.ferrieux@orange.com>
+Link: https://patch.msgid.link/20260211-aw88261-fwname-v1-1-e24e833a019d@fairphone.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/aw88261.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c
+index a697b5006b45b..f2a9c33ff4a64 100644
+--- a/sound/soc/codecs/aw88261.c
++++ b/sound/soc/codecs/aw88261.c
+@@ -424,9 +424,10 @@ static int aw88261_dev_reg_update(struct aw88261 *aw88261,
+ if (ret)
+ break;
+
++ /* keep all three bits from current hw status */
+ read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) |
+ (~AW88261_HMUTE_MASK);
+- reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK);
++ reg_val &= (AW88261_AMPPD_MASK & AW88261_PWDN_MASK & AW88261_HMUTE_MASK);
+ reg_val |= read_val;
+
+ /* enable uls hmute */
+--
+2.51.0
+
--- /dev/null
+From 1e0c54e25553a31008eeb53d713ee0de3f811860 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 18:57:14 +0000
+Subject: ASoC: fsl_xcvr: Revert fix missing lock in fsl_xcvr_mode_put()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9f16d96e1222391a6b996a1b676bec14fb91e3b2 ]
+
+This reverts commit f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()").
+
+The original patch attempted to acquire the card->controls_rwsem lock in
+fsl_xcvr_mode_put(). However, this function is called from the upper ALSA
+core function snd_ctl_elem_write(), which already holds the write lock on
+controls_rwsem for the whole put operation. So there is no need to simply
+hold the lock for fsl_xcvr_activate_ctl() again.
+
+Acquiring the read lock while holding the write lock in the same thread
+results in a deadlock and a hung task, as reported by Alexander Stein.
+
+Fixes: f51424872760 ("ASoC: fsl_xcvr: fix missing lock in fsl_xcvr_mode_put()")
+Reported-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Closes: https://lore.kernel.org/linux-sound/5056506.GXAFRqVoOG@steina-w/
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260210185714.556385-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/fsl/fsl_xcvr.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
+index 3a5ab8b536728..90a0a24c05d84 100644
+--- a/sound/soc/fsl/fsl_xcvr.c
++++ b/sound/soc/fsl/fsl_xcvr.c
+@@ -206,13 +206,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol,
+
+ xcvr->mode = snd_soc_enum_item_to_val(e, item[0]);
+
+- down_read(&card->snd_card->controls_rwsem);
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_ARC));
+ fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name,
+ (xcvr->mode == FSL_XCVR_MODE_EARC));
+- up_read(&card->snd_card->controls_rwsem);
+-
+ /* Allow playback for SPDIF only */
+ rtd = snd_soc_get_pcm_runtime(card, card->dai_link);
+ rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count =
+--
+2.51.0
+
--- /dev/null
+From 05e357a33eeb1ecc759cf817138a98ad50e777ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 15:18:34 -0500
+Subject: ASoC: rockchip: i2s-tdm: Use param rate if not provided by set_sysclk
+
+From: Detlev Casanova <detlev.casanova@collabora.com>
+
+[ Upstream commit 0783052534f547f8f201dd4554b1df9f1f8615b5 ]
+
+Drivers will not always call set_sysclk() for all clocks, especially when
+default mclk-fs can be used.
+When that is the case, use the clock rate set in the params multiplied by the
+default mclk-fs.
+
+Fixes: 5323186e2e8d ("ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback")
+Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
+Reported-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
+Link: https://patch.msgid.link/20260218201834.924358-1-detlev.casanova@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/rockchip/rockchip_i2s_tdm.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c
+index 7ae93cbaea9a7..15ef6b6bec2bb 100644
+--- a/sound/soc/rockchip/rockchip_i2s_tdm.c
++++ b/sound/soc/rockchip/rockchip_i2s_tdm.c
+@@ -24,6 +24,7 @@
+
+ #define DRV_NAME "rockchip-i2s-tdm"
+
++#define DEFAULT_MCLK_FS 256
+ #define CH_GRP_MAX 4 /* The max channel 8 / 2 */
+ #define MULTIPLEX_CH_MAX 10
+
+@@ -695,6 +696,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
+ mclk_rate = i2s_tdm->mclk_rx_freq;
+ }
+
++ /*
++ * When the dai/component driver doesn't need to set mclk-fs for a specific
++ * clock, it can skip the call to set_sysclk() for that clock.
++ * In that case, simply use the clock rate from the params and multiply it by
++ * the default mclk-fs value.
++ */
++ if (!mclk_rate)
++ mclk_rate = DEFAULT_MCLK_FS * params_rate(params);
++
+ err = clk_set_rate(mclk, mclk_rate);
+ if (err)
+ return err;
+--
+2.51.0
+
--- /dev/null
+From f94e9c79f37cc6c86dfdb5863c9369721c19eebb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 06:09:19 +0000
+Subject: bonding: alb: fix UAF in rlb_arp_recv during bond up/down
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+[ Upstream commit e6834a4c474697df23ab9948fd3577b26bf48656 ]
+
+The ALB RX path may access rx_hashtbl concurrently with bond
+teardown. During rapid bond up/down cycles, rlb_deinitialize()
+frees rx_hashtbl while RX handlers are still running, leading
+to a null pointer dereference detected by KASAN.
+
+However, the root cause is that rlb_arp_recv() can still be accessed
+after setting recv_probe to NULL, which is actually a use-after-free
+(UAF) issue. That is the reason for using the referenced commit in the
+Fixes tag.
+
+[ 214.174138] Oops: general protection fault, probably for non-canonical address 0xdffffc000000001d: 0000 [#1] SMP KASAN PTI
+[ 214.186478] KASAN: null-ptr-deref in range [0x00000000000000e8-0x00000000000000ef]
+[ 214.194933] CPU: 30 UID: 0 PID: 2375 Comm: ping Kdump: loaded Not tainted 6.19.0-rc8+ #2 PREEMPT(voluntary)
+[ 214.205907] Hardware name: Dell Inc. PowerEdge R730/0WCJNT, BIOS 2.14.0 01/14/2022
+[ 214.214357] RIP: 0010:rlb_arp_recv+0x505/0xab0 [bonding]
+[ 214.220320] Code: 0f 85 2b 05 00 00 48 b8 00 00 00 00 00 fc ff df 40 0f b6 ed 48 c1 e5 06 49 03 ad 78 01 00 00 48 8d 7d 28 48 89 fa 48 c1 ea 03 <0f> b6
+ 04 02 84 c0 74 06 0f 8e 12 05 00 00 80 7d 28 00 0f 84 8c 00
+[ 214.241280] RSP: 0018:ffffc900073d8870 EFLAGS: 00010206
+[ 214.247116] RAX: dffffc0000000000 RBX: ffff888168556822 RCX: ffff88816855681e
+[ 214.255082] RDX: 000000000000001d RSI: dffffc0000000000 RDI: 00000000000000e8
+[ 214.263048] RBP: 00000000000000c0 R08: 0000000000000002 R09: ffffed11192021c8
+[ 214.271013] R10: ffff8888c9010e43 R11: 0000000000000001 R12: 1ffff92000e7b119
+[ 214.278978] R13: ffff8888c9010e00 R14: ffff888168556822 R15: ffff888168556810
+[ 214.286943] FS: 00007f85d2d9cb80(0000) GS:ffff88886ccb3000(0000) knlGS:0000000000000000
+[ 214.295966] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 214.302380] CR2: 00007f0d047b5e34 CR3: 00000008a1c2e002 CR4: 00000000001726f0
+[ 214.310347] Call Trace:
+[ 214.313070] <IRQ>
+[ 214.315318] ? __pfx_rlb_arp_recv+0x10/0x10 [bonding]
+[ 214.320975] bond_handle_frame+0x166/0xb60 [bonding]
+[ 214.326537] ? __pfx_bond_handle_frame+0x10/0x10 [bonding]
+[ 214.332680] __netif_receive_skb_core.constprop.0+0x576/0x2710
+[ 214.339199] ? __pfx_arp_process+0x10/0x10
+[ 214.343775] ? sched_balance_find_src_group+0x98/0x630
+[ 214.349513] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10
+[ 214.356513] ? arp_rcv+0x307/0x690
+[ 214.360311] ? __pfx_arp_rcv+0x10/0x10
+[ 214.364499] ? __lock_acquire+0x58c/0xbd0
+[ 214.368975] __netif_receive_skb_one_core+0xae/0x1b0
+[ 214.374518] ? __pfx___netif_receive_skb_one_core+0x10/0x10
+[ 214.380743] ? lock_acquire+0x10b/0x140
+[ 214.385026] process_backlog+0x3f1/0x13a0
+[ 214.389502] ? process_backlog+0x3aa/0x13a0
+[ 214.394174] __napi_poll.constprop.0+0x9f/0x370
+[ 214.399233] net_rx_action+0x8c1/0xe60
+[ 214.403423] ? __pfx_net_rx_action+0x10/0x10
+[ 214.408193] ? lock_acquire.part.0+0xbd/0x260
+[ 214.413058] ? sched_clock_cpu+0x6c/0x540
+[ 214.417540] ? mark_held_locks+0x40/0x70
+[ 214.421920] handle_softirqs+0x1fd/0x860
+[ 214.426302] ? __pfx_handle_softirqs+0x10/0x10
+[ 214.431264] ? __neigh_event_send+0x2d6/0xf50
+[ 214.436131] do_softirq+0xb1/0xf0
+[ 214.439830] </IRQ>
+
+The issue is reproducible by repeatedly running
+ip link set bond0 up/down while receiving ARP messages, where
+rlb_arp_recv() can race with rlb_deinitialize() and dereference
+a freed rx_hashtbl entry.
+
+Fix this by setting recv_probe to NULL and then calling
+synchronize_net() to wait for any concurrent RX processing to finish.
+This ensures that no RX handler can access rx_hashtbl after it is freed
+in bond_alb_deinitialize().
+
+Reported-by: Liang Li <liali@redhat.com>
+Fixes: 3aba891dde38 ("bonding: move processing of recv handlers into handle_frame()")
+Reviewed-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Acked-by: Jay Vosburgh <jv@jvosburgh.net>
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://patch.msgid.link/20260218060919.101574-1-liuhangbin@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/bonding/bond_main.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 4f8a59b4ba985..836d7fcac71a1 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4401,9 +4401,13 @@ static int bond_close(struct net_device *bond_dev)
+
+ bond_work_cancel_all(bond);
+ bond->send_peer_notif = 0;
++ WRITE_ONCE(bond->recv_probe, NULL);
++
++ /* Wait for any in-flight RX handlers */
++ synchronize_net();
++
+ if (bond_is_lb(bond))
+ bond_alb_deinitialize(bond);
+- bond->recv_probe = NULL;
+
+ if (bond_uses_primary(bond)) {
+ rcu_read_lock();
+--
+2.51.0
+
--- /dev/null
+From 239922eabf1763cf5c95985a2a87008f035dac3a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 11:41:50 -0800
+Subject: bpftool: Fix truncated netlink dumps
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 3b39d73cc3379360a33eb583b17f21fe55e1288e ]
+
+Netlink requires that the recv buffer used during dumps is at least
+min(PAGE_SIZE, 8k) (see the man page). Otherwise the messages will
+get truncated. Make sure bpftool follows this requirement, avoid
+missing information on systems with large pages.
+
+Acked-by: Quentin Monnet <qmo@kernel.org>
+Fixes: 7084566a236f ("tools/bpftool: Remove libbpf_internal.h usage in bpftool")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Link: https://lore.kernel.org/r/20260217194150.734701-1-kuba@kernel.org
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/net.c | 5 ++++-
+ tools/lib/bpf/netlink.c | 4 +++-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c
+index c2ca82fc21e21..225d3678b4ed1 100644
+--- a/tools/bpf/bpftool/net.c
++++ b/tools/bpf/bpftool/net.c
+@@ -150,7 +150,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ bool multipart = true;
+ struct nlmsgerr *err;
+ struct nlmsghdr *nh;
+- char buf[4096];
++ char buf[8192];
+ int len, ret;
+
+ while (multipart) {
+@@ -195,6 +195,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq,
+ return ret;
+ }
+ }
++
++ if (len)
++ p_err("Invalid message or trailing data in Netlink response: %d bytes left", len);
+ }
+ ret = 0;
+ done:
+diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c
+index 68a2def171751..6f16c4f7b3a43 100644
+--- a/tools/lib/bpf/netlink.c
++++ b/tools/lib/bpf/netlink.c
+@@ -143,7 +143,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ struct nlmsghdr *nh;
+ int len, ret;
+
+- ret = alloc_iov(&iov, 4096);
++ ret = alloc_iov(&iov, 8192);
+ if (ret)
+ goto done;
+
+@@ -212,6 +212,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
+ }
+ }
+ }
++ if (len)
++ pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len);
+ }
+ ret = 0;
+ done:
+--
+2.51.0
+
--- /dev/null
+From 67764adc21f2039c89a49ada675c7fddc0bb254e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 4 Feb 2026 17:15:53 +0000
+Subject: btrfs: fix invalid leaf access in btrfs_quota_enable() if ref key not
+ found
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit ecb7c2484cfc83a93658907580035a8adf1e0a92 ]
+
+If btrfs_search_slot_for_read() returns 1, it means we did not find any
+key greater than or equals to the key we asked for, meaning we have
+reached the end of the tree and therefore the path is not valid. If
+this happens we need to break out of the loop and stop, instead of
+continuing and accessing an invalid path.
+
+Fixes: 5223cc60b40a ("btrfs: drop the path before adding qgroup items when enabling qgroups")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/qgroup.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index d27b9e0fa229a..622febdb61e23 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1129,11 +1129,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
+ }
+ if (ret > 0) {
+ /*
+- * Shouldn't happen, but in case it does we
+- * don't need to do the btrfs_next_item, just
+- * continue.
++ * Shouldn't happen because the key should still
++ * be there (return 0), but in case it does it
++ * means we have reached the end of the tree -
++ * there are no more leaves with items that have
++ * a key greater than or equals to @found_key,
++ * so just stop the search loop.
+ */
+- continue;
++ break;
+ }
+ }
+ ret = btrfs_next_item(tree_root, path);
+--
+2.51.0
+
--- /dev/null
+From a0b244ec9e689e1d33dcd1baaccae5c6870b4446 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Jun 2024 15:53:34 +0200
+Subject: cache: add __cacheline_group_{begin, end}_aligned() (+ couple more)
+
+From: Alexander Lobakin <aleksander.lobakin@intel.com>
+
+[ Upstream commit 2cb13dec8c5e5e104fd2f71c2dee761d6ed9a333 ]
+
+__cacheline_group_begin(), unfortunately, doesn't align the group
+anyhow. If it is wanted, then you need to do something like
+
+__cacheline_group_begin(grp) __aligned(ALIGN)
+
+which isn't really convenient nor compact.
+Add the _aligned() counterparts to align the groups automatically to
+either the specified alignment (optional) or ``SMP_CACHE_BYTES``.
+Note that the actual struct layout will then be (on x64 with 64-byte CL):
+
+struct x {
+ u32 y; // offset 0, size 4, padding 56
+ __cacheline_group_begin__grp; // offset 64, size 0
+ u32 z; // offset 64, size 4, padding 4
+ __cacheline_group_end__grp; // offset 72, size 0
+ __cacheline_group_pad__grp; // offset 72, size 0, padding 56
+ u32 w; // offset 128
+};
+
+The end marker is aligned to long, so that you can assert the struct
+size more strictly, but the offset of the next field in the structure
+will be aligned to the group alignment, so that the next field won't
+fall into the group it's not intended to.
+
+Add __LARGEST_ALIGN definition and LARGEST_ALIGN() macro.
+__LARGEST_ALIGN is the value to which the compilers align fields when
+__aligned_largest is specified. Sometimes, it might be needed to get
+this value outside of variable definitions. LARGEST_ALIGN() is macro
+which just aligns a value to __LARGEST_ALIGN.
+Also add SMP_CACHE_ALIGN(), similar to L1_CACHE_ALIGN(), but using
+``SMP_CACHE_BYTES`` instead of ``L1_CACHE_BYTES`` as the former
+also accounts L2, needed in some cases.
+
+Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Stable-dep-of: 87b08913a9ae ("inet: move icmp_global_{credit,stamp} to a separate cache line")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/cache.h | 59 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 59 insertions(+)
+
+diff --git a/include/linux/cache.h b/include/linux/cache.h
+index 0ecb17bb68837..ca2a05682a54b 100644
+--- a/include/linux/cache.h
++++ b/include/linux/cache.h
+@@ -13,6 +13,32 @@
+ #define SMP_CACHE_BYTES L1_CACHE_BYTES
+ #endif
+
++/**
++ * SMP_CACHE_ALIGN - align a value to the L2 cacheline size
++ * @x: value to align
++ *
++ * On some architectures, L2 ("SMP") CL size is bigger than L1, and sometimes,
++ * this needs to be accounted.
++ *
++ * Return: aligned value.
++ */
++#ifndef SMP_CACHE_ALIGN
++#define SMP_CACHE_ALIGN(x) ALIGN(x, SMP_CACHE_BYTES)
++#endif
++
++/*
++ * ``__aligned_largest`` aligns a field to the value most optimal for the
++ * target architecture to perform memory operations. Get the actual value
++ * to be able to use it anywhere else.
++ */
++#ifndef __LARGEST_ALIGN
++#define __LARGEST_ALIGN sizeof(struct { long x; } __aligned_largest)
++#endif
++
++#ifndef LARGEST_ALIGN
++#define LARGEST_ALIGN(x) ALIGN(x, __LARGEST_ALIGN)
++#endif
++
+ /*
+ * __read_mostly is used to keep rarely changing variables out of frequently
+ * updated cachelines. Its use should be reserved for data that is used
+@@ -95,6 +121,39 @@
+ __u8 __cacheline_group_end__##GROUP[0]
+ #endif
+
++/**
++ * __cacheline_group_begin_aligned - declare an aligned group start
++ * @GROUP: name of the group
++ * @...: optional group alignment
++ *
++ * The following block inside a struct:
++ *
++ * __cacheline_group_begin_aligned(grp);
++ * field a;
++ * field b;
++ * __cacheline_group_end_aligned(grp);
++ *
++ * will always be aligned to either the specified alignment or
++ * ``SMP_CACHE_BYTES``.
++ */
++#define __cacheline_group_begin_aligned(GROUP, ...) \
++ __cacheline_group_begin(GROUP) \
++ __aligned((__VA_ARGS__ + 0) ? : SMP_CACHE_BYTES)
++
++/**
++ * __cacheline_group_end_aligned - declare an aligned group end
++ * @GROUP: name of the group
++ * @...: optional alignment (same as was in __cacheline_group_begin_aligned())
++ *
++ * Note that the end marker is aligned to sizeof(long) to allow more precise
++ * size assertion. It also declares a padding at the end to avoid next field
++ * falling into this cacheline.
++ */
++#define __cacheline_group_end_aligned(GROUP, ...) \
++ __cacheline_group_end(GROUP) __aligned(sizeof(long)); \
++ struct { } __cacheline_group_pad__##GROUP \
++ __aligned((__VA_ARGS__ + 0) ? : SMP_CACHE_BYTES)
++
+ #ifndef CACHELINE_ASSERT_GROUP_MEMBER
+ #define CACHELINE_ASSERT_GROUP_MEMBER(TYPE, GROUP, MEMBER) \
+ BUILD_BUG_ON(!(offsetof(TYPE, MEMBER) >= \
+--
+2.51.0
+
--- /dev/null
+From 1a8c3053129f7bcb5b034121808177347f473094 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Nov 2023 07:27:53 +0000
+Subject: cache: enforce cache groups
+
+From: Coco Li <lixiaoyan@google.com>
+
+[ Upstream commit aeb9ce058d7c6193dc41e06b3a5b29d22c446b14 ]
+
+Set up build time warnings to safeguard against future header changes of
+organized structs.
+
+Warning includes:
+
+1) whether all variables are still in the same cache group
+2) whether all the cache groups have the sum of the members size (in the
+ maximum condition, including all members defined in configs)
+
+The __cache_group* variables are ignored in kernel-doc check in the
+various header files they appear in to enforce the cache groups.
+
+Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Coco Li <lixiaoyan@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Shakeel Butt <shakeelb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 87b08913a9ae ("inet: move icmp_global_{credit,stamp} to a separate cache line")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/cache.h | 25 +++++++++++++++++++++++++
+ scripts/kernel-doc | 5 +++++
+ 2 files changed, 30 insertions(+)
+
+diff --git a/include/linux/cache.h b/include/linux/cache.h
+index 9900d20b76c28..0ecb17bb68837 100644
+--- a/include/linux/cache.h
++++ b/include/linux/cache.h
+@@ -85,6 +85,31 @@
+ #define cache_line_size() L1_CACHE_BYTES
+ #endif
+
++#ifndef __cacheline_group_begin
++#define __cacheline_group_begin(GROUP) \
++ __u8 __cacheline_group_begin__##GROUP[0]
++#endif
++
++#ifndef __cacheline_group_end
++#define __cacheline_group_end(GROUP) \
++ __u8 __cacheline_group_end__##GROUP[0]
++#endif
++
++#ifndef CACHELINE_ASSERT_GROUP_MEMBER
++#define CACHELINE_ASSERT_GROUP_MEMBER(TYPE, GROUP, MEMBER) \
++ BUILD_BUG_ON(!(offsetof(TYPE, MEMBER) >= \
++ offsetofend(TYPE, __cacheline_group_begin__##GROUP) && \
++ offsetofend(TYPE, MEMBER) <= \
++ offsetof(TYPE, __cacheline_group_end__##GROUP)))
++#endif
++
++#ifndef CACHELINE_ASSERT_GROUP_SIZE
++#define CACHELINE_ASSERT_GROUP_SIZE(TYPE, GROUP, SIZE) \
++ BUILD_BUG_ON(offsetof(TYPE, __cacheline_group_end__##GROUP) - \
++ offsetofend(TYPE, __cacheline_group_begin__##GROUP) > \
++ SIZE)
++#endif
++
+ /*
+ * Helper to add padding within a struct to ensure data fall into separate
+ * cachelines.
+diff --git a/scripts/kernel-doc b/scripts/kernel-doc
+index 6e199a745ccb2..d963fdf40e900 100755
+--- a/scripts/kernel-doc
++++ b/scripts/kernel-doc
+@@ -1592,6 +1592,11 @@ sub push_parameter($$$$$) {
+ $parameterdescs{$param} = "anonymous\n";
+ $anon_struct_union = 1;
+ }
++ elsif ($param =~ "__cacheline_group" )
++ # handle cache group enforcing variables: they do not need be described in header files
++ {
++ return; # ignore __cacheline_group_begin and __cacheline_group_end
++ }
+
+ # warn if parameter has no description
+ # (but ignore ones starting with # as these are not parameters
+--
+2.51.0
+
--- /dev/null
+From 439d35481a7b6d1c6abab4a29a4a1b0c0fe7f2b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 00:20:02 +0530
+Subject: cpuidle: Skip governor when only one idle state is available
+
+From: Aboorva Devarajan <aboorvad@linux.ibm.com>
+
+[ Upstream commit e5c9ffc6ae1bcdb1062527d611043681ac301aca ]
+
+On certain platforms (PowerNV systems without a power-mgt DT node),
+cpuidle may register only a single idle state. In cases where that
+single state is a polling state (state 0), the ladder governor may
+incorrectly treat state 1 as the first usable state and pass an
+out-of-bounds index. This can lead to a NULL enter callback being
+invoked, ultimately resulting in a system crash.
+
+[ 13.342636] cpuidle-powernv : Only Snooze is available
+[ 13.351854] Faulting instruction address: 0x00000000
+[ 13.376489] NIP [0000000000000000] 0x0
+[ 13.378351] LR [c000000001e01974] cpuidle_enter_state+0x2c4/0x668
+
+Fix this by adding a bail-out in cpuidle_select() that returns state 0
+directly when state_count <= 1, bypassing the governor and keeping the
+tick running.
+
+Fixes: dc2251bf98c6 ("cpuidle: Eliminate the CPUIDLE_DRIVER_STATE_START symbol")
+Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
+Reviewed-by: Christian Loehle <christian.loehle@arm.com>
+Link: https://patch.msgid.link/20260216185005.1131593-2-aboorvad@linux.ibm.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cpuidle/cpuidle.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
+index 6704d610573ad..aa117f2967fdf 100644
+--- a/drivers/cpuidle/cpuidle.c
++++ b/drivers/cpuidle/cpuidle.c
+@@ -356,6 +356,16 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
+ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+ bool *stop_tick)
+ {
++ /*
++ * If there is only a single idle state (or none), there is nothing
++ * meaningful for the governor to choose. Skip the governor and
++ * always use state 0 with the tick running.
++ */
++ if (drv->state_count <= 1) {
++ *stop_tick = false;
++ return 0;
++ }
++
+ return cpuidle_curr_governor->select(drv, dev, stop_tick);
+ }
+
+--
+2.51.0
+
--- /dev/null
+From d2a84e160c92f39531581976e249940d9d5a69f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 23:38:28 +0100
+Subject: drm/amd/display: Use same max plane scaling limits for all 64 bpp
+ formats
+
+From: Mario Kleiner <mario.kleiner.de@gmail.com>
+
+[ Upstream commit f0157ce46cf0e5e2257e19d590c9b16036ce26d4 ]
+
+The plane scaling hw seems to have the same min/max plane scaling limits
+for all 16 bpc / 64 bpp interleaved pixel color formats.
+
+Therefore add cases to amdgpu_dm_plane_get_min_max_dc_plane_scaling() for
+all the 16 bpc fixed-point / unorm formats to use the same .fp16
+up/downscaling factor limits as used by the fp16 floating point formats.
+
+So far, 16 bpc unorm formats were not handled, and the default: path
+returned max/min factors for 32 bpp argb8888 formats, which were wrong
+and bigger than what many DCE / DCN hw generations could handle.
+
+The result sometimes was misscaling of framebuffers with
+DRM_FORMAT_XRGB16161616, DRM_FORMAT_ARGB16161616, DRM_FORMAT_XBGR16161616,
+DRM_FORMAT_ABGR16161616, leading to very wrong looking display, as tested
+on Polaris11 / DCE-11.2.
+
+So far this went unnoticed, because only few userspace clients used such
+16 bpc unorm framebuffers, and those didn't use hw plane scaling, so they
+did not experience this issue.
+
+With upcoming Mesa 26 exposing 16 bpc unorm formats under both OpenGL
+and Vulkan under Wayland, and the upcoming GNOME 50 Mutter Wayland
+compositor allowing for direct scanout of these formats, the scaling
+hw will be used on these formats if possible for HiDPI display scaling,
+so it is important to use the correct hw scaling limits to avoid wrong
+display.
+
+Tested on AMD Polaris 11 / DCE 11.2 with upcoming Mesa 26 and GNOME 50
+on HiDPI displays with scaling enabled. The mutter Wayland compositor now
+correctly falls back to scaling via desktop compositing instead of direct
+scanout, thereby avoiding wrong image display. For unscaled mode, it
+correctly uses direct scanout.
+
+Fixes: 580204038f5b ("drm/amd/display: Enable support for 16 bpc fixed-point framebuffers.")
+Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+index d1329f20b7bd4..746df72405eb4 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+@@ -970,10 +970,15 @@ static void get_min_max_dc_plane_scaling(struct drm_device *dev,
+ *min_downscale = plane_cap->max_downscale_factor.nv12;
+ break;
+
++ /* All 64 bpp formats have the same fp16 scaling limits */
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ABGR16161616F:
++ case DRM_FORMAT_XRGB16161616:
++ case DRM_FORMAT_ARGB16161616:
++ case DRM_FORMAT_XBGR16161616:
++ case DRM_FORMAT_ABGR16161616:
+ *max_upscale = plane_cap->max_upscale_factor.fp16;
+ *min_downscale = plane_cap->max_downscale_factor.fp16;
+ break;
+--
+2.51.0
+
--- /dev/null
+From e7222b03f59ee9d5737c85e10e12d7c3e6fe2e65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 09:25:32 +0000
+Subject: drm/amdgpu: Fix memory leak in amdgpu_acpi_enumerate_xcc()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit c9be63d565789b56ca7b0197e2cb78a3671f95a8 ]
+
+In amdgpu_acpi_enumerate_xcc(), if amdgpu_acpi_dev_init() returns -ENOMEM,
+the function returns directly without releasing the allocated xcc_info,
+resulting in a memory leak.
+
+Fix this by ensuring that xcc_info is properly freed in the error paths.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: 4d5275ab0b18 ("drm/amdgpu: Add parsing of acpi xcc objects")
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+index 8b2f2b921d9de..7730e56444934 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+@@ -1128,8 +1128,10 @@ static int amdgpu_acpi_enumerate_xcc(void)
+ if (!dev_info)
+ ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, bdf);
+
+- if (ret == -ENOMEM)
++ if (ret == -ENOMEM) {
++ kfree(xcc_info);
+ return ret;
++ }
+
+ if (!dev_info) {
+ kfree(xcc_info);
+--
+2.51.0
+
--- /dev/null
+From 2bb72b5c7a0c73fdfb12f14eb1f11983057422e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Jan 2026 08:35:15 +0000
+Subject: drm/amdgpu: Fix memory leak in amdgpu_ras_init()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit ee41e5b63c8210525c936ee637a2c8d185ce873c ]
+
+When amdgpu_nbio_ras_sw_init() fails in amdgpu_ras_init(), the function
+returns directly without freeing the allocated con structure, leading
+to a memory leak.
+
+Fix this by jumping to the release_con label to properly clean up the
+allocated memory before returning the error code.
+
+Compile tested only. Issue found using a prototype static analysis tool
+and code review.
+
+Fixes: fdc94d3a8c88 ("drm/amdgpu: Rework pcie_bif ras sw_init")
+Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+index 7cba98f8bbdca..4214bbd7a1a23 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+@@ -2673,7 +2673,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
+ * to handle fatal error */
+ r = amdgpu_nbio_ras_sw_init(adev);
+ if (r)
+- return r;
++ goto release_con;
+
+ if (adev->nbio.ras &&
+ adev->nbio.ras->init_ras_controller_interrupt) {
+--
+2.51.0
+
--- /dev/null
+From 90df9e4c96690846dd167572976b7e618b2cabf5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Jul 2024 13:26:08 -0400
+Subject: drm/amdkfd: fix debug watchpoints for logical devices
+
+From: Jonathan Kim <Jonathan.Kim@amd.com>
+
+[ Upstream commit b41a382932263b2951bc9e83a22168d579a94865 ]
+
+The number of watchpoints should be set and constrained per logical
+partition device, not by the socket device.
+
+Signed-off-by: Jonathan Kim <jonathan.kim@amd.com>
+Reviewed-by: Harish Kasiviswanathan <harish.kasiviswanathan@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 5a19302cab5c ("drm/amdkfd: Fix watch_id bounds checking in debug address watch v2")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++----------
+ drivers/gpu/drm/amd/amdkfd/kfd_device.c | 5 +++--
+ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 8 ++++----
+ 3 files changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+index 9c32c64c407fa..eb973f16848d3 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+@@ -381,47 +381,47 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i
+
+ *watch_id = KFD_DEBUGGER_INVALID_WATCH_POINT_ID;
+
+- spin_lock(&pdd->dev->kfd->watch_points_lock);
++ spin_lock(&pdd->dev->watch_points_lock);
+
+ for (i = 0; i < MAX_WATCH_ADDRESSES; i++) {
+ /* device watchpoint in use so skip */
+- if ((pdd->dev->kfd->alloc_watch_ids >> i) & 0x1)
++ if ((pdd->dev->alloc_watch_ids >> i) & 0x1)
+ continue;
+
+ pdd->alloc_watch_ids |= 0x1 << i;
+- pdd->dev->kfd->alloc_watch_ids |= 0x1 << i;
++ pdd->dev->alloc_watch_ids |= 0x1 << i;
+ *watch_id = i;
+- spin_unlock(&pdd->dev->kfd->watch_points_lock);
++ spin_unlock(&pdd->dev->watch_points_lock);
+ return 0;
+ }
+
+- spin_unlock(&pdd->dev->kfd->watch_points_lock);
++ spin_unlock(&pdd->dev->watch_points_lock);
+
+ return -ENOMEM;
+ }
+
+ static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id)
+ {
+- spin_lock(&pdd->dev->kfd->watch_points_lock);
++ spin_lock(&pdd->dev->watch_points_lock);
+
+ /* process owns device watch point so safe to clear */
+ if ((pdd->alloc_watch_ids >> watch_id) & 0x1) {
+ pdd->alloc_watch_ids &= ~(0x1 << watch_id);
+- pdd->dev->kfd->alloc_watch_ids &= ~(0x1 << watch_id);
++ pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id);
+ }
+
+- spin_unlock(&pdd->dev->kfd->watch_points_lock);
++ spin_unlock(&pdd->dev->watch_points_lock);
+ }
+
+ static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id)
+ {
+ bool owns_watch_id = false;
+
+- spin_lock(&pdd->dev->kfd->watch_points_lock);
++ spin_lock(&pdd->dev->watch_points_lock);
+ owns_watch_id = watch_id < MAX_WATCH_ADDRESSES &&
+ ((pdd->alloc_watch_ids >> watch_id) & 0x1);
+
+- spin_unlock(&pdd->dev->kfd->watch_points_lock);
++ spin_unlock(&pdd->dev->watch_points_lock);
+
+ return owns_watch_id;
+ }
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+index 6af65db4de947..af50aa9638cab 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+@@ -815,13 +815,14 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
+ dev_err(kfd_device, "Error initializing KFD node\n");
+ goto node_init_error;
+ }
++
++ spin_lock_init(&node->watch_points_lock);
++
+ kfd->nodes[i] = node;
+ }
+
+ svm_range_set_max_pages(kfd->adev);
+
+- spin_lock_init(&kfd->watch_points_lock);
+-
+ kfd->init_complete = true;
+ dev_info(kfd_device, "added device %x:%x\n", kfd->adev->pdev->vendor,
+ kfd->adev->pdev->device);
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+index b475c2ab9768a..0b69ff5375c52 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+@@ -316,6 +316,10 @@ struct kfd_node {
+ struct kfd_local_mem_info local_mem_info;
+
+ struct kfd_dev *kfd;
++
++ /* Track per device allocated watch points */
++ uint32_t alloc_watch_ids;
++ spinlock_t watch_points_lock;
+ };
+
+ struct kfd_dev {
+@@ -368,10 +372,6 @@ struct kfd_dev {
+ struct kfd_node *nodes[MAX_KFD_NODES];
+ unsigned int num_nodes;
+
+- /* Track per device allocated watch points */
+- uint32_t alloc_watch_ids;
+- spinlock_t watch_points_lock;
+-
+ /* Kernel doorbells for KFD device */
+ struct amdgpu_bo *doorbells;
+
+--
+2.51.0
+
--- /dev/null
+From cf5c14e45eff2dd348758645311e929eb0af05ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Feb 2026 21:18:11 +0530
+Subject: drm/amdkfd: Fix watch_id bounds checking in debug address watch v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+
+[ Upstream commit 5a19302cab5cec7ae7f1a60c619951e6c17d8742 ]
+
+The address watch clear code receives watch_id as an unsigned value
+(u32), but some helper functions were using a signed int and checked
+bits by shifting with watch_id.
+
+If a very large watch_id is passed from userspace, it can be converted
+to a negative value. This can cause invalid shifts and may access
+memory outside the watch_points array.
+
+drm/amdkfd: Fix watch_id bounds checking in debug address watch v2
+
+Fix this by checking that watch_id is within MAX_WATCH_ADDRESSES before
+using it. Also use BIT(watch_id) to test and clear bits safely.
+
+This keeps the behavior unchanged for valid watch IDs and avoids
+undefined behavior for invalid ones.
+
+Fixes the below:
+drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c:448
+kfd_dbg_trap_clear_dev_address_watch() error: buffer overflow
+'pdd->watch_points' 4 <= u32max user_rl='0-3,2147483648-u32max' uncapped
+
+drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_debug.c
+ 433 int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd,
+ 434 uint32_t watch_id)
+ 435 {
+ 436 int r;
+ 437
+ 438 if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id))
+
+kfd_dbg_owns_dev_watch_id() doesn't check for negative values so if
+watch_id is larger than INT_MAX it leads to a buffer overflow.
+(Negative shifts are undefined).
+
+ 439 return -EINVAL;
+ 440
+ 441 if (!pdd->dev->kfd->shared_resources.enable_mes) {
+ 442 r = debug_lock_and_unmap(pdd->dev->dqm);
+ 443 if (r)
+ 444 return r;
+ 445 }
+ 446
+ 447 amdgpu_gfx_off_ctrl(pdd->dev->adev, false);
+--> 448 pdd->watch_points[watch_id] = pdd->dev->kfd2kgd->clear_address_watch(
+ 449 pdd->dev->adev,
+ 450 watch_id);
+
+v2: (as per, Jonathan Kim)
+ - Add early watch_id >= MAX_WATCH_ADDRESSES validation in the set path to
+ match the clear path.
+ - Drop the redundant bounds check in kfd_dbg_owns_dev_watch_id().
+
+Fixes: e0f85f4690d0 ("drm/amdkfd: add debug set and clear address watch points operation")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Cc: Jonathan Kim <jonathan.kim@amd.com>
+Cc: Felix Kuehling <felix.kuehling@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: Christian König <christian.koenig@amd.com>
+Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
+Reviewed-by: Jonathan Kim <jonathan.kim@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+index eb973f16848d3..267650dcced9d 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+@@ -400,27 +400,25 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i
+ return -ENOMEM;
+ }
+
+-static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id)
++static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id)
+ {
+ spin_lock(&pdd->dev->watch_points_lock);
+
+ /* process owns device watch point so safe to clear */
+- if ((pdd->alloc_watch_ids >> watch_id) & 0x1) {
+- pdd->alloc_watch_ids &= ~(0x1 << watch_id);
+- pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id);
++ if (pdd->alloc_watch_ids & BIT(watch_id)) {
++ pdd->alloc_watch_ids &= ~BIT(watch_id);
++ pdd->dev->alloc_watch_ids &= ~BIT(watch_id);
+ }
+
+ spin_unlock(&pdd->dev->watch_points_lock);
+ }
+
+-static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id)
++static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id)
+ {
+ bool owns_watch_id = false;
+
+ spin_lock(&pdd->dev->watch_points_lock);
+- owns_watch_id = watch_id < MAX_WATCH_ADDRESSES &&
+- ((pdd->alloc_watch_ids >> watch_id) & 0x1);
+-
++ owns_watch_id = pdd->alloc_watch_ids & BIT(watch_id);
+ spin_unlock(&pdd->dev->watch_points_lock);
+
+ return owns_watch_id;
+@@ -431,6 +429,9 @@ int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd,
+ {
+ int r;
+
++ if (watch_id >= MAX_WATCH_ADDRESSES)
++ return -EINVAL;
++
+ if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id))
+ return -EINVAL;
+
+@@ -468,6 +469,9 @@ int kfd_dbg_trap_set_dev_address_watch(struct kfd_process_device *pdd,
+ if (r)
+ return r;
+
++ if (*watch_id >= MAX_WATCH_ADDRESSES)
++ return -EINVAL;
++
+ if (!pdd->dev->kfd->shared_resources.enable_mes) {
+ r = debug_lock_and_unmap(pdd->dev->dqm);
+ if (r) {
+--
+2.51.0
+
--- /dev/null
+From 987612ba0b9e300b8a0cefc63923204c93797a06 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 9 Jan 2026 08:55:49 +0530
+Subject: drm/i915/acpi: free _DSM package when no connectors
+
+From: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+
+[ Upstream commit 57b85fd53fccfdf14ce7b36d919c31aa752255f8 ]
+
+acpi_evaluate_dsm_typed() returns an ACPI package in pkg.
+When pkg->package.count == 0, we returned without freeing pkg,
+leaking memory. Free pkg before returning on the empty case.
+
+Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
+Fixes: 337d7a1621c7 ("drm/i915: Fix invalid access to ACPI _DSM objects")
+Reviewed-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patch.msgid.link/20260109032549.1826303-1-kaushlendra.kumar@intel.com
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+(cherry picked from commit c0a27a0ca8a34e96d08bb05a2c5d5ccf63fb8dc0)
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/display/intel_acpi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c
+index 9df78e7caa2bd..231b341d968ad 100644
+--- a/drivers/gpu/drm/i915/display/intel_acpi.c
++++ b/drivers/gpu/drm/i915/display/intel_acpi.c
+@@ -93,6 +93,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle)
+
+ if (!pkg->package.count) {
+ DRM_DEBUG_DRIVER("no connection in _DSM\n");
++ ACPI_FREE(pkg);
+ return;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 5a62ebb47b8662c5ed10f31a6988f70f4320b343 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 10:49:56 +0000
+Subject: efi: Fix reservation of unaccepted memory table
+
+From: Kiryl Shutsemau (Meta) <kas@kernel.org>
+
+[ Upstream commit 0862438c90487e79822d5647f854977d50381505 ]
+
+The reserve_unaccepted() function incorrectly calculates the size of the
+memblock reservation for the unaccepted memory table. It aligns the
+size of the table, but fails to account for cases where the table's
+starting physical address (efi.unaccepted) is not page-aligned.
+
+If the table starts at an offset within a page and its end crosses into
+a subsequent page that the aligned size does not cover, the end of the
+table will not be reserved. This can lead to the table being overwritten
+or inaccessible, causing a kernel panic in accept_memory().
+
+This issue was observed when starting Intel TDX VMs with specific memory
+sizes (e.g., > 64GB).
+
+Fix this by calculating the end address first (including the unaligned
+start) and then aligning it up, ensuring the entire range is covered
+by the reservation.
+
+Fixes: 8dbe33956d96 ("efi/unaccepted: Make sure unaccepted table is mapped")
+Reported-by: Moritz Sanft <ms@edgeless.systems>
+Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
+Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
+Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/firmware/efi/efi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index 1ab161e00c867..ef55e3851b362 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -648,13 +648,13 @@ static __init int match_config_table(const efi_guid_t *guid,
+
+ static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted)
+ {
+- phys_addr_t start, size;
++ phys_addr_t start, end;
+
+ start = PAGE_ALIGN_DOWN(efi.unaccepted);
+- size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size);
++ end = PAGE_ALIGN(efi.unaccepted + sizeof(*unaccepted) + unaccepted->size);
+
+- memblock_add(start, size);
+- memblock_reserve(start, size);
++ memblock_add(start, end - start);
++ memblock_reserve(start, end - start);
+ }
+
+ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+--
+2.51.0
+
--- /dev/null
+From 69fae95502073775d0eea5e1b00f07411eca9b82 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 17 Jan 2026 16:50:24 +0000
+Subject: fs/ntfs3: Fix slab-out-of-bounds read in DeleteIndexEntryRoot
+
+From: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+
+[ Upstream commit b2bc7c44ed1779fc9eaab9a186db0f0d01439622 ]
+
+In the 'DeleteIndexEntryRoot' case of the 'do_action' function, the
+entry size ('esize') is retrieved from the log record without adequate
+bounds checking.
+
+Specifically, the code calculates the end of the entry ('e2') using:
+ e2 = Add2Ptr(e1, esize);
+
+It then calculates the size for memmove using 'PtrOffset(e2, ...)',
+which subtracts the end pointer from the buffer limit. If 'esize' is
+maliciously large, 'e2' exceeds the used buffer size. This results in
+a negative offset which, when cast to size_t for memmove, interprets
+as a massive unsigned integer, leading to a heap buffer overflow.
+
+This commit adds a check to ensure that the entry size ('esize') strictly
+fits within the remaining used space of the index header before performing
+memory operations.
+
+Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal")
+Signed-off-by: Jiasheng Jiang <jiashengjiangcool@gmail.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/fslog.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
+index 2a1aeab53ea4b..598b7f42b5e7e 100644
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -3431,6 +3431,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe,
+
+ e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off));
+ esize = le16_to_cpu(e1->size);
++ if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize)
++ goto dirty_vol;
++
+ e2 = Add2Ptr(e1, esize);
+
+ memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used)));
+--
+2.51.0
+
--- /dev/null
+From 91ed73d355c883c97cd587a02cb94319e03cecc1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 28 Dec 2025 11:53:25 +0800
+Subject: fs/ntfs3: prevent infinite loops caused by the next valid being the
+ same
+
+From: Edward Adam Davis <eadavis@qq.com>
+
+[ Upstream commit 27b75ca4e51e3e4554dc85dbf1a0246c66106fd3 ]
+
+When processing valid within the range [valid : pos), if valid cannot
+be retrieved correctly, for example, if the retrieved valid value is
+always the same, this can trigger a potential infinite loop, similar
+to the hung problem reported by syzbot [1].
+
+Adding a check for the valid value within the loop body, and terminating
+the loop and returning -EINVAL if the value is the same as the current
+value, can prevent this.
+
+[1]
+INFO: task syz.4.21:6056 blocked for more than 143 seconds.
+Call Trace:
+ rwbase_write_lock+0x14f/0x750 kernel/locking/rwbase_rt.c:244
+ inode_lock include/linux/fs.h:1027 [inline]
+ ntfs_file_write_iter+0xe6/0x870 fs/ntfs3/file.c:1284
+
+Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
+Reported-by: syzbot+bcf9e1868c1a0c7e04f1@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=bcf9e1868c1a0c7e04f1
+Signed-off-by: Edward Adam Davis <eadavis@qq.com>
+Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ntfs3/file.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index a7fe2e02c32ee..212737a816d7a 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -901,8 +901,12 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from)
+ goto out;
+
+ if (lcn == SPARSE_LCN) {
+- ni->i_valid = valid =
+- frame_vbo + ((u64)clen << sbi->cluster_bits);
++ valid = frame_vbo + ((u64)clen << sbi->cluster_bits);
++ if (ni->i_valid == valid) {
++ err = -EINVAL;
++ goto out;
++ }
++ ni->i_valid = valid;
+ continue;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 39e84b15836fc6e5d38a48f5ad536261559902b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 14:46:41 +0000
+Subject: icmp: icmp_msgs_per_sec and icmp_msgs_burst sysctls become per netns
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit f17bf505ff89595df5147755e51441632a5dc563 ]
+
+Previous patch made ICMP rate limits per netns, it makes sense
+to allow each netns to change the associated sysctl.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20240829144641.3880376-4-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 034bbd806298 ("icmp: prevent possible overflow in icmp_global_allow()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip.h | 3 ---
+ include/net/netns/ipv4.h | 2 ++
+ net/ipv4/icmp.c | 9 ++++-----
+ net/ipv4/sysctl_net_ipv4.c | 32 ++++++++++++++++----------------
+ 4 files changed, 22 insertions(+), 24 deletions(-)
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index a8e70ba54da45..bacdb4fecc89b 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -793,9 +793,6 @@ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
+ bool icmp_global_allow(struct net *net);
+ void icmp_global_consume(struct net *net);
+
+-extern int sysctl_icmp_msgs_per_sec;
+-extern int sysctl_icmp_msgs_burst;
+-
+ #ifdef CONFIG_PROC_FS
+ int ip_misc_proc_init(void);
+ #endif
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 8d32df274910c..40a3a7e2e6070 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -84,6 +84,8 @@ struct netns_ipv4 {
+ u8 sysctl_icmp_errors_use_inbound_ifaddr;
+ int sysctl_icmp_ratelimit;
+ int sysctl_icmp_ratemask;
++ int sysctl_icmp_msgs_per_sec;
++ int sysctl_icmp_msgs_burst;
+ atomic_t icmp_global_credit;
+ u32 icmp_global_stamp;
+ u32 ip_rt_min_pmtu;
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index 0a67e1f0c3ba6..8a8c1fa3bb073 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -221,9 +221,6 @@ static inline void icmp_xmit_unlock(struct sock *sk)
+ spin_unlock(&sk->sk_lock.slock);
+ }
+
+-int sysctl_icmp_msgs_per_sec __read_mostly = 1000;
+-int sysctl_icmp_msgs_burst __read_mostly = 50;
+-
+ /**
+ * icmp_global_allow - Are we allowed to send one more ICMP message ?
+ * @net: network namespace
+@@ -250,14 +247,14 @@ bool icmp_global_allow(struct net *net)
+ if (delta < HZ / 50)
+ return false;
+
+- incr = READ_ONCE(sysctl_icmp_msgs_per_sec) * delta / HZ;
++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ;
+ if (!incr)
+ return false;
+
+ if (cmpxchg(&net->ipv4.icmp_global_stamp, oldstamp, now) == oldstamp) {
+ old = atomic_read(&net->ipv4.icmp_global_credit);
+ do {
+- new = min(old + incr, READ_ONCE(sysctl_icmp_msgs_burst));
++ new = min(old + incr, READ_ONCE(net->ipv4.sysctl_icmp_msgs_burst));
+ } while (!atomic_try_cmpxchg(&net->ipv4.icmp_global_credit, &old, new));
+ }
+ return true;
+@@ -1516,6 +1513,8 @@ static int __net_init icmp_sk_init(struct net *net)
+ net->ipv4.sysctl_icmp_ratelimit = 1 * HZ;
+ net->ipv4.sysctl_icmp_ratemask = 0x1818;
+ net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr = 0;
++ net->ipv4.sysctl_icmp_msgs_per_sec = 1000;
++ net->ipv4.sysctl_icmp_msgs_burst = 50;
+
+ return 0;
+ }
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 6ac890b4073f4..7a1164ea3d3af 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -547,22 +547,6 @@ static struct ctl_table ipv4_table[] = {
+ .mode = 0444,
+ .proc_handler = proc_tcp_available_ulp,
+ },
+- {
+- .procname = "icmp_msgs_per_sec",
+- .data = &sysctl_icmp_msgs_per_sec,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = proc_dointvec_minmax,
+- .extra1 = SYSCTL_ZERO,
+- },
+- {
+- .procname = "icmp_msgs_burst",
+- .data = &sysctl_icmp_msgs_burst,
+- .maxlen = sizeof(int),
+- .mode = 0644,
+- .proc_handler = proc_dointvec_minmax,
+- .extra1 = SYSCTL_ZERO,
+- },
+ {
+ .procname = "udp_mem",
+ .data = &sysctl_udp_mem,
+@@ -649,6 +633,22 @@ static struct ctl_table ipv4_net_table[] = {
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
++ {
++ .procname = "icmp_msgs_per_sec",
++ .data = &init_net.ipv4.sysctl_icmp_msgs_per_sec,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec_minmax,
++ .extra1 = SYSCTL_ZERO,
++ },
++ {
++ .procname = "icmp_msgs_burst",
++ .data = &init_net.ipv4.sysctl_icmp_msgs_burst,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec_minmax,
++ .extra1 = SYSCTL_ZERO,
++ },
+ {
+ .procname = "ping_group_range",
+ .data = &init_net.ipv4.ping_group_range.range,
+--
+2.51.0
+
--- /dev/null
+From 34091d5eff8468b4dac191ea7af281a65d6f921c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 29 Aug 2024 14:46:40 +0000
+Subject: icmp: move icmp_global.credit and icmp_global.stamp to per netns
+ storage
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit b056b4cd9178f7a1d5d57f7b48b073c29729ddaa ]
+
+Host wide ICMP ratelimiter should be per netns, to provide better isolation.
+
+Following patch in this series makes the sysctl per netns.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20240829144641.3880376-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 034bbd806298 ("icmp: prevent possible overflow in icmp_global_allow()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ip.h | 4 ++--
+ include/net/netns/ipv4.h | 3 ++-
+ net/ipv4/icmp.c | 26 +++++++++++---------------
+ net/ipv6/icmp.c | 4 ++--
+ 4 files changed, 17 insertions(+), 20 deletions(-)
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index d8bf1f0a6919c..a8e70ba54da45 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -790,8 +790,8 @@ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
+ ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0);
+ }
+
+-bool icmp_global_allow(void);
+-void icmp_global_consume(void);
++bool icmp_global_allow(struct net *net);
++void icmp_global_consume(struct net *net);
+
+ extern int sysctl_icmp_msgs_per_sec;
+ extern int sysctl_icmp_msgs_burst;
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 7a41c47915367..8d32df274910c 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -84,7 +84,8 @@ struct netns_ipv4 {
+ u8 sysctl_icmp_errors_use_inbound_ifaddr;
+ int sysctl_icmp_ratelimit;
+ int sysctl_icmp_ratemask;
+-
++ atomic_t icmp_global_credit;
++ u32 icmp_global_stamp;
+ u32 ip_rt_min_pmtu;
+ int ip_rt_mtu_expires;
+ int ip_rt_min_advmss;
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index 9653ef1281a46..0a67e1f0c3ba6 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -224,19 +224,15 @@ static inline void icmp_xmit_unlock(struct sock *sk)
+ int sysctl_icmp_msgs_per_sec __read_mostly = 1000;
+ int sysctl_icmp_msgs_burst __read_mostly = 50;
+
+-static struct {
+- atomic_t credit;
+- u32 stamp;
+-} icmp_global;
+-
+ /**
+ * icmp_global_allow - Are we allowed to send one more ICMP message ?
++ * @net: network namespace
+ *
+ * Uses a token bucket to limit our ICMP messages to ~sysctl_icmp_msgs_per_sec.
+ * Returns false if we reached the limit and can not send another packet.
+ * Works in tandem with icmp_global_consume().
+ */
+-bool icmp_global_allow(void)
++bool icmp_global_allow(struct net *net)
+ {
+ u32 delta, now, oldstamp;
+ int incr, new, old;
+@@ -245,11 +241,11 @@ bool icmp_global_allow(void)
+ * Then later icmp_global_consume() could consume more credits,
+ * this is an acceptable race.
+ */
+- if (atomic_read(&icmp_global.credit) > 0)
++ if (atomic_read(&net->ipv4.icmp_global_credit) > 0)
+ return true;
+
+ now = jiffies;
+- oldstamp = READ_ONCE(icmp_global.stamp);
++ oldstamp = READ_ONCE(net->ipv4.icmp_global_stamp);
+ delta = min_t(u32, now - oldstamp, HZ);
+ if (delta < HZ / 50)
+ return false;
+@@ -258,23 +254,23 @@ bool icmp_global_allow(void)
+ if (!incr)
+ return false;
+
+- if (cmpxchg(&icmp_global.stamp, oldstamp, now) == oldstamp) {
+- old = atomic_read(&icmp_global.credit);
++ if (cmpxchg(&net->ipv4.icmp_global_stamp, oldstamp, now) == oldstamp) {
++ old = atomic_read(&net->ipv4.icmp_global_credit);
+ do {
+ new = min(old + incr, READ_ONCE(sysctl_icmp_msgs_burst));
+- } while (!atomic_try_cmpxchg(&icmp_global.credit, &old, new));
++ } while (!atomic_try_cmpxchg(&net->ipv4.icmp_global_credit, &old, new));
+ }
+ return true;
+ }
+ EXPORT_SYMBOL(icmp_global_allow);
+
+-void icmp_global_consume(void)
++void icmp_global_consume(struct net *net)
+ {
+ int credits = get_random_u32_below(3);
+
+ /* Note: this might make icmp_global.credit negative. */
+ if (credits)
+- atomic_sub(credits, &icmp_global.credit);
++ atomic_sub(credits, &net->ipv4.icmp_global_credit);
+ }
+ EXPORT_SYMBOL(icmp_global_consume);
+
+@@ -300,7 +296,7 @@ static bool icmpv4_global_allow(struct net *net, int type, int code,
+ if (icmpv4_mask_allow(net, type, code))
+ return true;
+
+- if (icmp_global_allow()) {
++ if (icmp_global_allow(net)) {
+ *apply_ratelimit = true;
+ return true;
+ }
+@@ -337,7 +333,7 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
+ if (!rc)
+ __ICMP_INC_STATS(net, ICMP_MIB_RATELIMITHOST);
+ else
+- icmp_global_consume();
++ icmp_global_consume(net);
+ return rc;
+ }
+
+diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
+index e9e457b7d4eac..1d1c56e0e2460 100644
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -181,7 +181,7 @@ static bool icmpv6_global_allow(struct net *net, int type,
+ if (icmpv6_mask_allow(net, type))
+ return true;
+
+- if (icmp_global_allow()) {
++ if (icmp_global_allow(net)) {
+ *apply_ratelimit = true;
+ return true;
+ }
+@@ -231,7 +231,7 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
+ __ICMP6_INC_STATS(net, ip6_dst_idev(dst),
+ ICMP6_MIB_RATELIMITHOST);
+ else
+- icmp_global_consume();
++ icmp_global_consume(net);
+ dst_release(dst);
+ return res;
+ }
+--
+2.51.0
+
--- /dev/null
+From 29b5644bc67288e1aa069bfe3e8fba45e7f5a93e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:28 +0000
+Subject: icmp: prevent possible overflow in icmp_global_allow()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 034bbd806298e9ba4197dd1587b0348ee30996ea ]
+
+Following expression can overflow
+if sysctl_icmp_msgs_per_sec is big enough.
+
+sysctl_icmp_msgs_per_sec * delta / HZ;
+
+Fixes: 4cdf507d5452 ("icmp: add a global rate limitation")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216142832.3834174-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/icmp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index 8a8c1fa3bb073..784591ed5bb7c 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -247,7 +247,8 @@ bool icmp_global_allow(struct net *net)
+ if (delta < HZ / 50)
+ return false;
+
+- incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ;
++ incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec);
++ incr = div_u64((u64)incr * delta, HZ);
+ if (!incr)
+ return false;
+
+--
+2.51.0
+
--- /dev/null
+From b1a67ef30071ff00e67198a4a2a524dd9a2c29d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:28:29 +0000
+Subject: inet: move icmp_global_{credit,stamp} to a separate cache line
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 87b08913a9ae82082e276d237ece08fc8ee24380 ]
+
+icmp_global_credit was meant to be changed ~1000 times per second,
+but if an admin sets net.ipv4.icmp_msgs_per_sec to a very high value,
+icmp_global_credit changes can inflict false sharing to surrounding
+fields that are read mostly.
+
+Move icmp_global_credit and icmp_global_stamp to a separate
+cacheline aligned group.
+
+Fixes: b056b4cd9178 ("icmp: move icmp_global.credit and icmp_global.stamp to per netns storage")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216142832.3834174-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netns/ipv4.h | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 3d7e03847b5be..521529e61ae1c 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -74,6 +74,12 @@ struct netns_ipv4 {
+ int sysctl_tcp_rmem[3];
+ __cacheline_group_end(netns_ipv4_read_rx);
+
++ /* ICMP rate limiter hot cache line. */
++ __cacheline_group_begin_aligned(icmp);
++ atomic_t icmp_global_credit;
++ u32 icmp_global_stamp;
++ __cacheline_group_end_aligned(icmp);
++
+ struct inet_timewait_death_row tcp_death_row;
+ struct udp_table *udp_table;
+
+@@ -118,8 +124,7 @@ struct netns_ipv4 {
+ int sysctl_icmp_ratemask;
+ int sysctl_icmp_msgs_per_sec;
+ int sysctl_icmp_msgs_burst;
+- atomic_t icmp_global_credit;
+- u32 icmp_global_stamp;
++
+ u32 ip_rt_min_pmtu;
+ int ip_rt_mtu_expires;
+ int ip_rt_min_advmss;
+--
+2.51.0
+
--- /dev/null
+From 4b10e2f405fcb891206dc863aa483b49d58de6e7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:22:02 +0000
+Subject: ipv6: fix a race in ip6_sock_set_v6only()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 452a3eee22c57a5786ae6db5c97f3b0ec13bb3b7 ]
+
+It is unlikely that this function will be ever called
+with isk->inet_num being not zero.
+
+Perform the check on isk->inet_num inside the locked section
+for complete safety.
+
+Fixes: 9b115749acb24 ("ipv6: add ip6_sock_set_v6only")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Link: https://patch.msgid.link/20260216102202.3343588-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/ipv6.h | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index c6932d1a3fa80..9e5e44c6da0a6 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -1293,12 +1293,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
+
+ static inline int ip6_sock_set_v6only(struct sock *sk)
+ {
+- if (inet_sk(sk)->inet_num)
+- return -EINVAL;
++ int ret = 0;
++
+ lock_sock(sk);
+- sk->sk_ipv6only = true;
++ if (inet_sk(sk)->inet_num)
++ ret = -EINVAL;
++ else
++ sk->sk_ipv6only = true;
+ release_sock(sk);
+- return 0;
++ return ret;
+ }
+
+ static inline void ip6_sock_set_recverr(struct sock *sk)
+--
+2.51.0
+
--- /dev/null
+From caa04607ff0203bf1250fd859959e2c88b16e7f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 17:50:21 +0000
+Subject: ipv6: Fix out-of-bound access in fib6_add_rt2node().
+
+From: Kuniyuki Iwashima <kuniyu@google.com>
+
+[ Upstream commit 8244f959e2c125c849e569f5b23ed49804cce695 ]
+
+syzbot reported out-of-bound read in fib6_add_rt2node(). [0]
+
+When IPv6 route is created with RTA_NH_ID, struct fib6_info
+does not have the trailing struct fib6_nh.
+
+The cited commit started to check !iter->fib6_nh->fib_nh_gw_family
+to ensure that rt6_qualify_for_ecmp() will return false for iter.
+
+If iter->nh is not NULL, rt6_qualify_for_ecmp() returns false anyway.
+
+Let's check iter->nh before reading iter->fib6_nh and avoid OOB read.
+
+[0]:
+BUG: KASAN: slab-out-of-bounds in fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142
+Read of size 1 at addr ffff8880384ba6de by task syz.0.18/5500
+
+CPU: 0 UID: 0 PID: 5500 Comm: syz.0.18 Not tainted syzkaller #0 PREEMPT(full)
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
+ print_address_description mm/kasan/report.c:378 [inline]
+ print_report+0xba/0x230 mm/kasan/report.c:482
+ kasan_report+0x117/0x150 mm/kasan/report.c:595
+ fib6_add_rt2node+0x349c/0x3500 net/ipv6/ip6_fib.c:1142
+ fib6_add_rt2node_nh net/ipv6/ip6_fib.c:1363 [inline]
+ fib6_add+0x910/0x18c0 net/ipv6/ip6_fib.c:1531
+ __ip6_ins_rt net/ipv6/route.c:1351 [inline]
+ ip6_route_add+0xde/0x1b0 net/ipv6/route.c:3957
+ inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660
+ rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+RIP: 0033:0x7f9316b9aeb9
+Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007ffd8809b678 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007f9316e15fa0 RCX: 00007f9316b9aeb9
+RDX: 0000000000000000 RSI: 0000200000004380 RDI: 0000000000000003
+RBP: 00007f9316c08c1f R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 00007f9316e15fac R14: 00007f9316e15fa0 R15: 00007f9316e15fa0
+ </TASK>
+
+Allocated by task 5499:
+ kasan_save_stack mm/kasan/common.c:57 [inline]
+ kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
+ poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
+ __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:415
+ kasan_kmalloc include/linux/kasan.h:263 [inline]
+ __do_kmalloc_node mm/slub.c:5657 [inline]
+ __kmalloc_noprof+0x40c/0x7e0 mm/slub.c:5669
+ kmalloc_noprof include/linux/slab.h:961 [inline]
+ kzalloc_noprof include/linux/slab.h:1094 [inline]
+ fib6_info_alloc+0x30/0xf0 net/ipv6/ip6_fib.c:155
+ ip6_route_info_create+0x142/0x860 net/ipv6/route.c:3820
+ ip6_route_add+0x49/0x1b0 net/ipv6/route.c:3949
+ inet6_rtm_newroute+0x268/0x19e0 net/ipv6/route.c:5660
+ rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+
+Fixes: bbf4a17ad9ff ("ipv6: Fix ECMP sibling count mismatch when clearing RTF_ADDRCONF")
+Reported-by: syzbot+707d6a5da1ab9e0c6f9d@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/698cbfba.050a0220.2eeac1.009d.GAE@google.com/
+Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
+Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
+Reviewed-by: Shigeru Yoshida <syoshida@redhat.com>
+Link: https://patch.msgid.link/20260211175133.3657034-1-kuniyu@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/ip6_fib.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index fe57884ca7238..6fe867579118b 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -1137,7 +1137,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt,
+ fib6_add_gc_list(iter);
+ }
+ if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) &&
+- !iter->fib6_nh->fib_nh_gw_family) {
++ (iter->nh || !iter->fib6_nh->fib_nh_gw_family)) {
+ iter->fib6_flags &= ~RTF_ADDRCONF;
+ iter->fib6_flags &= ~RTF_PREFIX_RT;
+ }
+--
+2.51.0
+
--- /dev/null
+From 65e16191624c6d2fad2df78573992651dc2f321c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 13:45:22 -0800
+Subject: kbuild: Add objtool to top-level clean target
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit 68b4fe32d73789dea23e356f468de67c8367ef8f ]
+
+Objtool is an integral part of the build, make sure it gets cleaned by
+"make clean" and "make mrproper".
+
+Fixes: 442f04c34a1a ("objtool: Add tool to perform compile-time stack metadata validation")
+Reported-by: Jens Remus <jremus@linux.ibm.com>
+Closes: https://lore.kernel.org/15f2af3b-be33-46fc-b972-6b8e7e0aa52e@linux.ibm.com
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Tested-by: Jens Remus <jremus@linux.ibm.com>
+Link: https://patch.msgid.link/968faf2ed30fa8b3519f79f01a1ecfe7929553e5.1770759919.git.jpoimboe@kernel.org
+[nathan: use Closes: instead of Link: per checkpatch.pl]
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Makefile | 11 ++++++++++-
+ tools/objtool/Makefile | 2 ++
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index b9c04d8271b94..1c7555ea8b06a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1356,6 +1356,15 @@ ifneq ($(wildcard $(resolve_btfids_O)),)
+ $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean
+ endif
+
++PHONY += objtool_clean
++
++objtool_O = $(abspath $(objtree))/tools/objtool
++
++objtool_clean:
++ifneq ($(wildcard $(objtool_O)),)
++ $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) clean
++endif
++
+ tools/: FORCE
+ $(Q)mkdir -p $(objtree)/tools
+ $(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/
+@@ -1509,7 +1518,7 @@ vmlinuxclean:
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean
+ $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean)
+
+-clean: archclean vmlinuxclean resolve_btfids_clean
++clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean
+
+ # mrproper - Delete all generated files, including .config
+ #
+diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
+index 83b100c1e7f68..e9a0f89e9c39a 100644
+--- a/tools/objtool/Makefile
++++ b/tools/objtool/Makefile
+@@ -7,6 +7,8 @@ srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+ srctree := $(patsubst %/,%,$(dir $(srctree)))
+ endif
+
++RM ?= rm -f
++
+ LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/
+ ifneq ($(OUTPUT),)
+ LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd
+--
+2.51.0
+
--- /dev/null
+From 226f456233b3f23e9c7d88ac6b6cbdd7d4d000b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 14:25:57 +0000
+Subject: macvlan: observe an RCU grace period in macvlan_common_newlink()
+ error path
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit e3f000f0dee1bfab52e2e61ca6a3835d9e187e35 ]
+
+valis reported that a race condition still happens after my prior patch.
+
+macvlan_common_newlink() might have made @dev visible before
+detecting an error, and its caller will directly call free_netdev(dev).
+
+We must respect an RCU period, either in macvlan or the core networking
+stack.
+
+After adding a temporary mdelay(1000) in macvlan_forward_source_one()
+to open the race window, valis repro was:
+
+ip link add p1 type veth peer p2
+ip link set address 00:00:00:00:00:20 dev p1
+ip link set up dev p1
+ip link set up dev p2
+ip link add mv0 link p2 type macvlan mode source
+
+(ip link add invalid% link p2 type macvlan mode source macaddr add
+00:00:00:00:00:20 &) ; sleep 0.5 ; ping -c1 -I p1 1.2.3.4
+PING 1.2.3.4 (1.2.3.4): 56 data bytes
+RTNETLINK answers: Invalid argument
+
+BUG: KASAN: slab-use-after-free in macvlan_forward_source
+(drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+Read of size 8 at addr ffff888016bb89c0 by task e/175
+
+CPU: 1 UID: 1000 PID: 175 Comm: e Not tainted 6.19.0-rc8+ #33 NONE
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
+Call Trace:
+<IRQ>
+dump_stack_lvl (lib/dump_stack.c:123)
+print_report (mm/kasan/report.c:379 mm/kasan/report.c:482)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+kasan_report (mm/kasan/report.c:597)
+? macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+macvlan_forward_source (drivers/net/macvlan.c:408 drivers/net/macvlan.c:444)
+? tasklet_init (kernel/softirq.c:983)
+macvlan_handle_frame (drivers/net/macvlan.c:501)
+
+Allocated by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+__kasan_kmalloc (mm/kasan/common.c:419)
+__kvmalloc_node_noprof (./include/linux/kasan.h:263 mm/slub.c:5657
+mm/slub.c:7140)
+alloc_netdev_mqs (net/core/dev.c:12012)
+rtnl_create_link (net/core/rtnetlink.c:3648)
+rtnl_newlink (net/core/rtnetlink.c:3830 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Freed by task 169:
+kasan_save_stack (mm/kasan/common.c:58)
+kasan_save_track (./arch/x86/include/asm/current.h:25
+mm/kasan/common.c:70 mm/kasan/common.c:79)
+kasan_save_free_info (mm/kasan/generic.c:587)
+__kasan_slab_free (mm/kasan/common.c:287)
+kfree (mm/slub.c:6674 mm/slub.c:6882)
+rtnl_newlink (net/core/rtnetlink.c:3845 net/core/rtnetlink.c:3957
+net/core/rtnetlink.c:4072)
+rtnetlink_rcv_msg (net/core/rtnetlink.c:6958)
+netlink_rcv_skb (net/netlink/af_netlink.c:2550)
+netlink_unicast (net/netlink/af_netlink.c:1319 net/netlink/af_netlink.c:1344)
+netlink_sendmsg (net/netlink/af_netlink.c:1894)
+__sys_sendto (net/socket.c:727 net/socket.c:742 net/socket.c:2206)
+__x64_sys_sendto (net/socket.c:2209)
+do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
+entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:131)
+
+Fixes: f8db6475a836 ("macvlan: fix error recovery in macvlan_common_newlink()")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: valis <sec@valis.email>
+Link: https://patch.msgid.link/20260213142557.3059043-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macvlan.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index fea7352e2a470..4e28fcbf13c74 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1577,6 +1577,11 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
+ if (create)
+ macvlan_port_destroy(port->dev);
+ }
++ /* @dev might have been made visible before an error was detected.
++ * Make sure to observe an RCU grace period before our caller
++ * (rtnl_newlink()) frees it.
++ */
++ synchronize_net();
+ return err;
+ }
+ EXPORT_SYMBOL_GPL(macvlan_common_newlink);
+--
+2.51.0
+
--- /dev/null
+From f291b1916d80fe1cf9762322ba5f240958b42c2d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 09:00:30 +0200
+Subject: net: bridge: mcast: always update mdb_n_entries for vlan contexts
+
+From: Nikolay Aleksandrov <nikolay@nvidia.com>
+
+[ Upstream commit 8b769e311a86bb9d15c5658ad283b86fc8f080a2 ]
+
+syzbot triggered a warning[1] about the number of mdb entries in a context.
+It turned out that there are multiple ways to trigger that warning today
+(some got added during the years), the root cause of the problem is that
+the increase is done conditionally, and over the years these different
+conditions increased so there were new ways to trigger the warning, that is
+to do a decrease which wasn't paired with a previous increase.
+
+For example one way to trigger it is with flush:
+ $ ip l add br0 up type bridge vlan_filtering 1 mcast_snooping 1
+ $ ip l add dumdum up master br0 type dummy
+ $ bridge mdb add dev br0 port dumdum grp 239.0.0.1 permanent vid 1
+ $ ip link set dev br0 down
+ $ ip link set dev br0 type bridge mcast_vlan_snooping 1
+ ^^^^ this will enable snooping, but will not update mdb_n_entries
+ because in __br_multicast_enable_port_ctx() we check !netif_running
+ $ bridge mdb flush dev br0
+ ^^^ this will trigger the warning because it will delete the pg which
+ we added above, which will try to decrease mdb_n_entries
+
+Fix the problem by removing the conditional increase and always keep the
+count up-to-date while the vlan exists. In order to do that we have to
+first initialize it on port-vlan context creation, and then always increase
+or decrease the value regardless of mcast options. To keep the current
+behaviour we have to enforce the mdb limit only if the context is port's or
+if the port-vlan's mcast snooping is enabled.
+
+[1]
+ ------------[ cut here ]------------
+ n == 0
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline], CPU#0: syz.4.4607/22043
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline], CPU#0: syz.4.4607/22043
+ WARNING: net/bridge/br_multicast.c:718 at br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825, CPU#0: syz.4.4607/22043
+ Modules linked in:
+ CPU: 0 UID: 0 PID: 22043 Comm: syz.4.4607 Not tainted syzkaller #0 PREEMPT(full)
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026
+ RIP: 0010:br_multicast_port_ngroups_dec_one net/bridge/br_multicast.c:718 [inline]
+ RIP: 0010:br_multicast_port_ngroups_dec net/bridge/br_multicast.c:771 [inline]
+ RIP: 0010:br_multicast_del_pg+0x1bbe/0x1e20 net/bridge/br_multicast.c:825
+ Code: 41 5f 5d e9 04 7a 48 f7 e8 3f 73 5c f7 90 0f 0b 90 e9 cf fd ff ff e8 31 73 5c f7 90 0f 0b 90 e9 16 fd ff ff e8 23 73 5c f7 90 <0f> 0b 90 e9 60 fd ff ff e8 15 73 5c f7 eb 05 e8 0e 73 5c f7 48 8b
+ RSP: 0018:ffffc9000c207220 EFLAGS: 00010293
+ RAX: ffffffff8a68042d RBX: ffff88807c6f1800 RCX: ffff888066e90000
+ RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+ RBP: 0000000000000000 R08: ffff888066e90000 R09: 000000000000000c
+ R10: 000000000000000c R11: 0000000000000000 R12: ffff8880303ef800
+ R13: dffffc0000000000 R14: ffff888050eb11c4 R15: 1ffff1100a1d6238
+ FS: 00007fa45921b6c0(0000) GS:ffff8881256f5000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007fa4591f9ff8 CR3: 0000000081df2000 CR4: 00000000003526f0
+ Call Trace:
+ <TASK>
+ br_mdb_flush_pgs net/bridge/br_mdb.c:1525 [inline]
+ br_mdb_flush net/bridge/br_mdb.c:1544 [inline]
+ br_mdb_del_bulk+0x5e2/0xb20 net/bridge/br_mdb.c:1561
+ rtnl_mdb_del+0x48a/0x640 net/core/rtnetlink.c:-1
+ rtnetlink_rcv_msg+0x77e/0xbe0 net/core/rtnetlink.c:6967
+ netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
+ netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
+ netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
+ netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
+ sock_sendmsg_nosec net/socket.c:727 [inline]
+ __sock_sendmsg net/socket.c:742 [inline]
+ ____sys_sendmsg+0xa68/0xad0 net/socket.c:2592
+ ___sys_sendmsg+0x2a5/0x360 net/socket.c:2646
+ __sys_sendmsg net/socket.c:2678 [inline]
+ __do_sys_sendmsg net/socket.c:2683 [inline]
+ __se_sys_sendmsg net/socket.c:2681 [inline]
+ __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2681
+ do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
+ do_syscall_64+0xe2/0xf80 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ RIP: 0033:0x7fa45839aeb9
+ Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 e8 ff ff ff f7 d8 64 89 01 48
+ RSP: 002b:00007fa45921b028 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+ RAX: ffffffffffffffda RBX: 00007fa458615fa0 RCX: 00007fa45839aeb9
+ RDX: 0000000000000000 RSI: 00002000000000c0 RDI: 0000000000000004
+ RBP: 00007fa458408c1f R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+ R13: 00007fa458616038 R14: 00007fa458615fa0 R15: 00007fff0b59fae8
+ </TASK>
+
+Fixes: b57e8d870d52 ("net: bridge: Maintain number of MDB entries in net_bridge_mcast_port")
+Reported-by: syzbot+d5d1b7343531d17bd3c5@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/aYrWbRp83MQR1ife@debil/T/#t
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com>
+Link: https://patch.msgid.link/20260213070031.1400003-2-nikolay@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_multicast.c | 45 ++++++++++++++++-----------------------
+ 1 file changed, 18 insertions(+), 27 deletions(-)
+
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index 4a2d94e8717e6..4e75ec75c7021 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -243,14 +243,11 @@ br_multicast_port_vid_to_port_ctx(struct net_bridge_port *port, u16 vid)
+
+ lockdep_assert_held_once(&port->br->multicast_lock);
+
+- if (!br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED))
+- return NULL;
+-
+ /* Take RCU to access the vlan. */
+ rcu_read_lock();
+
+ vlan = br_vlan_find(nbp_vlan_group_rcu(port), vid);
+- if (vlan && !br_multicast_port_ctx_vlan_disabled(&vlan->port_mcast_ctx))
++ if (vlan)
+ pmctx = &vlan->port_mcast_ctx;
+
+ rcu_read_unlock();
+@@ -700,7 +697,10 @@ br_multicast_port_ngroups_inc_one(struct net_bridge_mcast_port *pmctx,
+ u32 max = READ_ONCE(pmctx->mdb_max_entries);
+ u32 n = READ_ONCE(pmctx->mdb_n_entries);
+
+- if (max && n >= max) {
++ /* enforce the max limit when it's a port pmctx or a port-vlan pmctx
++ * with snooping enabled
++ */
++ if (!br_multicast_port_ctx_vlan_disabled(pmctx) && max && n >= max) {
+ NL_SET_ERR_MSG_FMT_MOD(extack, "%s is already in %u groups, and mcast_max_groups=%u",
+ what, n, max);
+ return -E2BIG;
+@@ -735,9 +735,7 @@ static int br_multicast_port_ngroups_inc(struct net_bridge_port *port,
+ return err;
+ }
+
+- /* Only count on the VLAN context if VID is given, and if snooping on
+- * that VLAN is enabled.
+- */
++ /* Only count on the VLAN context if VID is given */
+ if (!group->vid)
+ return 0;
+
+@@ -2009,6 +2007,18 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port,
+ timer_setup(&pmctx->ip6_own_query.timer,
+ br_ip6_multicast_port_query_expired, 0);
+ #endif
++ /* initialize mdb_n_entries if a new port vlan is being created */
++ if (vlan) {
++ struct net_bridge_port_group *pg;
++ u32 n = 0;
++
++ spin_lock_bh(&port->br->multicast_lock);
++ hlist_for_each_entry(pg, &port->mglist, mglist)
++ if (pg->key.addr.vid == vlan->vid)
++ n++;
++ WRITE_ONCE(pmctx->mdb_n_entries, n);
++ spin_unlock_bh(&port->br->multicast_lock);
++ }
+ }
+
+ void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx)
+@@ -2092,25 +2102,6 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
+ br_ip4_multicast_add_router(brmctx, pmctx);
+ br_ip6_multicast_add_router(brmctx, pmctx);
+ }
+-
+- if (br_multicast_port_ctx_is_vlan(pmctx)) {
+- struct net_bridge_port_group *pg;
+- u32 n = 0;
+-
+- /* The mcast_n_groups counter might be wrong. First,
+- * BR_VLFLAG_MCAST_ENABLED is toggled before temporary entries
+- * are flushed, thus mcast_n_groups after the toggle does not
+- * reflect the true values. And second, permanent entries added
+- * while BR_VLFLAG_MCAST_ENABLED was disabled, are not reflected
+- * either. Thus we have to refresh the counter.
+- */
+-
+- hlist_for_each_entry(pg, &pmctx->port->mglist, mglist) {
+- if (pg->key.addr.vid == pmctx->vlan->vid)
+- n++;
+- }
+- WRITE_ONCE(pmctx->mdb_n_entries, n);
+- }
+ }
+
+ static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
+--
+2.51.0
+
--- /dev/null
+From b0a464b55e013fe646a7150cc767ecf2c3233e76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 09:28:59 +0200
+Subject: net/mlx5: Fix multiport device check over light SFs
+
+From: Shay Drory <shayd@nvidia.com>
+
+[ Upstream commit 47bf2e813817159f4d195be83a9b5a640ee6baec ]
+
+Driver is using num_vhca_ports capability to distinguish between
+multiport master device and multiport slave device. num_vhca_ports is a
+capability the driver sets according to the MAX num_vhca_ports
+capability reported by FW. On the other hand, light SFs doesn't set the
+above capbility.
+
+This leads to wrong results whenever light SFs is checking whether he is
+a multiport master or slave.
+
+Therefore, use the MAX capability to distinguish between master and
+slave devices.
+
+Fixes: e71383fb9cd1 ("net/mlx5: Light probe local SFs")
+Signed-off-by: Shay Drory <shayd@nvidia.com>
+Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20260218072904.1764634-2-tariqt@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/mlx5/driver.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index c0e0468b25a18..c29ecbfbf3da2 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -1288,12 +1288,12 @@ static inline bool mlx5_rl_is_supported(struct mlx5_core_dev *dev)
+ static inline int mlx5_core_is_mp_slave(struct mlx5_core_dev *dev)
+ {
+ return MLX5_CAP_GEN(dev, affiliate_nic_vport_criteria) &&
+- MLX5_CAP_GEN(dev, num_vhca_ports) <= 1;
++ MLX5_CAP_GEN_MAX(dev, num_vhca_ports) <= 1;
+ }
+
+ static inline int mlx5_core_is_mp_master(struct mlx5_core_dev *dev)
+ {
+- return MLX5_CAP_GEN(dev, num_vhca_ports) > 1;
++ return MLX5_CAP_GEN_MAX(dev, num_vhca_ports) > 1;
+ }
+
+ static inline int mlx5_core_mp_enabled(struct mlx5_core_dev *dev)
+--
+2.51.0
+
--- /dev/null
+From d6267ee421be7d2d0767a6a694f99500c02080e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:02 +0000
+Subject: net: mscc: ocelot: add missing lock protection in
+ ocelot_port_xmit_inj()
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 026f6513c5880c2c89e38ad66bbec2868f978605 ]
+
+ocelot_port_xmit_inj() calls ocelot_can_inject() and
+ocelot_port_inject_frame() without holding the injection group lock.
+Both functions contain lockdep_assert_held() for the injection lock,
+and the correct caller felix_port_deferred_xmit() properly acquires
+the lock using ocelot_lock_inj_grp() before calling these functions.
+
+Add ocelot_lock_inj_grp()/ocelot_unlock_inj_grp() around the register
+injection path to fix the missing lock protection. The FDMA path is not
+affected as it uses its own locking mechanism.
+
+Fixes: c5e12ac3beb0 ("net: mscc: ocelot: serialize access to the injection/extraction groups")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-4-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index 84b3dcf1d2f5a..b516b4e1ed974 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -597,14 +597,22 @@ static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb,
+ int port = priv->port.index;
+ u32 rew_op = 0;
+
+- if (!ocelot_can_inject(ocelot, 0))
++ ocelot_lock_inj_grp(ocelot, 0);
++
++ if (!ocelot_can_inject(ocelot, 0)) {
++ ocelot_unlock_inj_grp(ocelot, 0);
+ return NETDEV_TX_BUSY;
++ }
+
+- if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) {
++ ocelot_unlock_inj_grp(ocelot, 0);
+ return NETDEV_TX_OK;
++ }
+
+ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
++ ocelot_unlock_inj_grp(ocelot, 0);
++
+ consume_skb(skb);
+
+ return NETDEV_TX_OK;
+--
+2.51.0
+
--- /dev/null
+From e11b62207d110c0df277e1f6f254a7ff28bec62e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:00 +0000
+Subject: net: mscc: ocelot: extract ocelot_xmit_timestamp() helper
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 29372f07f7969a2f0490793226ecf6c8c6bde0fa ]
+
+Extract the PTP timestamp handling logic from ocelot_port_xmit() into a
+separate ocelot_xmit_timestamp() helper function. This is a pure
+refactor with no behavioral change.
+
+The helper returns false if the skb was consumed (freed) due to a
+timestamp request failure, and true if the caller should continue with
+frame injection. The rew_op value is returned via pointer.
+
+This prepares for splitting ocelot_port_xmit() into separate FDMA and
+register injection paths in a subsequent patch.
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-2-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 36 ++++++++++++++++----------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index 21a87a3fc5562..e2b475bf58e6c 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -551,33 +551,41 @@ static int ocelot_port_stop(struct net_device *dev)
+ return 0;
+ }
+
+-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port,
++ struct sk_buff *skb, u32 *rew_op)
+ {
+- struct ocelot_port_private *priv = netdev_priv(dev);
+- struct ocelot_port *ocelot_port = &priv->port;
+- struct ocelot *ocelot = ocelot_port->ocelot;
+- int port = priv->port.index;
+- u32 rew_op = 0;
+-
+- if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
+- !ocelot_can_inject(ocelot, 0))
+- return NETDEV_TX_BUSY;
+-
+- /* Check if timestamping is needed */
+ if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ struct sk_buff *clone = NULL;
+
+ if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) {
+ kfree_skb(skb);
+- return NETDEV_TX_OK;
++ return false;
+ }
+
+ if (clone)
+ OCELOT_SKB_CB(skb)->clone = clone;
+
+- rew_op = ocelot_ptp_rew_op(skb);
++ *rew_op = ocelot_ptp_rew_op(skb);
+ }
+
++ return true;
++}
++
++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ struct ocelot_port_private *priv = netdev_priv(dev);
++ struct ocelot_port *ocelot_port = &priv->port;
++ struct ocelot *ocelot = ocelot_port->ocelot;
++ int port = priv->port.index;
++ u32 rew_op = 0;
++
++ if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
++ !ocelot_can_inject(ocelot, 0))
++ return NETDEV_TX_BUSY;
++
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ return NETDEV_TX_OK;
++
+ if (static_branch_unlikely(&ocelot_fdma_enabled)) {
+ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
+ } else {
+--
+2.51.0
+
--- /dev/null
+From 5b287416a10c6f89b20d4921df20abd4ad6757a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 8 Feb 2026 22:56:01 +0000
+Subject: net: mscc: ocelot: split xmit into FDMA and register injection paths
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 47f79b20e7fb885aa1623b759a68e8e27401ec4d ]
+
+Split ocelot_port_xmit() into two separate functions:
+- ocelot_port_xmit_fdma(): handles the FDMA injection path
+- ocelot_port_xmit_inj(): handles the register-based injection path
+
+The top-level ocelot_port_xmit() now dispatches to the appropriate
+function based on the ocelot_fdma_enabled static key.
+
+This is a pure refactor with no behavioral change. Separating the two
+code paths makes each one simpler and prepares for adding proper locking
+to the register injection path without affecting the FDMA path.
+
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20260208225602.1339325-3-n7l8m4@u.northwestern.edu
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 026f6513c588 ("net: mscc: ocelot: add missing lock protection in ocelot_port_xmit_inj()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mscc/ocelot_net.c | 39 ++++++++++++++++++++------
+ 1 file changed, 30 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
+index e2b475bf58e6c..84b3dcf1d2f5a 100644
+--- a/drivers/net/ethernet/mscc/ocelot_net.c
++++ b/drivers/net/ethernet/mscc/ocelot_net.c
+@@ -571,7 +571,25 @@ static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port,
+ return true;
+ }
+
+-static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb,
++ struct net_device *dev)
++{
++ struct ocelot_port_private *priv = netdev_priv(dev);
++ struct ocelot_port *ocelot_port = &priv->port;
++ struct ocelot *ocelot = ocelot_port->ocelot;
++ int port = priv->port.index;
++ u32 rew_op = 0;
++
++ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
++ return NETDEV_TX_OK;
++
++ ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
++
++ return NETDEV_TX_OK;
++}
++
++static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb,
++ struct net_device *dev)
+ {
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ struct ocelot_port *ocelot_port = &priv->port;
+@@ -579,24 +597,27 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
+ int port = priv->port.index;
+ u32 rew_op = 0;
+
+- if (!static_branch_unlikely(&ocelot_fdma_enabled) &&
+- !ocelot_can_inject(ocelot, 0))
++ if (!ocelot_can_inject(ocelot, 0))
+ return NETDEV_TX_BUSY;
+
+ if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op))
+ return NETDEV_TX_OK;
+
+- if (static_branch_unlikely(&ocelot_fdma_enabled)) {
+- ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev);
+- } else {
+- ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
++ ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
+- consume_skb(skb);
+- }
++ consume_skb(skb);
+
+ return NETDEV_TX_OK;
+ }
+
++static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ if (static_branch_unlikely(&ocelot_fdma_enabled))
++ return ocelot_port_xmit_fdma(skb, dev);
++
++ return ocelot_port_xmit_inj(skb, dev);
++}
++
+ enum ocelot_action_type {
+ OCELOT_MACT_LEARN,
+ OCELOT_MACT_FORGET,
+--
+2.51.0
+
--- /dev/null
+From 8f36cae60e5f2726fa2c88a82592dd5da2481bdc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:54:09 -0700
+Subject: net/rds: rds_sendmsg should not discard payload_len
+
+From: Allison Henderson <achender@kernel.org>
+
+[ Upstream commit da29e453dcb3aa7cabead7915f5f945d0add3a52 ]
+
+Commit 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with
+connection teardown") modifies rds_sendmsg to avoid enqueueing work
+while a tear down is in progress. However, it also changed the return
+value of rds_sendmsg to that of rds_send_xmit instead of the
+payload_len. This means the user may incorrectly receive errno values
+when it should have simply received a payload of 0 while the peer
+attempts a reconnections. So this patch corrects the teardown handling
+code to only use the out error path in that case, thus restoring the
+original payload_len return value.
+
+Fixes: 3db6e0d172c9 ("rds: use RCU to synchronize work-enqueue with connection teardown")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Allison Henderson <achender@kernel.org>
+Link: https://patch.msgid.link/20260213035409.1963391-1-achender@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rds/send.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/rds/send.c b/net/rds/send.c
+index 09a2801106549..4a24ee9c22d7c 100644
+--- a/net/rds/send.c
++++ b/net/rds/send.c
+@@ -1382,9 +1382,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
+ else
+ queue_delayed_work(rds_wq, &cpath->cp_send_w, 1);
+ rcu_read_unlock();
++
++ if (ret)
++ goto out;
+ }
+- if (ret)
+- goto out;
++
+ rds_message_put(rm);
+
+ for (ind = 0; ind < vct.indx; ind++)
+--
+2.51.0
+
--- /dev/null
+From 0f44f28a225813d1f376868efa4a67255d484a13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 12:56:39 +0100
+Subject: net: remove WARN_ON_ONCE when accessing forward path array
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 008e7a7c293b30bc43e4368dac6ea3808b75a572 ]
+
+Although unlikely, recent support for IPIP tunnels increases chances of
+reaching this WARN_ON_ONCE if userspace manages to build a sufficiently
+long forward path.
+
+Remove it.
+
+Fixes: ddb94eafab8b ("net: resolve forwarding path from virtual netdevice and HW destination address")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 206194bb8fcad..890535fa52be6 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -701,7 +701,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack)
+ {
+ int k = stack->num_paths++;
+
+- if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX))
++ if (k >= NET_DEVICE_PATH_STACK_MAX)
+ return NULL;
+
+ return &stack->path[k];
+--
+2.51.0
+
--- /dev/null
+From 14f2bf9c482b625cdf0a5af3b76cfddd5477914b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 10 Feb 2026 14:44:01 +0100
+Subject: net: sparx5/lan969x: fix DWRR cost max to match hardware register
+ width
+
+From: Daniel Machon <daniel.machon@microchip.com>
+
+[ Upstream commit 6c28aa8dfdf24f554d4c5d4ff7d723a95360d94a ]
+
+DWRR (Deficit Weighted Round Robin) scheduling distributes bandwidth
+across traffic classes based on per-queue cost values, where lower cost
+means higher bandwidth share.
+
+The SPX5_DWRR_COST_MAX constant is 63 (6 bits) but the hardware
+register field HSCH_DWRR_ENTRY_DWRR_COST is GENMASK(24, 20), only
+5 bits wide (max 31). This causes sparx5_weight_to_hw_cost() to
+compute cost values that silently overflow via FIELD_PREP, resulting
+in incorrect scheduling weights.
+
+Set SPX5_DWRR_COST_MAX to 31 to match the hardware register width.
+
+Fixes: 211225428d65 ("net: microchip: sparx5: add support for offloading ets qdisc")
+Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260210-sparx5-fix-dwrr-cost-max-v1-1-58fbdbc25652@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/sparx5/sparx5_qos.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
+index ced35033a6c5d..b1c6c5c6f16ca 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h
+@@ -35,7 +35,7 @@
+ #define SPX5_SE_BURST_UNIT 4096
+
+ /* Dwrr */
+-#define SPX5_DWRR_COST_MAX 63
++#define SPX5_DWRR_COST_MAX 31
+
+ struct sparx5_shaper {
+ u32 mode;
+--
+2.51.0
+
--- /dev/null
+From c122d1a99a2704af85feb7ed661b0d08728b92e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 12:02:30 +0100
+Subject: net: sparx5/lan969x: fix PTP clock max_adj value
+
+From: Daniel Machon <daniel.machon@microchip.com>
+
+[ Upstream commit a49d2a2c37a6252c41cbdd505f9d1c58d5a3817a ]
+
+The max_adj field in ptp_clock_info tells userspace how much the PHC
+clock frequency can be adjusted. ptp4l reads this and will never request
+a correction larger than max_adj.
+
+On both sparx5 and lan969x the clock offset may never converge because
+the servo needs a frequency correction larger than the current max_adj
+of 200000 (200 ppm) allows. The servo rails at the max and the offset
+stays in the tens of microseconds.
+
+The hardware has no inherent max adjustment limit; frequency correction
+is done by writing a 64-bit clock period increment to CLK_PER_CFG, and
+the register has plenty of range. The 200000 value was just an overly
+conservative software limit. The max_adj is shared between sparx5 and
+lan969x, and the increased value is safe for both.
+
+Fix this by increasing max_adj to 10000000 (10000 ppm), giving the
+servo sufficient headroom.
+
+Fixes: 0933bd04047c ("net: sparx5: Add support for ptp clocks")
+Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20260212-sparx5-ptp-max-adj-v2-v1-1-06b200e50ce3@microchip.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+index 5a932460db581..6b2dbfbeef377 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+@@ -562,7 +562,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+ static struct ptp_clock_info sparx5_ptp_clock_info = {
+ .owner = THIS_MODULE,
+ .name = "sparx5 ptp",
+- .max_adj = 200000,
++ .max_adj = 10000000,
+ .gettime64 = sparx5_ptp_gettime64,
+ .settime64 = sparx5_ptp_settime64,
+ .adjtime = sparx5_ptp_adjtime,
+--
+2.51.0
+
--- /dev/null
+From b608072b660771a4b5cc3bc3b724ff1492a352de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 21:41:54 +0000
+Subject: net: usb: catc: enable basic endpoint checking
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 9e7021d2aeae57c323a6f722ed7915686cdcc123 ]
+
+catc_probe() fills three URBs with hardcoded endpoint pipes without
+verifying the endpoint descriptors:
+
+ - usb_sndbulkpipe(usbdev, 1) and usb_rcvbulkpipe(usbdev, 1) for TX/RX
+ - usb_rcvintpipe(usbdev, 2) for interrupt status
+
+A malformed USB device can present these endpoints with transfer types
+that differ from what the driver assumes.
+
+Add a catc_usb_ep enum for endpoint numbers, replacing magic constants
+throughout. Add usb_check_bulk_endpoints() and usb_check_int_endpoints()
+calls after usb_set_interface() to verify endpoint types before use,
+rejecting devices with mismatched descriptors at probe time.
+
+Similar to
+- commit 90b7f2961798 ("net: usb: rtl8150: enable basic endpoint checking")
+which fixed the issue in rtl8150.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Suggested-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Link: https://patch.msgid.link/20260212214154.3609844-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/catc.c | 37 +++++++++++++++++++++++++++++++------
+ 1 file changed, 31 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
+index ff439ef535ac9..98346cb4ece01 100644
+--- a/drivers/net/usb/catc.c
++++ b/drivers/net/usb/catc.c
+@@ -64,6 +64,16 @@ static const char driver_name[] = "catc";
+ #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */
+ #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */
+
++/*
++ * USB endpoints.
++ */
++
++enum catc_usb_ep {
++ CATC_USB_EP_CONTROL = 0,
++ CATC_USB_EP_BULK = 1,
++ CATC_USB_EP_INT_IN = 2,
++};
++
+ /*
+ * Control requests.
+ */
+@@ -772,6 +782,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ u8 broadcast[ETH_ALEN];
+ u8 *macbuf;
+ int pktsz, ret = -ENOMEM;
++ static const u8 bulk_ep_addr[] = {
++ CATC_USB_EP_BULK | USB_DIR_OUT,
++ CATC_USB_EP_BULK | USB_DIR_IN,
++ 0};
++ static const u8 int_ep_addr[] = {
++ CATC_USB_EP_INT_IN | USB_DIR_IN,
++ 0};
+
+ macbuf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if (!macbuf)
+@@ -784,6 +801,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ goto fail_mem;
+ }
+
++ /* Verify that all required endpoints are present */
++ if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
++ !usb_check_int_endpoints(intf, int_ep_addr)) {
++ dev_err(dev, "Missing or invalid endpoints\n");
++ ret = -ENODEV;
++ goto fail_mem;
++ }
++
+ netdev = alloc_etherdev(sizeof(struct catc));
+ if (!netdev)
+ goto fail_mem;
+@@ -828,14 +853,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
+ usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0),
+ NULL, NULL, 0, catc_ctrl_done, catc);
+
+- usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1),
+- NULL, 0, catc_tx_done, catc);
++ usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK),
++ NULL, 0, catc_tx_done, catc);
+
+- usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1),
+- catc->rx_buf, pktsz, catc_rx_done, catc);
++ usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK),
++ catc->rx_buf, pktsz, catc_rx_done, catc);
+
+- usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2),
+- catc->irq_buf, 2, catc_irq_done, catc, 1);
++ usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN),
++ catc->irq_buf, 2, catc_irq_done, catc, 1);
+
+ if (!catc->is_f5u011) {
+ u32 *buf;
+--
+2.51.0
+
--- /dev/null
+From 6c772a947a03e0f3326d3adee40149c08c2a4086 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 12:53:09 +0100
+Subject: netfilter: nf_conntrack_h323: don't pass uninitialised l3num value
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit a6d28eb8efe96b3e35c92efdf1bfacb0cccf541f ]
+
+Mihail Milev reports: Error: UNINIT (CWE-457):
+ net/netfilter/nf_conntrack_h323_main.c:1189:2: var_decl:
+ Declaring variable "tuple" without initializer.
+ net/netfilter/nf_conntrack_h323_main.c:1197:2:
+ uninit_use_in_call: Using uninitialized value "tuple.src.l3num" when calling "__nf_ct_expect_find".
+ net/netfilter/nf_conntrack_expect.c:142:2:
+ read_value: Reading value "tuple->src.l3num" when calling "nf_ct_expect_dst_hash".
+
+ 1195| tuple.dst.protonum = IPPROTO_TCP;
+ 1196|
+ 1197|-> exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ 1198| if (exp && exp->master == ct)
+ 1199| return exp;
+
+Switch this to a C99 initialiser and set the l3num value.
+
+Fixes: f587de0e2feb ("[NETFILTER]: nf_conntrack/nf_nat: add H.323 helper port")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_h323_main.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
+index 5a9bce24f3c3d..ed983421e2eb2 100644
+--- a/net/netfilter/nf_conntrack_h323_main.c
++++ b/net/netfilter/nf_conntrack_h323_main.c
+@@ -1186,13 +1186,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
+ {
+ struct net *net = nf_ct_net(ct);
+ struct nf_conntrack_expect *exp;
+- struct nf_conntrack_tuple tuple;
++ struct nf_conntrack_tuple tuple = {
++ .src.l3num = nf_ct_l3num(ct),
++ .dst.protonum = IPPROTO_TCP,
++ .dst.u.tcp.port = port,
++ };
+
+- memset(&tuple.src.u3, 0, sizeof(tuple.src.u3));
+- tuple.src.u.tcp.port = 0;
+ memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3));
+- tuple.dst.u.tcp.port = port;
+- tuple.dst.protonum = IPPROTO_TCP;
+
+ exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple);
+ if (exp && exp->master == ct)
+--
+2.51.0
+
--- /dev/null
+From abb4ebcf2d4cc0f9f4391bef9fad65cd60b12b20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 17 Feb 2026 21:14:40 +0900
+Subject: netfilter: nf_tables: fix use-after-free in nf_tables_addchain()
+
+From: Inseo An <y0un9sa@gmail.com>
+
+[ Upstream commit 71e99ee20fc3f662555118cf1159443250647533 ]
+
+nf_tables_addchain() publishes the chain to table->chains via
+list_add_tail_rcu() (in nft_chain_add()) before registering hooks.
+If nf_tables_register_hook() then fails, the error path calls
+nft_chain_del() (list_del_rcu()) followed by nf_tables_chain_destroy()
+with no RCU grace period in between.
+
+This creates two use-after-free conditions:
+
+ 1) Control-plane: nf_tables_dump_chains() traverses table->chains
+ under rcu_read_lock(). A concurrent dump can still be walking
+ the chain when the error path frees it.
+
+ 2) Packet path: for NFPROTO_INET, nf_register_net_hook() briefly
+ installs the IPv4 hook before IPv6 registration fails. Packets
+ entering nft_do_chain() via the transient IPv4 hook can still be
+ dereferencing chain->blob_gen_X when the error path frees the
+ chain.
+
+Add synchronize_rcu() between nft_chain_del() and the chain destroy
+so that all RCU readers -- both dump threads and in-flight packet
+evaluation -- have finished before the chain is freed.
+
+Fixes: 91c7b38dc9f0 ("netfilter: nf_tables: use new transaction infrastructure to handle chain")
+Signed-off-by: Inseo An <y0un9sa@gmail.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 8532d832aad6a..41614e897ec8f 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -2581,6 +2581,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
+
+ err_register_hook:
+ nft_chain_del(chain);
++ synchronize_rcu();
+ err_chain_add:
+ nft_trans_destroy(trans);
+ err_trans:
+--
+2.51.0
+
--- /dev/null
+From f36532ad882997aa1d24af45beeccdeaf51dce13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Nov 2023 07:27:54 +0000
+Subject: netns-ipv4: reorganize netns_ipv4 fast path variables
+
+From: Coco Li <lixiaoyan@google.com>
+
+[ Upstream commit 18fd64d2542292713b0322e6815be059bdee440c ]
+
+Reorganize fast path variables on tx-txrx-rx order.
+Fastpath cacheline ends after sysctl_tcp_rmem.
+There are only read-only variables here. (write is on the control path
+and not considered in this case)
+
+Below data generated with pahole on x86 architecture.
+Fast path variables span cache lines before change: 4
+Fast path variables span cache lines after change: 2
+
+Suggested-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Wei Wang <weiwan@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: Coco Li <lixiaoyan@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Shakeel Butt <shakeelb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 87b08913a9ae ("inet: move icmp_global_{credit,stamp} to a separate cache line")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netns/ipv4.h | 47 +++++++++++++++++++++++++++-------------
+ net/core/net_namespace.c | 45 ++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 77 insertions(+), 15 deletions(-)
+
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index fb7842dfd185a..3d7e03847b5be 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -42,6 +42,38 @@ struct inet_timewait_death_row {
+ struct tcp_fastopen_context;
+
+ struct netns_ipv4 {
++ /* Cacheline organization can be found documented in
++ * Documentation/networking/net_cachelines/netns_ipv4_sysctl.rst.
++ * Please update the document when adding new fields.
++ */
++
++ /* TX readonly hotpath cache lines */
++ __cacheline_group_begin(netns_ipv4_read_tx);
++ u8 sysctl_tcp_early_retrans;
++ u8 sysctl_tcp_tso_win_divisor;
++ u8 sysctl_tcp_tso_rtt_log;
++ u8 sysctl_tcp_autocorking;
++ int sysctl_tcp_min_snd_mss;
++ unsigned int sysctl_tcp_notsent_lowat;
++ int sysctl_tcp_limit_output_bytes;
++ int sysctl_tcp_min_rtt_wlen;
++ int sysctl_tcp_wmem[3];
++ u8 sysctl_ip_fwd_use_pmtu;
++ __cacheline_group_end(netns_ipv4_read_tx);
++
++ /* TXRX readonly hotpath cache lines */
++ __cacheline_group_begin(netns_ipv4_read_txrx);
++ u8 sysctl_tcp_moderate_rcvbuf;
++ __cacheline_group_end(netns_ipv4_read_txrx);
++
++ /* RX readonly hotpath cache line */
++ __cacheline_group_begin(netns_ipv4_read_rx);
++ u8 sysctl_ip_early_demux;
++ u8 sysctl_tcp_early_demux;
++ int sysctl_tcp_reordering;
++ int sysctl_tcp_rmem[3];
++ __cacheline_group_end(netns_ipv4_read_rx);
++
+ struct inet_timewait_death_row tcp_death_row;
+ struct udp_table *udp_table;
+
+@@ -99,17 +131,14 @@ struct netns_ipv4 {
+
+ u8 sysctl_ip_default_ttl;
+ u8 sysctl_ip_no_pmtu_disc;
+- u8 sysctl_ip_fwd_use_pmtu;
+ u8 sysctl_ip_fwd_update_priority;
+ u8 sysctl_ip_nonlocal_bind;
+ u8 sysctl_ip_autobind_reuse;
+ /* Shall we try to damage output packets if routing dev changes? */
+ u8 sysctl_ip_dynaddr;
+- u8 sysctl_ip_early_demux;
+ #ifdef CONFIG_NET_L3_MASTER_DEV
+ u8 sysctl_raw_l3mdev_accept;
+ #endif
+- u8 sysctl_tcp_early_demux;
+ u8 sysctl_udp_early_demux;
+
+ u8 sysctl_nexthop_compat_mode;
+@@ -122,7 +151,6 @@ struct netns_ipv4 {
+ u8 sysctl_tcp_mtu_probing;
+ int sysctl_tcp_mtu_probe_floor;
+ int sysctl_tcp_base_mss;
+- int sysctl_tcp_min_snd_mss;
+ int sysctl_tcp_probe_threshold;
+ u32 sysctl_tcp_probe_interval;
+
+@@ -138,17 +166,14 @@ struct netns_ipv4 {
+ u8 sysctl_tcp_backlog_ack_defer;
+ u8 sysctl_tcp_pingpong_thresh;
+
+- int sysctl_tcp_reordering;
+ u8 sysctl_tcp_retries1;
+ u8 sysctl_tcp_retries2;
+ u8 sysctl_tcp_orphan_retries;
+ u8 sysctl_tcp_tw_reuse;
+ int sysctl_tcp_fin_timeout;
+- unsigned int sysctl_tcp_notsent_lowat;
+ u8 sysctl_tcp_sack;
+ u8 sysctl_tcp_window_scaling;
+ u8 sysctl_tcp_timestamps;
+- u8 sysctl_tcp_early_retrans;
+ u8 sysctl_tcp_recovery;
+ u8 sysctl_tcp_thin_linear_timeouts;
+ u8 sysctl_tcp_slow_start_after_idle;
+@@ -164,21 +189,13 @@ struct netns_ipv4 {
+ u8 sysctl_tcp_frto;
+ u8 sysctl_tcp_nometrics_save;
+ u8 sysctl_tcp_no_ssthresh_metrics_save;
+- u8 sysctl_tcp_moderate_rcvbuf;
+- u8 sysctl_tcp_tso_win_divisor;
+ u8 sysctl_tcp_workaround_signed_windows;
+- int sysctl_tcp_limit_output_bytes;
+ int sysctl_tcp_challenge_ack_limit;
+- int sysctl_tcp_min_rtt_wlen;
+ u8 sysctl_tcp_min_tso_segs;
+- u8 sysctl_tcp_tso_rtt_log;
+- u8 sysctl_tcp_autocorking;
+ u8 sysctl_tcp_reflect_tos;
+ int sysctl_tcp_invalid_ratelimit;
+ int sysctl_tcp_pacing_ss_ratio;
+ int sysctl_tcp_pacing_ca_ratio;
+- int sysctl_tcp_wmem[3];
+- int sysctl_tcp_rmem[3];
+ unsigned int sysctl_tcp_child_ehash_entries;
+ unsigned long sysctl_tcp_comp_sack_delay_ns;
+ unsigned long sysctl_tcp_comp_sack_slack_ns;
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
+index 20829e0c36cdb..b99fdca441f31 100644
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -1144,11 +1144,56 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid,
+ rtnl_set_sk_err(net, RTNLGRP_NSID, err);
+ }
+
++#ifdef CONFIG_NET_NS
++static void __init netns_ipv4_struct_check(void)
++{
++ /* TX readonly hotpath cache lines */
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx,
++ sysctl_tcp_early_retrans);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx,
++ sysctl_tcp_tso_win_divisor);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx,
++ sysctl_tcp_tso_rtt_log);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx,
++ sysctl_tcp_autocorking);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx,
++ sysctl_tcp_min_snd_mss);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx,
++ sysctl_tcp_notsent_lowat);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx,
++ sysctl_tcp_limit_output_bytes);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx,
++ sysctl_tcp_min_rtt_wlen);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx,
++ sysctl_tcp_wmem);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_tx,
++ sysctl_ip_fwd_use_pmtu);
++ CACHELINE_ASSERT_GROUP_SIZE(struct netns_ipv4, netns_ipv4_read_tx, 33);
++
++ /* TXRX readonly hotpath cache lines */
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_txrx,
++ sysctl_tcp_moderate_rcvbuf);
++ CACHELINE_ASSERT_GROUP_SIZE(struct netns_ipv4, netns_ipv4_read_txrx, 1);
++
++ /* RX readonly hotpath cache line */
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_rx,
++ sysctl_ip_early_demux);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_rx,
++ sysctl_tcp_early_demux);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_rx,
++ sysctl_tcp_reordering);
++ CACHELINE_ASSERT_GROUP_MEMBER(struct netns_ipv4, netns_ipv4_read_rx,
++ sysctl_tcp_rmem);
++ CACHELINE_ASSERT_GROUP_SIZE(struct netns_ipv4, netns_ipv4_read_rx, 18);
++}
++#endif
++
+ void __init net_ns_init(void)
+ {
+ struct net_generic *ng;
+
+ #ifdef CONFIG_NET_NS
++ netns_ipv4_struct_check();
+ net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
+ SMP_CACHE_BYTES,
+ SLAB_PANIC|SLAB_ACCOUNT, NULL);
+--
+2.51.0
+
--- /dev/null
+From 7134bcf62a73fcdb18c15641ad4a919255a23180 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 14:33:38 +0530
+Subject: octeontx2-af: Fix default entries mcam entry action
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit 45be47bf5d7db0f762a93e9c0ede6cb3c91edf3b ]
+
+As per design, AF should update the default MCAM action only when
+mcam_index is -1. A bug in the previous patch caused default entries
+to be changed even when the request was not for them.
+
+Fixes: 570ba37898ec ("octeontx2-af: Update RSS algorithm index")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260216090338.1318976-1-hkelam@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/marvell/octeontx2/af/rvu_npc.c | 41 ++++++++++---------
+ 1 file changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+index 00ef6d201b973..9b8a6046e6dff 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+@@ -1070,32 +1070,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
+ rvu_write64(rvu, blkaddr,
+ NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action);
+
+- /* update the VF flow rule action with the VF default entry action */
+- if (mcam_index < 0)
+- npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
+- *(u64 *)&action);
+-
+ /* update the action change in default rule */
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+ if (pfvf->def_ucast_rule)
+ pfvf->def_ucast_rule->rx_action = action;
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_PROMISC_ENTRY);
++ if (mcam_index < 0) {
++ /* update the VF flow rule action with the VF default
++ * entry action
++ */
++ npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc,
++ *(u64 *)&action);
+
+- /* If PF's promiscuous entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_PROMISC_ENTRY);
+
+- index = npc_get_nixlf_mcam_index(mcam, pcifunc,
+- nixlf, NIXLF_ALLMULTI_ENTRY);
+- /* If PF's allmulti entry is enabled,
+- * Set RSS action for that entry as well
+- */
+- npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr,
+- alg_idx);
++ /* If PF's promiscuous entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++
++ index = npc_get_nixlf_mcam_index(mcam, pcifunc,
++ nixlf, NIXLF_ALLMULTI_ENTRY);
++ /* If PF's allmulti entry is enabled,
++ * Set RSS action for that entry as well
++ */
++ npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index,
++ blkaddr, alg_idx);
++ }
+ }
+
+ void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc,
+--
+2.51.0
+
--- /dev/null
+From a9b6fccd7c9ea9010fc126e90d7de6107c4aa41f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 10:01:49 +0000
+Subject: ping: annotate data-races in ping_lookup()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit ad5dfde2a5733aaf652ea3e40c8c5e071e935901 ]
+
+isk->inet_num, isk->inet_rcv_saddr and sk->sk_bound_dev_if
+are read locklessly in ping_lookup().
+
+Add READ_ONCE()/WRITE_ONCE() annotations.
+
+The race on isk->inet_rcv_saddr is probably coming from IPv6 support,
+but does not deserve a specific backport.
+
+Fixes: dbca1596bbb0 ("ping: convert to RCU lookups, get rid of rwlock")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260216100149.3319315-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/ping.c | 31 +++++++++++++++++++------------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index 47f2e7dd554ad..fa13cfa2fa00f 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -159,7 +159,7 @@ void ping_unhash(struct sock *sk)
+ pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+ spin_lock(&ping_table.lock);
+ if (sk_del_node_init_rcu(sk)) {
+- isk->inet_num = 0;
++ WRITE_ONCE(isk->inet_num, 0);
+ isk->inet_sport = 0;
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+ }
+@@ -192,31 +192,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ }
+
+ sk_for_each_rcu(sk, hslot) {
++ int bound_dev_if;
++
+ if (!net_eq(sock_net(sk), net))
+ continue;
+ isk = inet_sk(sk);
+
+ pr_debug("iterate\n");
+- if (isk->inet_num != ident)
++ if (READ_ONCE(isk->inet_num) != ident)
+ continue;
+
++ bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
+ if (skb->protocol == htons(ETH_P_IP) &&
+ sk->sk_family == AF_INET) {
++ __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr);
++
+ pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk,
+- (int) isk->inet_num, &isk->inet_rcv_saddr,
+- sk->sk_bound_dev_if);
++ ident, &rcv_saddr,
++ bound_dev_if);
+
+- if (isk->inet_rcv_saddr &&
+- isk->inet_rcv_saddr != ip_hdr(skb)->daddr)
++ if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr)
+ continue;
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (skb->protocol == htons(ETH_P_IPV6) &&
+ sk->sk_family == AF_INET6) {
+
+ pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk,
+- (int) isk->inet_num,
++ ident,
+ &sk->sk_v6_rcv_saddr,
+- sk->sk_bound_dev_if);
++ bound_dev_if);
+
+ if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) &&
+ !ipv6_addr_equal(&sk->sk_v6_rcv_saddr,
+@@ -227,8 +231,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ continue;
+ }
+
+- if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
+- sk->sk_bound_dev_if != sdif)
++ if (bound_dev_if && bound_dev_if != dif &&
++ bound_dev_if != sdif)
+ continue;
+
+ goto exit;
+@@ -403,7 +407,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr *saddr)
+ if (saddr->sa_family == AF_INET) {
+ struct inet_sock *isk = inet_sk(sk);
+ struct sockaddr_in *addr = (struct sockaddr_in *) saddr;
+- isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
++
++ isk->inet_saddr = addr->sin_addr.s_addr;
++ WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr);
+ #if IS_ENABLED(CONFIG_IPV6)
+ } else if (saddr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr;
+@@ -860,7 +866,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
+ struct sk_buff *skb;
+ int copied, err;
+
+- pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
++ pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk,
++ READ_ONCE(isk->inet_num));
+
+ err = -EOPNOTSUPP;
+ if (flags & MSG_OOB)
+--
+2.51.0
+
--- /dev/null
+From c8dc4af0ceee074f372db6536c633432d217505b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Feb 2026 14:34:01 -0800
+Subject: powercap: intel_rapl_tpmi: Remove FW_BUG from invalid version check
+
+From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+
+[ Upstream commit c7d54dafa042cf379859dba265fe5afef6fa8770 ]
+
+On partitioned systems, multiple TPMI instances may exist per package,
+but RAPL registers are only valid on one instance since RAPL has
+package-scope control. Other instances return invalid versions during
+domain parsing, which is expected behavior on such systems.
+
+Currently this generates a firmware bug warning:
+
+ intel_rapl_tpmi: [Firmware Bug]: Invalid version
+
+Remove the FW_BUG tag, downgrade to pr_debug(), and update the message
+to clarify that invalid versions are expected on partitioned systems
+where only one instance can be valid.
+
+Fixes: 9eef7f9da928 ("powercap: intel_rapl: Introduce RAPL TPMI interface driver")
+Reported-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
+Reviewed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Link: https://patch.msgid.link/20260211223401.1575776-1-sathyanarayanan.kuppuswamy@linux.intel.com
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/powercap/intel_rapl_tpmi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/powercap/intel_rapl_tpmi.c b/drivers/powercap/intel_rapl_tpmi.c
+index 1c48dba0ba96a..6958c2f0b7660 100644
+--- a/drivers/powercap/intel_rapl_tpmi.c
++++ b/drivers/powercap/intel_rapl_tpmi.c
+@@ -156,7 +156,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
+ tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff;
+
+ if (tpmi_domain_version == TPMI_VERSION_INVALID) {
+- pr_warn(FW_BUG "Invalid version\n");
++ pr_debug("Invalid version, other instances may be valid\n");
+ return -ENODEV;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 603e00de5edc37885a89d5b99de1eeac030f17ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Feb 2026 07:29:16 +0100
+Subject: s390/kexec: Make KEXEC_SIG available when CONFIG_MODULES=n
+
+From: Alexander Egorenkov <egorenar@linux.ibm.com>
+
+[ Upstream commit dd3411959b57df6e05a3ccbac67b0a836871c0c4 ]
+
+The commit c8424e776b09 ("MODSIGN: Export module signature definitions")
+replaced the dependency of KEXEC_SIG on SYSTEM_DATA_VERIFICATION with the
+dependency on MODULE_SIG_FORMAT. This change disables KEXEC_SIG in s390
+kernels built with MODULES=n if nothing else selects MODULE_SIG_FORMAT.
+
+Furthermore, the signature verification in s390 kexec does not require
+MODULE_SIG_FORMAT because it requires only the struct module_signature and,
+therefore, does not depend on code in kernel/module_signature.c.
+
+But making ARCH_SUPPORTS_KEXEC_SIG depend on SYSTEM_DATA_VERIFICATION is
+also incorrect because it makes KEXEC_SIG available on s390 only if some
+other arbitrary option (for instance a file system or device driver)
+selects it directly or indirectly.
+
+To properly make KEXEC_SIG available for s390 kernels built with MODULES=y
+as well as MODULES=n _and_ also not depend on arbitrary options selecting
+SYSTEM_DATA_VERIFICATION, set ARCH_SUPPORTS_KEXEC_SIG=y for s390 and select
+SYSTEM_DATA_VERIFICATION when KEXEC_SIG=y.
+
+Fixes: c8424e776b09 ("MODSIGN: Export module signature definitions")
+Suggested-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/Kconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index e99dae26500d2..3b2625eb34c5a 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -231,6 +231,7 @@ config S390
+ select SPARSE_IRQ
+ select SWIOTLB
+ select SYSCTL_EXCEPTION_TRACE
++ select SYSTEM_DATA_VERIFICATION if KEXEC_SIG
+ select THREAD_INFO_IN_TASK
+ select TRACE_IRQFLAGS_SUPPORT
+ select TTY
+@@ -254,7 +255,7 @@ config ARCH_SUPPORTS_KEXEC_FILE
+ def_bool y
+
+ config ARCH_SUPPORTS_KEXEC_SIG
+- def_bool MODULE_SIG_FORMAT
++ def_bool y
+
+ config ARCH_SUPPORTS_KEXEC_PURGATORY
+ def_bool y
+--
+2.51.0
+
--- /dev/null
+From 0acdf013c231b607dea8003875686ae602501a59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:05 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d: fix test failure with
+ br_netfilter enabled
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit 02cb2e6bacbb08ebf6acb61be816efd11e1f4a21 ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv4 packet contains a zero IP header checksum. After VXLAN
+decapsulation, such packets do not pass sanity checks in br_netfilter
+and are dropped, which causes the test to fail.
+
+Fix this by calculating and setting a valid IPv4 header checksum for the
+encapsulated packet generated by mausezahn, so that the packet is accepted
+by br_netfilter. Fixed by using the payload_template_calc_checksum() /
+payload_template_expand_checksum() helpers that are only available
+in v6.3 and newer kernels.
+
+Fixes: a0b61f3d8ebf ("selftests: forwarding: vxlan_bridge_1d: Add an ECN decap test")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-2-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/forwarding/vxlan_bridge_1d.sh | 26 ++++++++++++-------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+index eb307ca37bfa6..002551451a728 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh
+@@ -559,6 +559,21 @@ vxlan_encapped_ping_do()
+ local inner_tos=$1; shift
+ local outer_tos=$1; shift
+
++ local ipv4hdr=$(:
++ )"45:"$( : IP version + IHL
++ )"$inner_tos:"$( : IP TOS
++ )"00:54:"$( : IP total length
++ )"99:83:"$( : IP identification
++ )"40:00:"$( : IP flags + frag off
++ )"40:"$( : IP TTL
++ )"01:"$( : IP proto
++ )"CHECKSUM:"$( : IP header csum
++ )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
++ )"c0:00:02:01"$( : IP daddr: 192.0.2.1
++ )
++ local checksum=$(payload_template_calc_checksum "$ipv4hdr")
++ ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum)
++
+ $MZ $dev -c $count -d 100msec -q \
+ -b $next_hop_mac -B $dest_ip \
+ -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(:
+@@ -569,16 +584,7 @@ vxlan_encapped_ping_do()
+ )"$dest_mac:"$( : ETH daddr
+ )"$(mac_get w2):"$( : ETH saddr
+ )"08:00:"$( : ETH type
+- )"45:"$( : IP version + IHL
+- )"$inner_tos:"$( : IP TOS
+- )"00:54:"$( : IP total length
+- )"99:83:"$( : IP identification
+- )"40:00:"$( : IP flags + frag off
+- )"40:"$( : IP TTL
+- )"01:"$( : IP proto
+- )"00:00:"$( : IP header csum
+- )"c0:00:02:03:"$( : IP saddr: 192.0.2.3
+- )"c0:00:02:01:"$( : IP daddr: 192.0.2.1
++ )"$ipv4hdr:"$( : IPv4 header
+ )"08:"$( : ICMP type
+ )"00:"$( : ICMP code
+ )"8b:f2:"$( : ICMP csum
+--
+2.51.0
+
--- /dev/null
+From bbda4bb7775df718f20e2bf07f64e06a50b37c28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 13:19:06 +0000
+Subject: selftests: forwarding: vxlan_bridge_1d_ipv6: fix test failure with
+ br_netfilter enabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+
+[ Upstream commit ce9f6aec0fb780dafc1dfc5f47c688422aff464a ]
+
+The test generates VXLAN traffic using mausezahn, where the encapsulated
+inner IPv6 packet has an incorrect payload length set in the IPv6 header.
+After VXLAN decapsulation, such packets do not pass sanity checks in
+br_netfilter and are dropped, which causes the test to fail.
+
+Fix this by setting the correct IPv6 payload length for the encapsulated
+packet generated by mausezahn, so that the packet is accepted
+by br_netfilter.
+
+tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+lines 698-706
+
+ )"00:03:"$( : Payload length
+ )"3a:"$( : Next header
+ )"04:"$( : Hop limit
+ )"$saddr:"$( : IP saddr
+ )"$daddr:"$( : IP daddr
+ )"80:"$( : ICMPv6.type
+ )"00:"$( : ICMPv6.code
+ )"00:"$( : ICMPv6.checksum
+ )
+
+Data after IPv6 header:
+• 80: — 1 byte (ICMPv6 type)
+• 00: — 1 byte (ICMPv6 code)
+• 00: — 1 byte (ICMPv6 checksum, truncated)
+
+Total: 3 bytes → 00:03 is correct. The old value 00:08 did not match
+the actual payload size.
+
+Fixes: b07e9957f220 ("selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for IPv6")
+Signed-off-by: Aleksei Oladko <aleksey.oladko@virtuozzo.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260213131907.43351-3-aleksey.oladko@virtuozzo.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+index bd3f7d492af2b..28284a5aa07a9 100755
+--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
+@@ -695,7 +695,7 @@ vxlan_encapped_ping_do()
+ )"6"$( : IP version
+ )"$inner_tos"$( : Traffic class
+ )"0:00:00:"$( : Flow label
+- )"00:08:"$( : Payload length
++ )"00:03:"$( : Payload length
+ )"3a:"$( : Next header
+ )"04:"$( : Hop limit
+ )"$saddr:"$( : IP saddr
+--
+2.51.0
+
--- /dev/null
+From dd6119c39c549edc4e63147b745a151ab94309b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jan 2024 01:50:57 -0800
+Subject: selftests/memfd: delete unused declarations
+
+From: Greg Thelen <gthelen@google.com>
+
+[ Upstream commit a9117b4d7f178ea36e8d256f8ab3752839e245b2 ]
+
+Commit 32d118ad50a5 ("selftests/memfd: add tests for F_SEAL_EXEC"):
+- added several unused 'nbytes' local variables
+
+Commit 6469b66e3f5a ("selftests: improve vm.memfd_noexec sysctl tests"):
+- orphaned 'newpid_thread_fn2()' forward declaration
+- orphaned 'join_newpid_thread()' forward declaration
+- added unused 'pid' local in sysctl_simple_child()
+- orphaned 'fd' local in sysctl_simple_child()
+- added unused 'fd' in sysctl_nested_child()
+
+Delete the unused locals and forward declarations.
+
+Link: https://lkml.kernel.org/r/20240118095057.677544-1-gthelen@google.com
+Signed-off-by: Greg Thelen <gthelen@google.com>
+Cc: Aleksa Sarai <cyphar@cyphar.com>
+Cc: Daniel Verkamp <dverkamp@chromium.org>
+Cc: Jeff Xu <jeffxu@google.com>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: b24335521de9 ("selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/memfd/memfd_test.c | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c
+index 9c9c82fd18a7e..da88dbe37dda9 100644
+--- a/tools/testing/selftests/memfd/memfd_test.c
++++ b/tools/testing/selftests/memfd/memfd_test.c
+@@ -45,8 +45,6 @@
+ */
+ static size_t mfd_def_size = MFD_DEF_SIZE;
+ static const char *memfd_str = MEMFD_STR;
+-static int newpid_thread_fn2(void *arg);
+-static void join_newpid_thread(pid_t pid);
+
+ static ssize_t fd2name(int fd, char *buf, size_t bufsize)
+ {
+@@ -195,7 +193,6 @@ static unsigned int mfd_assert_get_seals(int fd)
+ static void mfd_assert_has_seals(int fd, unsigned int seals)
+ {
+ char buf[PATH_MAX];
+- int nbytes;
+ unsigned int s;
+ fd2name(fd, buf, PATH_MAX);
+
+@@ -715,7 +712,6 @@ static void mfd_assert_mode(int fd, int mode)
+ {
+ struct stat st;
+ char buf[PATH_MAX];
+- int nbytes;
+
+ fd2name(fd, buf, PATH_MAX);
+
+@@ -734,7 +730,6 @@ static void mfd_assert_mode(int fd, int mode)
+ static void mfd_assert_chmod(int fd, int mode)
+ {
+ char buf[PATH_MAX];
+- int nbytes;
+
+ fd2name(fd, buf, PATH_MAX);
+
+@@ -750,7 +745,6 @@ static void mfd_fail_chmod(int fd, int mode)
+ {
+ struct stat st;
+ char buf[PATH_MAX];
+- int nbytes;
+
+ fd2name(fd, buf, PATH_MAX);
+
+@@ -1297,9 +1291,6 @@ static void test_sysctl_set_sysctl2(void)
+
+ static int sysctl_simple_child(void *arg)
+ {
+- int fd;
+- int pid;
+-
+ printf("%s sysctl 0\n", memfd_str);
+ test_sysctl_set_sysctl0();
+
+@@ -1364,7 +1355,6 @@ static void test_sysctl_sysctl2_failset(void)
+
+ static int sysctl_nested_child(void *arg)
+ {
+- int fd;
+ int pid;
+
+ printf("%s nested sysctl 0\n", memfd_str);
+--
+2.51.0
+
--- /dev/null
+From a8cf7fdd71fa4049c416339cae2f312f6059d4e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Feb 2026 09:38:05 -0500
+Subject: selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT
+
+From: Aristeu Rozanski <aris@redhat.com>
+
+[ Upstream commit b24335521de92fd2ee22460072b75367ca8860b0 ]
+
+selftests/memfd: use IPC semaphore instead of SIGSTOP/SIGCONT
+
+In order to synchronize new processes to test inheritance of memfd_noexec
+sysctl, memfd_test sets up the sysctl with a value before creating the new
+process. The new process then sends itself a SIGSTOP in order to wait for
+the parent to flip the sysctl value and send a SIGCONT signal.
+
+This would work as intended if it wasn't the fact that the new process is
+being created with CLONE_NEWPID, which creates a new PID namespace and the
+new process has PID 1 in this namespace. There're restrictions on sending
+signals to PID 1 and, although it's relaxed for other than root PID
+namespace, it's biting us here. In this specific case the SIGSTOP sent by
+the new process is ignored (no error to kill() is returned) and it never
+stops its execution. This is usually not noticiable as the parent usually
+manages to set the new sysctl value before the child has a chance to run
+and the test succeeds. But if you run the test in a loop, it eventually
+reproduces:
+
+ while [ 1 ]; do ./memfd_test >log 2>&1 || break; done; cat log
+
+So this patch replaces the SIGSTOP/SIGCONT synchronization with IPC
+semaphore.
+
+Link: https://lkml.kernel.org/r/a7776389-b3d6-4b18-b438-0b0e3ed1fd3b@work
+Fixes: 6469b66e3f5a ("selftests: improve vm.memfd_noexec sysctl tests")
+Signed-off-by: Aristeu Rozanski <aris@redhat.com>
+Cc: Aleksa Sarai <cyphar@cyphar.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: liuye <liuye@kylinos.cn>
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/memfd/memfd_test.c | 113 +++++++++++++++++++--
+ 1 file changed, 105 insertions(+), 8 deletions(-)
+
+diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c
+index da88dbe37dda9..f2042de4bab8e 100644
+--- a/tools/testing/selftests/memfd/memfd_test.c
++++ b/tools/testing/selftests/memfd/memfd_test.c
+@@ -18,6 +18,9 @@
+ #include <sys/stat.h>
+ #include <sys/syscall.h>
+ #include <sys/wait.h>
++#include <sys/types.h>
++#include <sys/ipc.h>
++#include <sys/sem.h>
+ #include <unistd.h>
+ #include <ctype.h>
+
+@@ -39,6 +42,20 @@
+ F_SEAL_EXEC)
+
+ #define MFD_NOEXEC_SEAL 0x0008U
++union semun {
++ int val;
++ struct semid_ds *buf;
++ unsigned short int *array;
++ struct seminfo *__buf;
++};
++
++/*
++ * we use semaphores on nested wait tasks due the use of CLONE_NEWPID: the
++ * child will be PID 1 and can't send SIGSTOP to themselves due special
++ * treatment of the init task, so the SIGSTOP/SIGCONT synchronization
++ * approach can't be used here.
++ */
++#define SEM_KEY 0xdeadbeef
+
+ /*
+ * Default is not to test hugetlbfs
+@@ -1333,8 +1350,22 @@ static int sysctl_nested(void *arg)
+
+ static int sysctl_nested_wait(void *arg)
+ {
+- /* Wait for a SIGCONT. */
+- kill(getpid(), SIGSTOP);
++ int sem = semget(SEM_KEY, 1, 0600);
++ struct sembuf sembuf;
++
++ if (sem < 0) {
++ perror("semget:");
++ abort();
++ }
++ sembuf.sem_num = 0;
++ sembuf.sem_flg = 0;
++ sembuf.sem_op = 0;
++
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ abort();
++ }
++
+ return sysctl_nested(arg);
+ }
+
+@@ -1355,7 +1386,9 @@ static void test_sysctl_sysctl2_failset(void)
+
+ static int sysctl_nested_child(void *arg)
+ {
+- int pid;
++ int pid, sem;
++ union semun semun;
++ struct sembuf sembuf;
+
+ printf("%s nested sysctl 0\n", memfd_str);
+ sysctl_assert_write("0");
+@@ -1389,23 +1422,53 @@ static int sysctl_nested_child(void *arg)
+ test_sysctl_sysctl2_failset);
+ join_thread(pid);
+
++ sem = semget(SEM_KEY, 1, IPC_CREAT | 0600);
++ if (sem < 0) {
++ perror("semget:");
++ return 1;
++ }
++ semun.val = 1;
++ sembuf.sem_op = -1;
++ sembuf.sem_flg = 0;
++ sembuf.sem_num = 0;
++
+ /* Verify that the rules are actually inherited after fork. */
+ printf("%s nested sysctl 0 -> 1 after fork\n", memfd_str);
+ sysctl_assert_write("0");
+
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl1_failset);
+ sysctl_assert_write("1");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 0 -> 2 after fork\n", memfd_str);
+ sysctl_assert_write("0");
+
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2_failset);
+ sysctl_assert_write("2");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ /*
+@@ -1415,28 +1478,62 @@ static int sysctl_nested_child(void *arg)
+ */
+ printf("%s nested sysctl 2 -> 1 after fork\n", memfd_str);
+ sysctl_assert_write("2");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2);
+ sysctl_assert_write("1");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 2 -> 0 after fork\n", memfd_str);
+ sysctl_assert_write("2");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl2);
+ sysctl_assert_write("0");
+- kill(pid, SIGCONT);
++
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
+ printf("%s nested sysctl 1 -> 0 after fork\n", memfd_str);
+ sysctl_assert_write("1");
++
++ if (semctl(sem, 0, SETVAL, semun) < 0) {
++ perror("semctl:");
++ return 1;
++ }
++
+ pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait,
+ test_sysctl_sysctl1);
+ sysctl_assert_write("0");
+- kill(pid, SIGCONT);
++ /* Allow child to continue */
++ if (semop(sem, &sembuf, 1) < 0) {
++ perror("semop:");
++ return 1;
++ }
+ join_thread(pid);
+
++ semctl(sem, 0, IPC_RMID);
++
+ return 0;
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 15b2d8e785967b15bc7af018a6f5dbf72ca40412 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Feb 2026 14:53:53 +0100
+Subject: selftests: mlxsw: tc_restrictions: Fix test failure with new iproute2
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit a2646773a005b59fd1dc7ff3ba15df84889ca5d2 ]
+
+As explained in [1], iproute2 started rejecting tc-police burst sizes
+that result in an overflow. This can happen when the burst size is high
+enough and the rate is low enough.
+
+A couple of test cases specify such configurations, resulting in
+iproute2 errors and test failure.
+
+Fix by reducing the burst size so that the test will pass with both new
+and old iproute2 versions.
+
+[1] https://lore.kernel.org/netdev/20250916215731.3431465-1-jay.vosburgh@canonical.com/
+
+Fixes: cb12d1763267 ("selftests: mlxsw: tc_restrictions: Test tc-police restrictions")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/88b00c6e85188aa6a065dc240206119b328c46e1.1770643998.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+index 0441a18f098b1..aac8ef490feb8 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh
+@@ -317,7 +317,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 0.5kbit burst 1m conform-exceed drop/ok
++ action police rate 0.5kbit burst 2k conform-exceed drop/ok
+ check_fail $? "Incorrect success to add police action with too low rate"
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+@@ -327,7 +327,7 @@ police_limits_test()
+
+ tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \
+ flower skip_sw \
+- action police rate 1.5kbit burst 1m conform-exceed drop/ok
++ action police rate 1.5kbit burst 2k conform-exceed drop/ok
+ check_err $? "Failed to add police action with low rate"
+
+ tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower
+--
+2.51.0
+
--- /dev/null
+From cff71c2fa13849512f84b7f7f9a04167eff28026 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 13 Feb 2026 19:51:59 -0800
+Subject: selftests: tc_actions: don't dump 2MB of \0 to stdout
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 32b70e62034aa72f8414ad4e9122cce7ad418c48 ]
+
+Since we started running selftests in NIPA we have been seeing
+tc_actions.sh generate a soft lockup warning on ~20% of the runs.
+On the pre-netdev foundation setup it was actually a missed irq
+splat from the console. Now it's either that or a lockup.
+
+I initially suspected a socket locking issue since the test
+is exercising local loopback with act_mirred.
+After hours of staring at this I noticed in strace that ncat
+when -o $file is specified _both_ saves the output to the file
+and still prints it to stdout. Because the file being sent
+is constructed with:
+
+ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred
+ ^^^^^^^^^
+
+the data printed is all \0. Most terminals don't display nul
+characters (and neither does vng output capture save them).
+But QEMU's serial console still has to poke them thru which
+is very slow and causes the lockup (if the file is >600kB).
+
+Replace the '-o $file' with '> $file'. This speeds the test up
+from 2m20s to 18s on debug kernels, and prevents the warnings.
+
+Fixes: ca22da2fbd69 ("act_mirred: use the backlog for nested calls to mirred ingress")
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260214035159.2119699-1-kuba@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/forwarding/tc_actions.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh
+index 5896296365022..b2f9aae401e09 100755
+--- a/tools/testing/selftests/net/forwarding/tc_actions.sh
++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh
+@@ -222,7 +222,7 @@ mirred_egress_to_ingress_tcp_test()
+ ip_proto icmp \
+ action drop
+
+- ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 &
++ ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 &
+ local rpid=$!
+ ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1
+ wait -n $rpid
+--
+2.51.0
+
dmaengine-fsl-edma-main-convert-to-platform-remove-c.patch
dmaengine-fsl-edma-don-t-explicitly-disable-clocks-i.patch
io_uring-cancel-de-unionize-file-and-user_data-in-st.patch
+fs-ntfs3-prevent-infinite-loops-caused-by-the-next-v.patch
+fs-ntfs3-fix-slab-out-of-bounds-read-in-deleteindexe.patch
+acpi-cppc-fix-remaining-for_each_possible_cpu-to-use.patch
+powercap-intel_rapl_tpmi-remove-fw_bug-from-invalid-.patch
+kbuild-add-objtool-to-top-level-clean-target.patch
+selftests-memfd-delete-unused-declarations.patch
+selftests-memfd-use-ipc-semaphore-instead-of-sigstop.patch
+acpi-pm-add-unused-power-resource-quirk-for-thundero.patch
+cpuidle-skip-governor-when-only-one-idle-state-is-av.patch
+selftests-mlxsw-tc_restrictions-fix-test-failure-wit.patch
+net-sparx5-lan969x-fix-dwrr-cost-max-to-match-hardwa.patch
+net-mscc-ocelot-extract-ocelot_xmit_timestamp-helper.patch
+net-mscc-ocelot-split-xmit-into-fdma-and-register-in.patch
+net-mscc-ocelot-add-missing-lock-protection-in-ocelo.patch
+ipv6-fix-out-of-bound-access-in-fib6_add_rt2node.patch
+net-sparx5-lan969x-fix-ptp-clock-max_adj-value.patch
+net-usb-catc-enable-basic-endpoint-checking.patch
+xen-netback-reject-zero-queue-configuration-from-gue.patch
+net-rds-rds_sendmsg-should-not-discard-payload_len.patch
+net-bridge-mcast-always-update-mdb_n_entries-for-vla.patch
+selftests-forwarding-vxlan_bridge_1d-fix-test-failur.patch
+selftests-forwarding-vxlan_bridge_1d_ipv6-fix-test-f.patch
+netfilter-nf_conntrack_h323-don-t-pass-uninitialised.patch
+net-remove-warn_on_once-when-accessing-forward-path-.patch
+netfilter-nf_tables-fix-use-after-free-in-nf_tables_.patch
+ipv6-fix-a-race-in-ip6_sock_set_v6only.patch
+bpftool-fix-truncated-netlink-dumps.patch
+ping-annotate-data-races-in-ping_lookup.patch
+selftests-tc_actions-don-t-dump-2mb-of-0-to-stdout.patch
+macvlan-observe-an-rcu-grace-period-in-macvlan_commo.patch
+icmp-move-icmp_global.credit-and-icmp_global.stamp-t.patch
+icmp-icmp_msgs_per_sec-and-icmp_msgs_burst-sysctls-b.patch
+icmp-prevent-possible-overflow-in-icmp_global_allow.patch
+tcp-defer-regular-ack-while-processing-socket-backlo.patch
+tcp-set-pingpong-threshold-via-sysctl.patch
+cache-enforce-cache-groups.patch
+netns-ipv4-reorganize-netns_ipv4-fast-path-variables.patch
+cache-add-__cacheline_group_-begin-end-_aligned-coup.patch
+inet-move-icmp_global_-credit-stamp-to-a-separate-ca.patch
+octeontx2-af-fix-default-entries-mcam-entry-action.patch
+bonding-alb-fix-uaf-in-rlb_arp_recv-during-bond-up-d.patch
+net-mlx5-fix-multiport-device-check-over-light-sfs.patch
+apparmor-fix-null-sock-in-aa_sock_file_perm.patch
+apparmor-return-enomem-in-unpack_perms_table-upon-al.patch
+apparmor-fix-rlimit-for-posix-cpu-timers.patch
+apparmor-use-passed-in-gfp-flags-in-aa_alloc_null.patch
+apparmor-provide-separate-audit-messages-for-file-an.patch
+apparmor-refcount-the-pdb.patch
+apparmor-remove-apply_modes_to_perms-from-label_matc.patch
+apparmor-make-label_match-return-a-consistent-value.patch
+apparmor-fix-invalid-deref-of-rawdata-when-export_bi.patch
+apparmor-fix-aa_label-to-return-state-from-compount-.patch
+drm-amdgpu-fix-memory-leak-in-amdgpu_acpi_enumerate_.patch
+drm-amdgpu-fix-memory-leak-in-amdgpu_ras_init.patch
+asoc-fsl_xcvr-revert-fix-missing-lock-in-fsl_xcvr_mo.patch
+drm-i915-acpi-free-_dsm-package-when-no-connectors.patch
+asoc-codecs-aw88261-fix-erroneous-bitmask-logic-in-a.patch
+drm-amdkfd-fix-debug-watchpoints-for-logical-devices.patch
+drm-amdkfd-fix-watch_id-bounds-checking-in-debug-add.patch
+spi-wpcm-fiu-use-devm_platform_ioremap_resource_byna.patch
+spi-wpcm-fiu-fix-uninitialized-res.patch
+spi-wpcm-fiu-simplify-with-dev_err_probe.patch
+spi-wpcm-fiu-fix-potential-null-pointer-dereference-.patch
+s390-kexec-make-kexec_sig-available-when-config_modu.patch
+efi-fix-reservation-of-unaccepted-memory-table.patch
+btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch
+x86-hyperv-fix-error-pointer-dereference.patch
+asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch
+drm-amd-display-use-same-max-plane-scaling-limits-fo.patch
--- /dev/null
+From b79b4c97cde12d07c706dfbd75f3f9b73505b83d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 20:41:40 +0800
+Subject: spi: wpcm-fiu: Fix potential NULL pointer dereference in
+ wpcm_fiu_probe()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Felix Gu <ustc.gu@gmail.com>
+
+[ Upstream commit 888a0a802c467bbe34a42167bdf9d7331333440a ]
+
+platform_get_resource_byname() can return NULL, which would cause a crash
+when passed the pointer to resource_size().
+
+Move the fiu->memory_size assignment after the error check for
+devm_ioremap_resource() to prevent the potential NULL pointer dereference.
+
+Fixes: 9838c182471e ("spi: wpcm-fiu: Add direct map support")
+Signed-off-by: Felix Gu <ustc.gu@gmail.com>
+Reviewed-by: J. Neuschäfer <j.ne@posteo.net>
+Link: https://patch.msgid.link/20260212-wpcm-v1-1-5b7c4f526aac@gmail.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-wpcm-fiu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c
+index a67432a4bea21..c006889b37ebb 100644
+--- a/drivers/spi/spi-wpcm-fiu.c
++++ b/drivers/spi/spi-wpcm-fiu.c
+@@ -459,11 +459,11 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
+ fiu->memory = devm_ioremap_resource(dev, res);
+- fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+ if (IS_ERR(fiu->memory))
+ return dev_err_probe(dev, PTR_ERR(fiu->memory),
+ "Failed to map flash memory window\n");
+
++ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+ fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm");
+
+ wpcm_fiu_hw_init(fiu);
+--
+2.51.0
+
--- /dev/null
+From 2b86a28b1fb3f5852f01ea056d0495ed3084d6f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Aug 2024 21:25:43 +0800
+Subject: spi: wpcm-fiu: Fix uninitialized res
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 0f2cf3bc4727fd07e3a1c8acb9f83e462b455986 ]
+
+The second platform_get_resource_byname() can not be replaced with
+devm_platform_ioremap_resource_byname(), because the intermediate "res"
+is used by resource_size() later.
+
+Fixes: 3bf2a5359b0b ("spi: wpcm-fiu: Use devm_platform_ioremap_resource_byname()")
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://patch.msgid.link/20240826132544.3463616-2-ruanjinjie@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 888a0a802c46 ("spi: wpcm-fiu: Fix potential NULL pointer dereference in wpcm_fiu_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-wpcm-fiu.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c
+index 5d16340524007..d07a06f492044 100644
+--- a/drivers/spi/spi-wpcm-fiu.c
++++ b/drivers/spi/spi-wpcm-fiu.c
+@@ -458,7 +458,8 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
+ if (IS_ERR(fiu->clk))
+ return PTR_ERR(fiu->clk);
+
+- fiu->memory = devm_platform_ioremap_resource_byname(pdev, "memory");
++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
++ fiu->memory = devm_ioremap_resource(dev, res);
+ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+ if (IS_ERR(fiu->memory)) {
+ dev_err(dev, "Failed to map flash memory window\n");
+--
+2.51.0
+
--- /dev/null
+From d6ace5a2111b0981cf76af646863e14cf1c8585e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 26 Aug 2024 21:25:44 +0800
+Subject: spi: wpcm-fiu: Simplify with dev_err_probe()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 196d34e2c8cfec7b94e44e75d0b1bc9176acf6f8 ]
+
+Use the dev_err_probe() helper to simplify error handling during probe.
+This also handle scenario, when EDEFER is returned and useless error
+is printed.
+
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://patch.msgid.link/20240826132544.3463616-3-ruanjinjie@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 888a0a802c46 ("spi: wpcm-fiu: Fix potential NULL pointer dereference in wpcm_fiu_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-wpcm-fiu.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c
+index d07a06f492044..a67432a4bea21 100644
+--- a/drivers/spi/spi-wpcm-fiu.c
++++ b/drivers/spi/spi-wpcm-fiu.c
+@@ -449,10 +449,9 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
+ fiu->dev = dev;
+
+ fiu->regs = devm_platform_ioremap_resource_byname(pdev, "control");
+- if (IS_ERR(fiu->regs)) {
+- dev_err(dev, "Failed to map registers\n");
+- return PTR_ERR(fiu->regs);
+- }
++ if (IS_ERR(fiu->regs))
++ return dev_err_probe(dev, PTR_ERR(fiu->regs),
++ "Failed to map registers\n");
+
+ fiu->clk = devm_clk_get_enabled(dev, NULL);
+ if (IS_ERR(fiu->clk))
+@@ -461,10 +460,9 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
+ fiu->memory = devm_ioremap_resource(dev, res);
+ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+- if (IS_ERR(fiu->memory)) {
+- dev_err(dev, "Failed to map flash memory window\n");
+- return PTR_ERR(fiu->memory);
+- }
++ if (IS_ERR(fiu->memory))
++ return dev_err_probe(dev, PTR_ERR(fiu->memory),
++ "Failed to map flash memory window\n");
+
+ fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm");
+
+--
+2.51.0
+
--- /dev/null
+From b088bc8bb0d2053f387352ac91d1a84d15cf79cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Aug 2024 20:35:18 +0800
+Subject: spi: wpcm-fiu: Use devm_platform_ioremap_resource_byname()
+
+From: Jinjie Ruan <ruanjinjie@huawei.com>
+
+[ Upstream commit 3bf2a5359b0bde22418705ec862ac5077312e4c2 ]
+
+Use the devm_platform_ioremap_resource_byname() helper instead of
+calling platform_get_resource_byname() and devm_ioremap_resource()
+separately.
+
+Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
+Link: https://patch.msgid.link/20240820123518.1788294-1-ruanjinjie@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 888a0a802c46 ("spi: wpcm-fiu: Fix potential NULL pointer dereference in wpcm_fiu_probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-wpcm-fiu.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c
+index 852ffe013d326..5d16340524007 100644
+--- a/drivers/spi/spi-wpcm-fiu.c
++++ b/drivers/spi/spi-wpcm-fiu.c
+@@ -448,8 +448,7 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
+ fiu = spi_controller_get_devdata(ctrl);
+ fiu->dev = dev;
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control");
+- fiu->regs = devm_ioremap_resource(dev, res);
++ fiu->regs = devm_platform_ioremap_resource_byname(pdev, "control");
+ if (IS_ERR(fiu->regs)) {
+ dev_err(dev, "Failed to map registers\n");
+ return PTR_ERR(fiu->regs);
+@@ -459,8 +458,7 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
+ if (IS_ERR(fiu->clk))
+ return PTR_ERR(fiu->clk);
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
+- fiu->memory = devm_ioremap_resource(dev, res);
++ fiu->memory = devm_platform_ioremap_resource_byname(pdev, "memory");
+ fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+ if (IS_ERR(fiu->memory)) {
+ dev_err(dev, "Failed to map flash memory window\n");
+--
+2.51.0
+
--- /dev/null
+From a17c938b428aae174884775fb234ded4c40748bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Sep 2023 17:05:31 +0000
+Subject: tcp: defer regular ACK while processing socket backlog
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 133c4c0d37175f510a10fa9bed51e223936073fc ]
+
+This idea came after a particular workload requested
+the quickack attribute set on routes, and a performance
+drop was noticed for large bulk transfers.
+
+For high throughput flows, it is best to use one cpu
+running the user thread issuing socket system calls,
+and a separate cpu to process incoming packets from BH context.
+(With TSO/GRO, bottleneck is usually the 'user' cpu)
+
+Problem is the user thread can spend a lot of time while holding
+the socket lock, forcing BH handler to queue most of incoming
+packets in the socket backlog.
+
+Whenever the user thread releases the socket lock, it must first
+process all accumulated packets in the backlog, potentially
+adding latency spikes. Due to flood mitigation, having too many
+packets in the backlog increases chance of unexpected drops.
+
+Backlog processing unfortunately shifts a fair amount of cpu cycles
+from the BH cpu to the 'user' cpu, thus reducing max throughput.
+
+This patch takes advantage of the backlog processing,
+and the fact that ACK are mostly cumulative.
+
+The idea is to detect we are in the backlog processing
+and defer all eligible ACK into a single one,
+sent from tcp_release_cb().
+
+This saves cpu cycles on both sides, and network resources.
+
+Performance of a single TCP flow on a 200Gbit NIC:
+
+- Throughput is increased by 20% (100Gbit -> 120Gbit).
+- Number of generated ACK per second shrinks from 240,000 to 40,000.
+- Number of backlog drops per second shrinks from 230 to 0.
+
+Benchmark context:
+ - Regular netperf TCP_STREAM (no zerocopy)
+ - Intel(R) Xeon(R) Platinum 8481C (Saphire Rapids)
+ - MAX_SKB_FRAGS = 17 (~60KB per GRO packet)
+
+This feature is guarded by a new sysctl, and enabled by default:
+ /proc/sys/net/ipv4/tcp_backlog_ack_defer
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Acked-by: Yuchung Cheng <ycheng@google.com>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
+Acked-by: Dave Taht <dave.taht@gmail.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Stable-dep-of: 87b08913a9ae ("inet: move icmp_global_{credit,stamp} to a separate cache line")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/networking/ip-sysctl.rst | 7 +++++++
+ include/linux/tcp.h | 14 ++++++++------
+ include/net/netns/ipv4.h | 1 +
+ net/ipv4/sysctl_net_ipv4.c | 9 +++++++++
+ net/ipv4/tcp_input.c | 8 ++++++++
+ net/ipv4/tcp_ipv4.c | 1 +
+ net/ipv4/tcp_output.c | 5 ++++-
+ 7 files changed, 38 insertions(+), 7 deletions(-)
+
+diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
+index a66054d0763a6..5bfa1837968ce 100644
+--- a/Documentation/networking/ip-sysctl.rst
++++ b/Documentation/networking/ip-sysctl.rst
+@@ -745,6 +745,13 @@ tcp_comp_sack_nr - INTEGER
+
+ Default : 44
+
++tcp_backlog_ack_defer - BOOLEAN
++ If set, user thread processing socket backlog tries sending
++ one ACK for the whole queue. This helps to avoid potential
++ long latencies at end of a TCP socket syscall.
++
++ Default : true
++
+ tcp_slow_start_after_idle - BOOLEAN
+ If set, provide RFC2861 behavior and time out the congestion
+ window after an idle period. An idle period is defined at
+diff --git a/include/linux/tcp.h b/include/linux/tcp.h
+index 9b371aa7c7962..e15452df9804f 100644
+--- a/include/linux/tcp.h
++++ b/include/linux/tcp.h
+@@ -471,15 +471,17 @@ enum tsq_enum {
+ TCP_MTU_REDUCED_DEFERRED, /* tcp_v{4|6}_err() could not call
+ * tcp_v{4|6}_mtu_reduced()
+ */
++ TCP_ACK_DEFERRED, /* TX pure ack is deferred */
+ };
+
+ enum tsq_flags {
+- TSQF_THROTTLED = (1UL << TSQ_THROTTLED),
+- TSQF_QUEUED = (1UL << TSQ_QUEUED),
+- TCPF_TSQ_DEFERRED = (1UL << TCP_TSQ_DEFERRED),
+- TCPF_WRITE_TIMER_DEFERRED = (1UL << TCP_WRITE_TIMER_DEFERRED),
+- TCPF_DELACK_TIMER_DEFERRED = (1UL << TCP_DELACK_TIMER_DEFERRED),
+- TCPF_MTU_REDUCED_DEFERRED = (1UL << TCP_MTU_REDUCED_DEFERRED),
++ TSQF_THROTTLED = BIT(TSQ_THROTTLED),
++ TSQF_QUEUED = BIT(TSQ_QUEUED),
++ TCPF_TSQ_DEFERRED = BIT(TCP_TSQ_DEFERRED),
++ TCPF_WRITE_TIMER_DEFERRED = BIT(TCP_WRITE_TIMER_DEFERRED),
++ TCPF_DELACK_TIMER_DEFERRED = BIT(TCP_DELACK_TIMER_DEFERRED),
++ TCPF_MTU_REDUCED_DEFERRED = BIT(TCP_MTU_REDUCED_DEFERRED),
++ TCPF_ACK_DEFERRED = BIT(TCP_ACK_DEFERRED),
+ };
+
+ #define tcp_sk(ptr) container_of_const(ptr, struct tcp_sock, inet_conn.icsk_inet.sk)
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 40a3a7e2e6070..3193e362b8a55 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -135,6 +135,7 @@ struct netns_ipv4 {
+ u8 sysctl_tcp_syncookies;
+ u8 sysctl_tcp_migrate_req;
+ u8 sysctl_tcp_comp_sack_nr;
++ u8 sysctl_tcp_backlog_ack_defer;
+ int sysctl_tcp_reordering;
+ u8 sysctl_tcp_retries1;
+ u8 sysctl_tcp_retries2;
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 7a1164ea3d3af..18bcbcfee824a 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -1366,6 +1366,15 @@ static struct ctl_table ipv4_net_table[] = {
+ .proc_handler = proc_dou8vec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ },
++ {
++ .procname = "tcp_backlog_ack_defer",
++ .data = &init_net.ipv4.sysctl_tcp_backlog_ack_defer,
++ .maxlen = sizeof(u8),
++ .mode = 0644,
++ .proc_handler = proc_dou8vec_minmax,
++ .extra1 = SYSCTL_ZERO,
++ .extra2 = SYSCTL_ONE,
++ },
+ {
+ .procname = "tcp_reflect_tos",
+ .data = &init_net.ipv4.sysctl_tcp_reflect_tos,
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 8834cd41b3840..f67967c757714 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -5678,6 +5678,14 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
+ tcp_in_quickack_mode(sk) ||
+ /* Protocol state mandates a one-time immediate ACK */
+ inet_csk(sk)->icsk_ack.pending & ICSK_ACK_NOW) {
++ /* If we are running from __release_sock() in user context,
++ * Defer the ack until tcp_release_cb().
++ */
++ if (sock_owned_by_user_nocheck(sk) &&
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_backlog_ack_defer)) {
++ set_bit(TCP_ACK_DEFERRED, &sk->sk_tsq_flags);
++ return;
++ }
+ send_now:
+ tcp_send_ack(sk);
+ return;
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 2f49a504c9d3e..6cc4cf3ca9f45 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -3279,6 +3279,7 @@ static int __net_init tcp_sk_init(struct net *net)
+ net->ipv4.sysctl_tcp_comp_sack_delay_ns = NSEC_PER_MSEC;
+ net->ipv4.sysctl_tcp_comp_sack_slack_ns = 100 * NSEC_PER_USEC;
+ net->ipv4.sysctl_tcp_comp_sack_nr = 44;
++ net->ipv4.sysctl_tcp_backlog_ack_defer = 1;
+ net->ipv4.sysctl_tcp_fastopen = TFO_CLIENT_ENABLE;
+ net->ipv4.sysctl_tcp_fastopen_blackhole_timeout = 0;
+ atomic_set(&net->ipv4.tfo_active_disable_times, 0);
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 88551db62ca29..b82d1c146d3a4 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1083,7 +1083,8 @@ static void tcp_tasklet_func(struct tasklet_struct *t)
+ #define TCP_DEFERRED_ALL (TCPF_TSQ_DEFERRED | \
+ TCPF_WRITE_TIMER_DEFERRED | \
+ TCPF_DELACK_TIMER_DEFERRED | \
+- TCPF_MTU_REDUCED_DEFERRED)
++ TCPF_MTU_REDUCED_DEFERRED | \
++ TCPF_ACK_DEFERRED)
+ /**
+ * tcp_release_cb - tcp release_sock() callback
+ * @sk: socket
+@@ -1130,6 +1131,8 @@ void tcp_release_cb(struct sock *sk)
+ inet_csk(sk)->icsk_af_ops->mtu_reduced(sk);
+ __sock_put(sk);
+ }
++ if ((flags & TCPF_ACK_DEFERRED) && inet_csk_ack_scheduled(sk))
++ tcp_send_ack(sk);
+ }
+ EXPORT_SYMBOL(tcp_release_cb);
+
+--
+2.51.0
+
--- /dev/null
+From e52602fe536a06925d7ec1acaae0ea3fd0df344d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Oct 2023 13:30:44 -0700
+Subject: tcp: Set pingpong threshold via sysctl
+
+From: Haiyang Zhang <haiyangz@microsoft.com>
+
+[ Upstream commit 562b1fdf061bff9394ccd884456ed1173c224fdc ]
+
+TCP pingpong threshold is 1 by default. But some applications, like SQL DB
+may prefer a higher pingpong threshold to activate delayed acks in quick
+ack mode for better performance.
+
+The pingpong threshold and related code were changed to 3 in the year
+2019 in:
+ commit 4a41f453bedf ("tcp: change pingpong threshold to 3")
+And reverted to 1 in the year 2022 in:
+ commit 4d8f24eeedc5 ("Revert "tcp: change pingpong threshold to 3"")
+
+There is no single value that fits all applications.
+Add net.ipv4.tcp_pingpong_thresh sysctl tunable, so it can be tuned for
+optimal performance based on the application needs.
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://lore.kernel.org/r/1697056244-21888-1-git-send-email-haiyangz@microsoft.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 87b08913a9ae ("inet: move icmp_global_{credit,stamp} to a separate cache line")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/networking/ip-sysctl.rst | 13 +++++++++++++
+ include/net/inet_connection_sock.h | 16 ++++++++++++----
+ include/net/netns/ipv4.h | 2 ++
+ net/ipv4/sysctl_net_ipv4.c | 8 ++++++++
+ net/ipv4/tcp_ipv4.c | 2 ++
+ net/ipv4/tcp_output.c | 4 ++--
+ 6 files changed, 39 insertions(+), 6 deletions(-)
+
+diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
+index 5bfa1837968ce..531a070df2a6b 100644
+--- a/Documentation/networking/ip-sysctl.rst
++++ b/Documentation/networking/ip-sysctl.rst
+@@ -1183,6 +1183,19 @@ tcp_plb_cong_thresh - INTEGER
+
+ Default: 128
+
++tcp_pingpong_thresh - INTEGER
++ The number of estimated data replies sent for estimated incoming data
++ requests that must happen before TCP considers that a connection is a
++ "ping-pong" (request-response) connection for which delayed
++ acknowledgments can provide benefits.
++
++ This threshold is 1 by default, but some applications may need a higher
++ threshold for optimal performance.
++
++ Possible Values: 1 - 255
++
++ Default: 1
++
+ UDP variables
+ =============
+
+diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
+index e85834722b8f2..3eb715f66cbf6 100644
+--- a/include/net/inet_connection_sock.h
++++ b/include/net/inet_connection_sock.h
+@@ -326,11 +326,10 @@ void inet_csk_update_fastreuse(struct inet_bind_bucket *tb,
+
+ struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu);
+
+-#define TCP_PINGPONG_THRESH 1
+-
+ static inline void inet_csk_enter_pingpong_mode(struct sock *sk)
+ {
+- inet_csk(sk)->icsk_ack.pingpong = TCP_PINGPONG_THRESH;
++ inet_csk(sk)->icsk_ack.pingpong =
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_pingpong_thresh);
+ }
+
+ static inline void inet_csk_exit_pingpong_mode(struct sock *sk)
+@@ -340,7 +339,16 @@ static inline void inet_csk_exit_pingpong_mode(struct sock *sk)
+
+ static inline bool inet_csk_in_pingpong_mode(struct sock *sk)
+ {
+- return inet_csk(sk)->icsk_ack.pingpong >= TCP_PINGPONG_THRESH;
++ return inet_csk(sk)->icsk_ack.pingpong >=
++ READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_pingpong_thresh);
++}
++
++static inline void inet_csk_inc_pingpong_cnt(struct sock *sk)
++{
++ struct inet_connection_sock *icsk = inet_csk(sk);
++
++ if (icsk->icsk_ack.pingpong < U8_MAX)
++ icsk->icsk_ack.pingpong++;
+ }
+
+ static inline bool inet_csk_has_ulp(const struct sock *sk)
+diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
+index 3193e362b8a55..fb7842dfd185a 100644
+--- a/include/net/netns/ipv4.h
++++ b/include/net/netns/ipv4.h
+@@ -136,6 +136,8 @@ struct netns_ipv4 {
+ u8 sysctl_tcp_migrate_req;
+ u8 sysctl_tcp_comp_sack_nr;
+ u8 sysctl_tcp_backlog_ack_defer;
++ u8 sysctl_tcp_pingpong_thresh;
++
+ int sysctl_tcp_reordering;
+ u8 sysctl_tcp_retries1;
+ u8 sysctl_tcp_retries2;
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 18bcbcfee824a..96f1b8d39fac1 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -1498,6 +1498,14 @@ static struct ctl_table ipv4_net_table[] = {
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE,
+ },
++ {
++ .procname = "tcp_pingpong_thresh",
++ .data = &init_net.ipv4.sysctl_tcp_pingpong_thresh,
++ .maxlen = sizeof(u8),
++ .mode = 0644,
++ .proc_handler = proc_dou8vec_minmax,
++ .extra1 = SYSCTL_ONE,
++ },
+ { }
+ };
+
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 6cc4cf3ca9f45..ab4be34e58bb2 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -3303,6 +3303,8 @@ static int __net_init tcp_sk_init(struct net *net)
+ net->ipv4.sysctl_tcp_syn_linear_timeouts = 4;
+ net->ipv4.sysctl_tcp_shrink_window = 0;
+
++ net->ipv4.sysctl_tcp_pingpong_thresh = 1;
++
+ return 0;
+ }
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index b82d1c146d3a4..db8f2830c67bf 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -170,10 +170,10 @@ static void tcp_event_data_sent(struct tcp_sock *tp,
+ tp->lsndtime = now;
+
+ /* If it is a reply for ato after last received
+- * packet, enter pingpong mode.
++ * packet, increase pingpong count.
+ */
+ if ((u32)(now - icsk->icsk_ack.lrcvtime) < icsk->icsk_ack.ato)
+- inet_csk_enter_pingpong_mode(sk);
++ inet_csk_inc_pingpong_cnt(sk);
+ }
+
+ /* Account for an ACK we sent. */
+--
+2.51.0
+
--- /dev/null
+From acea335c8b2171cd93e02bc4d4e287e7ebfb85a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Feb 2026 13:09:03 -0600
+Subject: x86/hyperv: Fix error pointer dereference
+
+From: Ethan Tidmore <ethantidmore06@gmail.com>
+
+[ Upstream commit 705d01c8d78121ee1634bfc602ac4b0ad1438fab ]
+
+The function idle_thread_get() can return an error pointer and is not
+checked for it. Add check for error pointer.
+
+Detected by Smatch:
+arch/x86/hyperv/hv_vtl.c:126 hv_vtl_bringup_vcpu() error:
+'idle' dereferencing possible ERR_PTR()
+
+Fixes: 2b4b90e053a29 ("x86/hyperv: Use per cpu initial stack for vtl context")
+Signed-off-by: Ethan Tidmore <ethantidmore06@gmail.com>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/hyperv/hv_vtl.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c
+index b12bef0ff7bb6..4b91b41df5207 100644
+--- a/arch/x86/hyperv/hv_vtl.c
++++ b/arch/x86/hyperv/hv_vtl.c
+@@ -68,7 +68,7 @@ static void hv_vtl_ap_entry(void)
+
+ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
+ {
+- u64 status;
++ u64 status, rsp, rip;
+ int ret = 0;
+ struct hv_enable_vp_vtl *input;
+ unsigned long irq_flags;
+@@ -81,9 +81,11 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
+ struct desc_struct *gdt;
+
+ struct task_struct *idle = idle_thread_get(cpu);
+- u64 rsp = (unsigned long)idle->thread.sp;
++ if (IS_ERR(idle))
++ return PTR_ERR(idle);
+
+- u64 rip = (u64)&hv_vtl_ap_entry;
++ rsp = (unsigned long)idle->thread.sp;
++ rip = (u64)&hv_vtl_ap_entry;
+
+ native_store_gdt(&gdt_ptr);
+ store_idt(&idt_ptr);
+--
+2.51.0
+
--- /dev/null
+From 9b38d2c92d3786a0e568b43b6b9933e02e25be51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Feb 2026 22:40:40 +0000
+Subject: xen-netback: reject zero-queue configuration from guest
+
+From: Ziyi Guo <n7l8m4@u.northwestern.edu>
+
+[ Upstream commit 6d1dc8014334c7fb25719999bca84d811e60a559 ]
+
+A malicious or buggy Xen guest can write "0" to the xenbus key
+"multi-queue-num-queues". The connect() function in the backend only
+validates the upper bound (requested_num_queues > xenvif_max_queues)
+but not zero, allowing requested_num_queues=0 to reach
+vzalloc(array_size(0, sizeof(struct xenvif_queue))), which triggers
+WARN_ON_ONCE(!size) in __vmalloc_node_range().
+
+On systems with panic_on_warn=1, this allows a guest-to-host denial
+of service.
+
+The Xen network interface specification requires
+the queue count to be "greater than zero".
+
+Add a zero check to match the validation already present
+in xen-blkback, which has included this
+guard since its multi-queue support was added.
+
+Fixes: 8d3d53b3e433 ("xen-netback: Add support for multiple queues")
+Signed-off-by: Ziyi Guo <n7l8m4@u.northwestern.edu>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Link: https://patch.msgid.link/20260212224040.86674-1-n7l8m4@u.northwestern.edu
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/xen-netback/xenbus.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
+index a78a25b872409..61b547aab286a 100644
+--- a/drivers/net/xen-netback/xenbus.c
++++ b/drivers/net/xen-netback/xenbus.c
+@@ -735,10 +735,11 @@ static void connect(struct backend_info *be)
+ */
+ requested_num_queues = xenbus_read_unsigned(dev->otherend,
+ "multi-queue-num-queues", 1);
+- if (requested_num_queues > xenvif_max_queues) {
++ if (requested_num_queues > xenvif_max_queues ||
++ requested_num_queues == 0) {
+ /* buggy or malicious guest */
+ xenbus_dev_fatal(dev, -EINVAL,
+- "guest requested %u queues, exceeding the maximum of %u.",
++ "guest requested %u queues, but valid range is 1 - %u.",
+ requested_num_queues, xenvif_max_queues);
+ return;
+ }
+--
+2.51.0
+