]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees
authorSasha Levin <sashal@kernel.org>
Thu, 23 Apr 2026 00:00:57 +0000 (20:00 -0400)
committerSasha Levin <sashal@kernel.org>
Thu, 23 Apr 2026 00:00:57 +0000 (20:00 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
63 files changed:
queue-5.10/alsa-usb-audio-fix-null-pointer-dereference-on-point.patch [new file with mode: 0644]
queue-5.10/blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-.patch [new file with mode: 0644]
queue-5.10/bpf-sockmap-fix-an-infinite-loop-error-when-len-is-0.patch [new file with mode: 0644]
queue-5.10/cifs-fix-connections-leak-when-tlink-setup-failed.patch [new file with mode: 0644]
queue-5.10/drm-amd-display-add-null-checker-before-passing-vari.patch [new file with mode: 0644]
queue-5.10/drm-amd-display-fix-memory-leak.patch [new file with mode: 0644]
queue-5.10/ib-mad-don-t-call-to-function-that-might-sleep-while.patch [new file with mode: 0644]
queue-5.10/ipv6-add-null-checks-for-idev-in-srv6-paths.patch [new file with mode: 0644]
queue-5.10/net-sched-act_ct-fix-ref-leak-when-switching-zones.patch [new file with mode: 0644]
queue-5.10/net-tap-null-pointer-derefence-in-dev_parse_header_p.patch [new file with mode: 0644]
queue-5.10/scsi-qla2xxx-fix-crash-when-i-o-abort-times-out.patch [new file with mode: 0644]
queue-5.10/scsi-qla2xxx-fix-warning-message-due-to-adisc-being-.patch [new file with mode: 0644]
queue-5.10/scsi-ufs-core-improve-scsi-abort-handling.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/thermal-int340x_thermal-handle-data_vault-when-the-v.patch [new file with mode: 0644]
queue-5.10/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch [new file with mode: 0644]
queue-5.15/gfs2-improve-gfs2_consist_inode-usage.patch [new file with mode: 0644]
queue-5.15/gfs2-validate-i_depth-for-exhash-directories.patch [new file with mode: 0644]
queue-5.15/ipv6-add-null-checks-for-idev-in-srv6-paths.patch [new file with mode: 0644]
queue-5.15/net-tap-null-pointer-derefence-in-dev_parse_header_p.patch [new file with mode: 0644]
queue-5.15/pci-acpi-restrict-program_hpx_type2-to-aer-bits.patch [new file with mode: 0644]
queue-5.15/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch [new file with mode: 0644]
queue-5.15/revert-net-ethernet-xscale-check-for-ptp-support-pro.patch [new file with mode: 0644]
queue-5.15/revert-net-ixp4xx_eth-convert-to-ndo_hwtstamp_get-an.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch [new file with mode: 0644]
queue-6.1/gfs2-improve-gfs2_consist_inode-usage.patch [new file with mode: 0644]
queue-6.1/gfs2-validate-i_depth-for-exhash-directories.patch [new file with mode: 0644]
queue-6.1/ipv6-add-null-checks-for-idev-in-srv6-paths.patch [new file with mode: 0644]
queue-6.1/net-dsa-clean-up-fdb-mdb-vlan-entries-on-unbind.patch [new file with mode: 0644]
queue-6.1/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch [new file with mode: 0644]
queue-6.1/revert-net-ethernet-xscale-check-for-ptp-support-pro.patch [new file with mode: 0644]
queue-6.1/revert-net-ixp4xx_eth-convert-to-ndo_hwtstamp_get-an.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch [new file with mode: 0644]
queue-6.12/ima-do-not-copy-measurement-list-to-kdump-kernel.patch [new file with mode: 0644]
queue-6.12/ima-verify-if-the-segment-size-has-changed.patch [new file with mode: 0644]
queue-6.12/mm-userfaultfd-fix-hugetlb-fault-mutex-hash-calculat.patch [new file with mode: 0644]
queue-6.12/net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch [new file with mode: 0644]
queue-6.12/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch [new file with mode: 0644]
queue-6.12/rust-warn-on-bindgen-0.69.5-and-libclang-19.1.patch [new file with mode: 0644]
queue-6.12/series [new file with mode: 0644]
queue-6.12/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch [new file with mode: 0644]
queue-6.18/arm64-cputype-add-c1-pro-definitions.patch [new file with mode: 0644]
queue-6.18/arm64-errata-work-around-early-cme-dvmsync-acknowled.patch [new file with mode: 0644]
queue-6.18/arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch [new file with mode: 0644]
queue-6.18/arm64-tlb-introduce-__tlbi_sync_s1ish_-kernel-batch-.patch [new file with mode: 0644]
queue-6.18/arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch [new file with mode: 0644]
queue-6.18/arm64-tlb-pass-the-corresponding-mm-to-__tlbi_sync_s.patch [new file with mode: 0644]
queue-6.18/ipv6-add-null-checks-for-idev-in-srv6-paths.patch [new file with mode: 0644]
queue-6.18/net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch [new file with mode: 0644]
queue-6.18/series [new file with mode: 0644]
queue-6.6/i40e-fix-preempt-count-leak-in-napi-poll-tracepoint.patch [new file with mode: 0644]
queue-6.6/ipv6-add-null-checks-for-idev-in-srv6-paths.patch [new file with mode: 0644]
queue-6.6/md-raid1-raid10-don-t-ignore-io-flags.patch [new file with mode: 0644]
queue-6.6/net-annotate-data-races-around-sk-sk_-data_ready-wri.patch [new file with mode: 0644]
queue-6.6/net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch [new file with mode: 0644]
queue-6.6/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch [new file with mode: 0644]
queue-6.6/revert-perf-unwind-libdw-fix-invalid-reference-count.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch [new file with mode: 0644]
queue-7.0/pwm-th1520-fix-clippy-1-warning.patch [new file with mode: 0644]
queue-7.0/series [new file with mode: 0644]

diff --git a/queue-5.10/alsa-usb-audio-fix-null-pointer-dereference-on-point.patch b/queue-5.10/alsa-usb-audio-fix-null-pointer-dereference-on-point.patch
new file mode 100644 (file)
index 0000000..1606c1a
--- /dev/null
@@ -0,0 +1,53 @@
+From d8e3fbedb617d8fdb48d015c523938560b1fc86c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:20:47 +0300
+Subject: ALSA: usb-audio: fix null pointer dereference on pointer cs_desc
+
+From: Chengfeng Ye <cyeaa@connect.ust.hk>
+
+commit b97053df0f04747c3c1e021ecbe99db675342954 upstream.
+
+The pointer cs_desc return from snd_usb_find_clock_source could
+be null, so there is a potential null pointer dereference issue.
+Fix this by adding a null check before dereference.
+
+Signed-off-by: Chengfeng Ye <cyeaa@connect.ust.hk>
+Link: https://lore.kernel.org/r/20211024111736.11342-1-cyeaa@connect.ust.hk
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Fixes: 1dc669fed61a ("ALSA: usb-audio: UAC2: support read-only freq control")
+[ kovalev: bp to fix CVE-2021-47211; added Fixes tag; the null
+  check was added into both UAC2 and UAC3 branches since the
+  older kernel still has the clock source lookup split between
+  snd_usb_find_clock_source() and snd_usb_find_clock_source_v3()
+  (see upstream commit 9ec730052fa2) ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/clock.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/sound/usb/clock.c b/sound/usb/clock.c
+index 197a6b7d8ad6f..3d5d4f3aafce4 100644
+--- a/sound/usb/clock.c
++++ b/sound/usb/clock.c
+@@ -646,11 +646,17 @@ static int set_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
+               struct uac3_clock_source_descriptor *cs_desc;
+               cs_desc = snd_usb_find_clock_source_v3(chip->ctrl_intf, clock);
++
++              if (!cs_desc)
++                      return 0;
+               bmControls = le32_to_cpu(cs_desc->bmControls);
+       } else {
+               struct uac_clock_source_descriptor *cs_desc;
+               cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock);
++
++              if (!cs_desc)
++                      return 0;
+               bmControls = cs_desc->bmControls;
+       }
+-- 
+2.53.0
+
diff --git a/queue-5.10/blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-.patch b/queue-5.10/blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-.patch
new file mode 100644 (file)
index 0000000..76fa8bc
--- /dev/null
@@ -0,0 +1,65 @@
+From 262eae4b70b0206378b6253e40a1842433117160 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:29:20 +0300
+Subject: blk-cgroup: Reinit blkg_iostat_set after clearing in
+ blkcg_reset_stats()
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit 3d2af77e31ade05ff7ccc3658c3635ec1bea0979 ]
+
+When blkg_alloc() is called to allocate a blkcg_gq structure
+with the associated blkg_iostat_set's, there are 2 fields within
+blkg_iostat_set that requires proper initialization - blkg & sync.
+The former field was introduced by commit 3b8cc6298724 ("blk-cgroup:
+Optimize blkcg_rstat_flush()") while the later one was introduced by
+commit f73316482977 ("blk-cgroup: reimplement basic IO stats using
+cgroup rstat").
+
+Unfortunately those fields in the blkg_iostat_set's are not properly
+re-initialized when they are cleared in v1's blkcg_reset_stats(). This
+can lead to a kernel panic due to NULL pointer access of the blkg
+pointer. The missing initialization of sync is less problematic and
+can be a problem in a debug kernel due to missing lockdep initialization.
+
+Fix these problems by re-initializing them after memory clearing.
+
+Fixes: 3b8cc6298724 ("blk-cgroup: Optimize blkcg_rstat_flush()")
+Fixes: f73316482977 ("blk-cgroup: reimplement basic IO stats using cgroup rstat")
+Signed-off-by: Waiman Long <longman@redhat.com>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Acked-by: Tejun Heo <tj@kernel.org>
+Link: https://lore.kernel.org/r/20230606180724.2455066-1-longman@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+[ Remove this line: bis -> blkg = blkg for blkg was introduced by commit
+  3b8cc6298724 ("blk-cgroup: Optimize blkcg_rstat_flush()") since v6.2. ]
+Signed-off-by: Alva Lan <alvalan9@foxmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit 0561aa6033dd181594116d705c41fc16e97161a2)
+[ kovalev: bp to fix CVE-2023-53421 ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-cgroup.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index dbd18b75ec915..7ffdc3360a6c2 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -464,8 +464,12 @@ static int blkcg_reset_stats(struct cgroup_subsys_state *css,
+                       struct blkg_iostat_set *bis =
+                               per_cpu_ptr(blkg->iostat_cpu, cpu);
+                       memset(bis, 0, sizeof(*bis));
++
++                      /* Re-initialize the cleared blkg_iostat_set */
++                      u64_stats_init(&bis->sync);
+               }
+               memset(&blkg->iostat, 0, sizeof(blkg->iostat));
++              u64_stats_init(&blkg->iostat.sync);
+               for (i = 0; i < BLKCG_MAX_POLS; i++) {
+                       struct blkcg_policy *pol = blkcg_policy[i];
+-- 
+2.53.0
+
diff --git a/queue-5.10/bpf-sockmap-fix-an-infinite-loop-error-when-len-is-0.patch b/queue-5.10/bpf-sockmap-fix-an-infinite-loop-error-when-len-is-0.patch
new file mode 100644 (file)
index 0000000..765db5b
--- /dev/null
@@ -0,0 +1,92 @@
+From 28397a96d39224baf431d8752747d3cbba94dfea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:28:39 +0300
+Subject: bpf, sockmap: Fix an infinite loop error when len is 0 in
+ tcp_bpf_recvmsg_parser()
+
+From: Liu Jian <liujian56@huawei.com>
+
+commit d900f3d20cc3169ce42ec72acc850e662a4d4db2 upstream.
+
+When the buffer length of the recvmsg system call is 0, we got the
+flollowing soft lockup problem:
+
+watchdog: BUG: soft lockup - CPU#3 stuck for 27s! [a.out:6149]
+CPU: 3 PID: 6149 Comm: a.out Kdump: loaded Not tainted 6.2.0+ #30
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014
+RIP: 0010:remove_wait_queue+0xb/0xc0
+Code: 5e 41 5f c3 cc cc cc cc 0f 1f 80 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 0f 1f 44 00 00 41 57 <41> 56 41 55 41 54 55 48 89 fd 53 48 89 f3 4c 8d 6b 18 4c 8d 73 20
+RSP: 0018:ffff88811b5978b8 EFLAGS: 00000246
+RAX: 0000000000000000 RBX: ffff88811a7d3780 RCX: ffffffffb7a4d768
+RDX: dffffc0000000000 RSI: ffff88811b597908 RDI: ffff888115408040
+RBP: 1ffff110236b2f1b R08: 0000000000000000 R09: ffff88811a7d37e7
+R10: ffffed10234fa6fc R11: 0000000000000001 R12: ffff88811179b800
+R13: 0000000000000001 R14: ffff88811a7d38a8 R15: ffff88811a7d37e0
+FS:  00007f6fb5398740(0000) GS:ffff888237180000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000020000000 CR3: 000000010b6ba002 CR4: 0000000000370ee0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <TASK>
+ tcp_msg_wait_data+0x279/0x2f0
+ tcp_bpf_recvmsg_parser+0x3c6/0x490
+ inet_recvmsg+0x280/0x290
+ sock_recvmsg+0xfc/0x120
+ ____sys_recvmsg+0x160/0x3d0
+ ___sys_recvmsg+0xf0/0x180
+ __sys_recvmsg+0xea/0x1a0
+ do_syscall_64+0x3f/0x90
+ entry_SYSCALL_64_after_hwframe+0x72/0xdc
+
+The logic in tcp_bpf_recvmsg_parser is as follows:
+
+msg_bytes_ready:
+       copied = sk_msg_recvmsg(sk, psock, msg, len, flags);
+       if (!copied) {
+               wait data;
+               goto msg_bytes_ready;
+       }
+
+In this case, "copied" always is 0, the infinite loop occurs.
+
+According to the Linux system call man page, 0 should be returned in this
+case. Therefore, in tcp_bpf_recvmsg_parser(), if the length is 0, directly
+return. Also modify several other functions with the same problem.
+
+Fixes: 1f5be6b3b063 ("udp: Implement udp_bpf_recvmsg() for sockmap")
+Fixes: 9825d866ce0d ("af_unix: Implement unix_dgram_bpf_recvmsg()")
+Fixes: c5d2177a72a1 ("bpf, sockmap: Fix race in ingress receive verdict with redirect to self")
+Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
+Signed-off-by: Liu Jian <liujian56@huawei.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: John Fastabend <john.fastabend@gmail.com>
+Cc: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://lore.kernel.org/bpf/20230303080946.1146638-1-liujian56@huawei.com
+[ kovalev: bp to fix CVE-2023-53133; applied only to tcp_bpf_recvmsg as the
+  older kernel lacks tcp_bpf_recvmsg_parser, udp_bpf_recvmsg and
+  unix_bpf_recvmsg (see upstream commits c5d2177a72a1, 1f5be6b3b063 and
+  9825d866ce0d) ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_bpf.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index bcd5fc484f777..76cd974887774 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -277,6 +277,9 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
+       if (unlikely(flags & MSG_ERRQUEUE))
+               return inet_recv_error(sk, msg, len, addr_len);
++      if (!len)
++              return 0;
++
+       psock = sk_psock_get(sk);
+       if (unlikely(!psock))
+               return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len);
+-- 
+2.53.0
+
diff --git a/queue-5.10/cifs-fix-connections-leak-when-tlink-setup-failed.patch b/queue-5.10/cifs-fix-connections-leak-when-tlink-setup-failed.patch
new file mode 100644 (file)
index 0000000..1b5a7d3
--- /dev/null
@@ -0,0 +1,70 @@
+From a673f9695413a4ee877ef4500501e432670259a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:26:12 +0300
+Subject: cifs: Fix connections leak when tlink setup failed
+
+From: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+
+commit 1dcdf5f5b2137185cbdd5385f29949ab3da4f00c upstream.
+
+If the tlink setup failed, lost to put the connections, then
+the module refcnt leak since the cifsd kthread not exit.
+
+Also leak the fscache info, and for next mount with fsc, it will
+print the follow errors:
+  CIFS: Cache volume key already in use (cifs,127.0.0.1:445,TEST)
+
+Let's check the result of tlink setup, and do some cleanup.
+
+Fixes: 56c762eb9bee ("cifs: Refactor out cifs_mount()")
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+[ kovalev: bp to fix CVE-2022-49822; adapted to use direct xid/ses/tcon
+  variables instead of mnt_ctx struct fields due to the older kernel not
+  having the corresponding cifs_mount() refactoring (see upstream commit
+  c88f7dcd6d64) ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/connect.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 769c7759601db..3161155fd069b 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -4786,9 +4786,13 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol)
+       vol->prepath = NULL;
+ out:
+-      free_xid(xid);
+       cifs_try_adding_channels(ses);
+-      return mount_setup_tlink(cifs_sb, ses, tcon);
++      rc = mount_setup_tlink(cifs_sb, ses, tcon);
++      if (rc)
++              goto error;
++
++      free_xid(xid);
++      return rc;
+ error:
+       kfree(ref_path);
+@@ -4820,9 +4824,12 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol)
+                       goto error;
+       }
+-      free_xid(xid);
++      rc = mount_setup_tlink(cifs_sb, ses, tcon);
++      if (rc)
++              goto error;
+-      return mount_setup_tlink(cifs_sb, ses, tcon);
++      free_xid(xid);
++      return rc;
+ error:
+       mount_put_conns(cifs_sb, xid, server, ses, tcon);
+-- 
+2.53.0
+
diff --git a/queue-5.10/drm-amd-display-add-null-checker-before-passing-vari.patch b/queue-5.10/drm-amd-display-add-null-checker-before-passing-vari.patch
new file mode 100644 (file)
index 0000000..f00ef0e
--- /dev/null
@@ -0,0 +1,64 @@
+From 7d242d657edfd9dc6b5ff8c3d01d6401fbd6e346 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:30:02 +0300
+Subject: drm/amd/display: Add null checker before passing variables
+
+From: Alex Hung <alex.hung@amd.com>
+
+commit 8092aa3ab8f7b737a34b71f91492c676a843043a upstream.
+
+Checks null pointer before passing variables to functions.
+
+This fixes 3 NULL_RETURNS issues reported by Coverity.
+
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Signed-off-by: Alex Hung <alex.hung@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Fixes: cdaae8371aa9 ("drm/amd/display: Handle GPU reset for DC block")
+Fixes: dcd5fb82ffb4 ("drm/amd/display: Fix reference counting for struct dc_sink.")
+Fixes: 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)")
+[ kovalev: bp to fix CVE-2024-43902; added Fixes tags ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 ++++++---
+ 1 file changed, 6 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 c22783b882067..bd15de4dee75e 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1778,7 +1778,8 @@ static int dm_suspend(void *handle)
+               mutex_lock(&dm->dc_lock);
+               dm->cached_dc_state = dc_copy_state(dm->dc->current_state);
+-              dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
++              if (dm->cached_dc_state)
++                      dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
+               amdgpu_dm_commit_zero_streams(dm->dc);
+@@ -5396,7 +5397,8 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector)
+               aconnector->dc_sink = aconnector->dc_link->local_sink ?
+               aconnector->dc_link->local_sink :
+               aconnector->dc_em_sink;
+-              dc_sink_retain(aconnector->dc_sink);
++              if (aconnector->dc_sink)
++                      dc_sink_retain(aconnector->dc_sink);
+       }
+ }
+@@ -6575,7 +6577,8 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector)
+                               drm_add_modes_noedid(connector, 640, 480);
+       } else {
+               amdgpu_dm_connector_ddc_get_modes(connector, edid);
+-              amdgpu_dm_connector_add_common_modes(encoder, connector);
++              if (encoder)
++                      amdgpu_dm_connector_add_common_modes(encoder, connector);
+       }
+       amdgpu_dm_fbc_init(connector);
+-- 
+2.53.0
+
diff --git a/queue-5.10/drm-amd-display-fix-memory-leak.patch b/queue-5.10/drm-amd-display-fix-memory-leak.patch
new file mode 100644 (file)
index 0000000..c91293f
--- /dev/null
@@ -0,0 +1,251 @@
+From d76e99b1f3bd524a34fe3905d019c4dc437821cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:22:10 +0300
+Subject: drm/amd/display: Fix memory leak
+
+From: Yongzhi Liu <lyz_cs@pku.edu.cn>
+
+commit 5d5c6dba2b43e28845d7d7ed32a36802329a5f52 upstream.
+
+[why]
+Resource release is needed on the error handling path
+to prevent memory leak.
+
+[how]
+Fix this by adding kfree on the error handling path.
+
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Yongzhi Liu <lyz_cs@pku.edu.cn>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Fixes: f8ac2cf78f27 ("drm/amd/display: Linux set/read lane settings through debugfs")
+Fixes: c06e09b76639 ("drm/amd/display: Add DSC parameters logging to debugfs")
+[ kovalev: bp to fix CVE-2022-49135; added Fixes tags ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 72 ++++++++++++++-----
+ 1 file changed, 54 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+index 6914738f0275a..f4a1ad8959b7d 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+@@ -229,8 +229,10 @@ static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -388,8 +390,10 @@ static ssize_t dp_phy_settings_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user((*(rd_buf + result)), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1195,8 +1199,10 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1212,8 +1218,10 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1351,8 +1359,10 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1368,8 +1378,10 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1505,8 +1517,10 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1522,8 +1536,10 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1655,8 +1671,10 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1672,8 +1690,10 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1800,8 +1820,10 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1817,8 +1839,10 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1857,8 +1881,10 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1874,8 +1900,10 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -1929,8 +1957,10 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -1946,8 +1976,10 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+@@ -2001,8 +2033,10 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
+                               break;
+       }
+-      if (!pipe_ctx)
++      if (!pipe_ctx) {
++              kfree(rd_buf);
+               return -ENXIO;
++      }
+       dsc = pipe_ctx->stream_res.dsc;
+       if (dsc)
+@@ -2018,8 +2052,10 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
+                       break;
+               r = put_user(*(rd_buf + result), buf);
+-              if (r)
++              if (r) {
++                      kfree(rd_buf);
+                       return r; /* r = -EFAULT */
++              }
+               buf += 1;
+               size -= 1;
+-- 
+2.53.0
+
diff --git a/queue-5.10/ib-mad-don-t-call-to-function-that-might-sleep-while.patch b/queue-5.10/ib-mad-don-t-call-to-function-that-might-sleep-while.patch
new file mode 100644 (file)
index 0000000..4f281aa
--- /dev/null
@@ -0,0 +1,149 @@
+From e0ef7f5827eb4e7de8eabf099b10bc8e61db1c00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:28:08 +0300
+Subject: IB/mad: Don't call to function that might sleep while in atomic
+ context
+
+From: Leonid Ravich <lravich@gmail.com>
+
+commit 5c20311d76cbaeb7ed2ecf9c8b8322f8fc4a7ae3 upstream.
+
+Tracepoints are not allowed to sleep, as such the following splat is
+generated due to call to ib_query_pkey() in atomic context.
+
+WARNING: CPU: 0 PID: 1888000 at kernel/trace/ring_buffer.c:2492 rb_commit+0xc1/0x220
+CPU: 0 PID: 1888000 Comm: kworker/u9:0 Kdump: loaded Tainted: G           OE    --------- -  - 4.18.0-305.3.1.el8.x86_64 #1
+ Hardware name: Red Hat KVM, BIOS 1.13.0-2.module_el8.3.0+555+a55c8938 04/01/2014
+ Workqueue: ib-comp-unb-wq ib_cq_poll_work [ib_core]
+ RIP: 0010:rb_commit+0xc1/0x220
+ RSP: 0000:ffffa8ac80f9bca0 EFLAGS: 00010202
+ RAX: ffff8951c7c01300 RBX: ffff8951c7c14a00 RCX: 0000000000000246
+ RDX: ffff8951c707c000 RSI: ffff8951c707c57c RDI: ffff8951c7c14a00
+ RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
+ R10: ffff8951c7c01300 R11: 0000000000000001 R12: 0000000000000246
+ R13: 0000000000000000 R14: ffffffff964c70c0 R15: 0000000000000000
+ FS:  0000000000000000(0000) GS:ffff8951fbc00000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f20e8f39010 CR3: 000000002ca10005 CR4: 0000000000170ef0
+ Call Trace:
+  ring_buffer_unlock_commit+0x1d/0xa0
+  trace_buffer_unlock_commit_regs+0x3b/0x1b0
+  trace_event_buffer_commit+0x67/0x1d0
+  trace_event_raw_event_ib_mad_recv_done_handler+0x11c/0x160 [ib_core]
+  ib_mad_recv_done+0x48b/0xc10 [ib_core]
+  ? trace_event_raw_event_cq_poll+0x6f/0xb0 [ib_core]
+  __ib_process_cq+0x91/0x1c0 [ib_core]
+  ib_cq_poll_work+0x26/0x80 [ib_core]
+  process_one_work+0x1a7/0x360
+  ? create_worker+0x1a0/0x1a0
+  worker_thread+0x30/0x390
+  ? create_worker+0x1a0/0x1a0
+  kthread+0x116/0x130
+  ? kthread_flush_work_fn+0x10/0x10
+  ret_from_fork+0x35/0x40
+ ---[ end trace 78ba8509d3830a16 ]---
+
+Fixes: 821bf1de45a1 ("IB/MAD: Add recv path trace point")
+Signed-off-by: Leonid Ravich <lravich@gmail.com>
+Link: https://lore.kernel.org/r/Y2t5feomyznrVj7V@leonid-Inspiron-3421
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+[ kovalev: bp to fix CVE-2022-50472 ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/mad.c |  5 -----
+ include/trace/events/ib_mad.h | 13 ++++---------
+ 2 files changed, 4 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 19540a13cb84d..e38ae4ac454f6 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -59,9 +59,6 @@ static void create_mad_addr_info(struct ib_mad_send_wr_private *mad_send_wr,
+                         struct ib_mad_qp_info *qp_info,
+                         struct trace_event_raw_ib_mad_send_template *entry)
+ {
+-      u16 pkey;
+-      struct ib_device *dev = qp_info->port_priv->device;
+-      u8 pnum = qp_info->port_priv->port_num;
+       struct ib_ud_wr *wr = &mad_send_wr->send_wr;
+       struct rdma_ah_attr attr = {};
+@@ -69,8 +66,6 @@ static void create_mad_addr_info(struct ib_mad_send_wr_private *mad_send_wr,
+       /* These are common */
+       entry->sl = attr.sl;
+-      ib_query_pkey(dev, pnum, wr->pkey_index, &pkey);
+-      entry->pkey = pkey;
+       entry->rqpn = wr->remote_qpn;
+       entry->rqkey = wr->remote_qkey;
+       entry->dlid = rdma_ah_get_dlid(&attr);
+diff --git a/include/trace/events/ib_mad.h b/include/trace/events/ib_mad.h
+index 59363a083ecb9..d92691c78cff6 100644
+--- a/include/trace/events/ib_mad.h
++++ b/include/trace/events/ib_mad.h
+@@ -49,7 +49,6 @@ DECLARE_EVENT_CLASS(ib_mad_send_template,
+               __field(int,            retries_left)
+               __field(int,            max_retries)
+               __field(int,            retry)
+-              __field(u16,            pkey)
+       ),
+       TP_fast_assign(
+@@ -89,7 +88,7 @@ DECLARE_EVENT_CLASS(ib_mad_send_template,
+                 "hdr : base_ver 0x%x class 0x%x class_ver 0x%x " \
+                 "method 0x%x status 0x%x class_specific 0x%x tid 0x%llx " \
+                 "attr_id 0x%x attr_mod 0x%x  => dlid 0x%08x sl %d "\
+-                "pkey 0x%x rpqn 0x%x rqpkey 0x%x",
++                "rpqn 0x%x rqpkey 0x%x",
+               __entry->dev_index, __entry->port_num, __entry->qp_num,
+               __entry->agent_priv, be64_to_cpu(__entry->wrtid),
+               __entry->retries_left, __entry->max_retries,
+@@ -100,7 +99,7 @@ DECLARE_EVENT_CLASS(ib_mad_send_template,
+               be16_to_cpu(__entry->class_specific),
+               be64_to_cpu(__entry->tid), be16_to_cpu(__entry->attr_id),
+               be32_to_cpu(__entry->attr_mod),
+-              be32_to_cpu(__entry->dlid), __entry->sl, __entry->pkey,
++              be32_to_cpu(__entry->dlid), __entry->sl,
+               __entry->rqpn, __entry->rqkey
+       )
+ );
+@@ -204,7 +203,6 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+               __field(u16,            wc_status)
+               __field(u32,            slid)
+               __field(u32,            dev_index)
+-              __field(u16,            pkey)
+       ),
+       TP_fast_assign(
+@@ -224,9 +222,6 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+               __entry->slid = wc->slid;
+               __entry->src_qp = wc->src_qp;
+               __entry->sl = wc->sl;
+-              ib_query_pkey(qp_info->port_priv->device,
+-                            qp_info->port_priv->port_num,
+-                            wc->pkey_index, &__entry->pkey);
+               __entry->wc_status = wc->status;
+       ),
+@@ -234,7 +229,7 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+                 "base_ver 0x%02x class 0x%02x class_ver 0x%02x " \
+                 "method 0x%02x status 0x%04x class_specific 0x%04x " \
+                 "tid 0x%016llx attr_id 0x%04x attr_mod 0x%08x " \
+-                "slid 0x%08x src QP%d, sl %d pkey 0x%04x",
++                "slid 0x%08x src QP%d, sl %d",
+               __entry->dev_index, __entry->port_num, __entry->qp_num,
+               __entry->wc_status,
+               __entry->length,
+@@ -244,7 +239,7 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+               be16_to_cpu(__entry->class_specific),
+               be64_to_cpu(__entry->tid), be16_to_cpu(__entry->attr_id),
+               be32_to_cpu(__entry->attr_mod),
+-              __entry->slid, __entry->src_qp, __entry->sl, __entry->pkey
++              __entry->slid, __entry->src_qp, __entry->sl
+       )
+ );
+-- 
+2.53.0
+
diff --git a/queue-5.10/ipv6-add-null-checks-for-idev-in-srv6-paths.patch b/queue-5.10/ipv6-add-null-checks-for-idev-in-srv6-paths.patch
new file mode 100644 (file)
index 0000000..f0b501a
--- /dev/null
@@ -0,0 +1,60 @@
+From 2874b2e897dbd331c8790ce67932ed9916f68984 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 13:43:34 +0800
+Subject: ipv6: add NULL checks for idev in SRv6 paths
+
+From: Minhong He <heminhong@kylinos.cn>
+
+[ Upstream commit 06413793526251870e20402c39930804f14d59c0 ]
+
+__in6_dev_get() can return NULL when the device has no IPv6 configuration
+(e.g. MTU < IPV6_MIN_MTU or after NETDEV_UNREGISTER).
+
+Add NULL checks for idev returned by __in6_dev_get() in both
+seg6_hmac_validate_skb() and ipv6_srh_rcv() to prevent potential NULL
+pointer dereferences.
+
+Fixes: 1ababeba4a21 ("ipv6: implement dataplane support for rthdr type 4 (Segment Routing Header)")
+Fixes: bf355b8d2c30 ("ipv6: sr: add core files for SR HMAC support")
+Signed-off-by: Minhong He <heminhong@kylinos.cn>
+Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it>
+Link: https://patch.msgid.link/20260316073301.106643-1-heminhong@kylinos.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c   | 4 ++++
+ net/ipv6/seg6_hmac.c | 2 ++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index cdad9019c77c4..dfa0fb3d6c35f 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -361,6 +361,10 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
+       hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
+       idev = __in6_dev_get(skb->dev);
++      if (!idev) {
++              kfree_skb(skb);
++              return -1;
++      }
+       accept_seg6 = net->ipv6.devconf_all->seg6_enabled;
+       if (accept_seg6 > idev->cnf.seg6_enabled)
+diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
+index f82fcd8908e14..b52985c867c29 100644
+--- a/net/ipv6/seg6_hmac.c
++++ b/net/ipv6/seg6_hmac.c
+@@ -245,6 +245,8 @@ bool seg6_hmac_validate_skb(struct sk_buff *skb)
+       struct inet6_dev *idev;
+       idev = __in6_dev_get(skb->dev);
++      if (!idev)
++              return false;
+       srh = (struct ipv6_sr_hdr *)skb_transport_header(skb);
+-- 
+2.53.0
+
diff --git a/queue-5.10/net-sched-act_ct-fix-ref-leak-when-switching-zones.patch b/queue-5.10/net-sched-act_ct-fix-ref-leak-when-switching-zones.patch
new file mode 100644 (file)
index 0000000..8852388
--- /dev/null
@@ -0,0 +1,69 @@
+From f025eecbed345ba9801b7a92dc364b173500ae9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:24:47 +0300
+Subject: net/sched: act_ct: fix ref leak when switching zones
+
+From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+
+commit bcb74e132a76ce0502bb33d5b65533a4ed72d159 upstream.
+
+When switching zones or network namespaces without doing a ct clear in
+between, it is now leaking a reference to the old ct entry. That's
+because tcf_ct_skb_nfct_cached() returns false and
+tcf_ct_flow_table_lookup() may simply overwrite it.
+
+The fix is to, as the ct entry is not reusable, free it already at
+tcf_ct_skb_nfct_cached().
+
+Reported-by: Florian Westphal <fw@strlen.de>
+Fixes: 2f131de361f6 ("net/sched: act_ct: Fix flow table lookup after ct clear or switching zones")
+Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[ kovalev: bp to fix CVE-2022-49183; used nf_conntrack_put(&ct->ct_general)
+  instead of nf_ct_put(ct) due to the older kernel not yet having the
+  conversion from the indirect call (see upstream commit 408bdcfce8df) ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/act_ct.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
+index d9748c917a503..d75f4b2b97daa 100644
+--- a/net/sched/act_ct.c
++++ b/net/sched/act_ct.c
+@@ -589,22 +589,25 @@ static bool tcf_ct_skb_nfct_cached(struct net *net, struct sk_buff *skb,
+       if (!ct)
+               return false;
+       if (!net_eq(net, read_pnet(&ct->ct_net)))
+-              return false;
++              goto drop_ct;
+       if (nf_ct_zone(ct)->id != zone_id)
+-              return false;
++              goto drop_ct;
+       /* Force conntrack entry direction. */
+       if (force && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) {
+               if (nf_ct_is_confirmed(ct))
+                       nf_ct_kill(ct);
+-              nf_conntrack_put(&ct->ct_general);
+-              nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
+-
+-              return false;
++              goto drop_ct;
+       }
+       return true;
++
++drop_ct:
++      nf_conntrack_put(&ct->ct_general);
++      nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
++
++      return false;
+ }
+ /* Trim the skb to the length specified by the IP/IPv6 header,
+-- 
+2.53.0
+
diff --git a/queue-5.10/net-tap-null-pointer-derefence-in-dev_parse_header_p.patch b/queue-5.10/net-tap-null-pointer-derefence-in-dev_parse_header_p.patch
new file mode 100644 (file)
index 0000000..084331e
--- /dev/null
@@ -0,0 +1,116 @@
+From f4e132dea25274f9899ddd27026c2334ae0a2ce7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:27:29 +0300
+Subject: net: tap: NULL pointer derefence in dev_parse_header_protocol when
+ skb->dev is null
+
+From: Cezar Bulinaru <cbulinaru@gmail.com>
+
+commit 4f61f133f354853bc394ec7d6028adb9b02dd701 upstream.
+
+Fixes a NULL pointer derefence bug triggered from tap driver.
+When tap_get_user calls virtio_net_hdr_to_skb the skb->dev is null
+(in tap.c skb->dev is set after the call to virtio_net_hdr_to_skb)
+virtio_net_hdr_to_skb calls dev_parse_header_protocol which
+needs skb->dev field to be valid.
+
+The line that trigers the bug is in dev_parse_header_protocol
+(dev is at offset 0x10 from skb and is stored in RAX register)
+  if (!dev->header_ops || !dev->header_ops->parse_protocol)
+  22e1:   mov    0x10(%rbx),%rax
+  22e5:          mov    0x230(%rax),%rax
+
+Setting skb->dev before the call in tap.c fixes the issue.
+
+BUG: kernel NULL pointer dereference, address: 0000000000000230
+RIP: 0010:virtio_net_hdr_to_skb.constprop.0+0x335/0x410 [tap]
+Code: c0 0f 85 b7 fd ff ff eb d4 41 39 c6 77 cf 29 c6 48 89 df 44 01 f6 e8 7a 79 83 c1 48 85 c0 0f 85 d9 fd ff ff eb b7 48 8b 43 10 <48> 8b 80 30 02 00 00 48 85 c0 74 55 48 8b 40 28 48 85 c0 74 4c 48
+RSP: 0018:ffffc90005c27c38 EFLAGS: 00010246
+RAX: 0000000000000000 RBX: ffff888298f25300 RCX: 0000000000000010
+RDX: 0000000000000005 RSI: ffffc90005c27cb6 RDI: ffff888298f25300
+RBP: ffffc90005c27c80 R08: 00000000ffffffea R09: 00000000000007e8
+R10: ffff88858ec77458 R11: 0000000000000000 R12: 0000000000000001
+R13: 0000000000000014 R14: ffffc90005c27e08 R15: ffffc90005c27cb6
+FS:  0000000000000000(0000) GS:ffff88858ec40000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000000000230 CR3: 0000000281408006 CR4: 00000000003706e0
+Call Trace:
+ tap_get_user+0x3f1/0x540 [tap]
+ tap_sendmsg+0x56/0x362 [tap]
+ ? get_tx_bufs+0xc2/0x1e0 [vhost_net]
+ handle_tx_copy+0x114/0x670 [vhost_net]
+ handle_tx+0xb0/0xe0 [vhost_net]
+ handle_tx_kick+0x15/0x20 [vhost_net]
+ vhost_worker+0x7b/0xc0 [vhost]
+ ? vhost_vring_call_reset+0x40/0x40 [vhost]
+ kthread+0xfa/0x120
+ ? kthread_complete_and_exit+0x20/0x20
+ ret_from_fork+0x1f/0x30
+
+Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
+Signed-off-by: Cezar Bulinaru <cbulinaru@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[ kovalev: bp to fix CVE-2022-50073 ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tap.c | 23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/tap.c b/drivers/net/tap.c
+index 16fa0e3e752ab..18f19fc66c64f 100644
+--- a/drivers/net/tap.c
++++ b/drivers/net/tap.c
+@@ -703,11 +703,22 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,
+       skb_reset_mac_header(skb);
+       skb->protocol = eth_hdr(skb)->h_proto;
++      rcu_read_lock();
++      tap = rcu_dereference(q->tap);
++      if (!tap) {
++              kfree_skb(skb);
++              rcu_read_unlock();
++              return total_len;
++      }
++      skb->dev = tap->dev;
++
+       if (vnet_hdr_len) {
+               err = virtio_net_hdr_to_skb(skb, &vnet_hdr,
+                                           tap_is_little_endian(q));
+-              if (err)
++              if (err) {
++                      rcu_read_unlock();
+                       goto err_kfree;
++              }
+       }
+       skb_probe_transport_header(skb);
+@@ -717,8 +728,6 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,
+           vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0)
+               skb_set_network_header(skb, depth);
+-      rcu_read_lock();
+-      tap = rcu_dereference(q->tap);
+       /* copy skb_ubuf_info for callback when skb has no error */
+       if (zerocopy) {
+               skb_shinfo(skb)->destructor_arg = msg_control;
+@@ -729,14 +738,8 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,
+               uarg->callback(uarg, false);
+       }
+-      if (tap) {
+-              skb->dev = tap->dev;
+-              dev_queue_xmit(skb);
+-      } else {
+-              kfree_skb(skb);
+-      }
++      dev_queue_xmit(skb);
+       rcu_read_unlock();
+-
+       return total_len;
+ err_kfree:
+-- 
+2.53.0
+
diff --git a/queue-5.10/scsi-qla2xxx-fix-crash-when-i-o-abort-times-out.patch b/queue-5.10/scsi-qla2xxx-fix-crash-when-i-o-abort-times-out.patch
new file mode 100644 (file)
index 0000000..5477632
--- /dev/null
@@ -0,0 +1,96 @@
+From 286424098d655ba449dac91350c21ebc2f791cbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:23:27 +0300
+Subject: scsi: qla2xxx: Fix crash when I/O abort times out
+
+From: Arun Easi <aeasi@marvell.com>
+
+commit 68ad83188d782b2ecef2e41ac245d27e0710fe8e upstream.
+
+While performing CPU hotplug, a crash with the following stack was seen:
+
+Call Trace:
+     qla24xx_process_response_queue+0x42a/0x970 [qla2xxx]
+     qla2x00_start_nvme_mq+0x3a2/0x4b0 [qla2xxx]
+     qla_nvme_post_cmd+0x166/0x240 [qla2xxx]
+     nvme_fc_start_fcp_op.part.0+0x119/0x2e0 [nvme_fc]
+     blk_mq_dispatch_rq_list+0x17b/0x610
+     __blk_mq_sched_dispatch_requests+0xb0/0x140
+     blk_mq_sched_dispatch_requests+0x30/0x60
+     __blk_mq_run_hw_queue+0x35/0x90
+     __blk_mq_delay_run_hw_queue+0x161/0x180
+     blk_execute_rq+0xbe/0x160
+     __nvme_submit_sync_cmd+0x16f/0x220 [nvme_core]
+     nvmf_connect_admin_queue+0x11a/0x170 [nvme_fabrics]
+     nvme_fc_create_association.cold+0x50/0x3dc [nvme_fc]
+     nvme_fc_connect_ctrl_work+0x19/0x30 [nvme_fc]
+     process_one_work+0x1e8/0x3c0
+
+On abort timeout, completion was called without checking if the I/O was
+already completed.
+
+Verify that I/O and abort request are indeed outstanding before attempting
+completion.
+
+Fixes: 71c80b75ce8f ("scsi: qla2xxx: Do command completion on abort timeout")
+Reported-by: Marco Patalano <mpatalan@redhat.com>
+Tested-by: Marco Patalano <mpatalan@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Arun Easi <aeasi@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Link: https://lore.kernel.org/r/20221129092634.15347-1-njavali@marvell.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+[ kovalev: bp to fix CVE-2022-50493 ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 79b9571f63508..4a057748ba175 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -101,6 +101,7 @@ static void qla24xx_abort_iocb_timeout(void *data)
+       struct qla_qpair *qpair = sp->qpair;
+       u32 handle;
+       unsigned long flags;
++      int sp_found = 0, cmdsp_found = 0;
+       if (sp->cmd_sp)
+               ql_dbg(ql_dbg_async, sp->vha, 0x507c,
+@@ -115,22 +116,27 @@ static void qla24xx_abort_iocb_timeout(void *data)
+       spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+       for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
+               if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
+-                  sp->cmd_sp))
++                  sp->cmd_sp)) {
+                       qpair->req->outstanding_cmds[handle] = NULL;
++                      cmdsp_found = 1;
++              }
+               /* removing the abort */
+               if (qpair->req->outstanding_cmds[handle] == sp) {
+                       qpair->req->outstanding_cmds[handle] = NULL;
++                      sp_found = 1;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+-      if (sp->cmd_sp)
++      if (cmdsp_found && sp->cmd_sp)
+               sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
+-      abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
+-      sp->done(sp, QLA_OS_TIMER_EXPIRED);
++      if (sp_found) {
++              abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
++              sp->done(sp, QLA_OS_TIMER_EXPIRED);
++      }
+ }
+ static void qla24xx_abort_sp_done(srb_t *sp, int res)
+-- 
+2.53.0
+
diff --git a/queue-5.10/scsi-qla2xxx-fix-warning-message-due-to-adisc-being-.patch b/queue-5.10/scsi-qla2xxx-fix-warning-message-due-to-adisc-being-.patch
new file mode 100644 (file)
index 0000000..ca2ff7a
--- /dev/null
@@ -0,0 +1,93 @@
+From 74b20bde9cca494db3cf5a277eaf41d393fe0318 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:23:26 +0300
+Subject: scsi: qla2xxx: Fix warning message due to adisc being flushed
+
+From: Quinn Tran <qutran@marvell.com>
+
+commit 64f24af75b79cba3b86b0760e27e0fa904db570f upstream.
+
+Fix warning message due to adisc being flushed.  Linux kernel triggered a
+warning message where a different error code type is not matching up with
+the expected type. Add additional translation of one error code type to
+another.
+
+WARNING: CPU: 2 PID: 1131623 at drivers/scsi/qla2xxx/qla_init.c:498
+qla2x00_async_adisc_sp_done+0x294/0x2b0 [qla2xxx]
+CPU: 2 PID: 1131623 Comm: drmgr Not tainted 5.13.0-rc1-autotest #1
+..
+GPR28: c000000aaa9c8890 c0080000079ab678 c00000140a104800 c00000002bd19000
+NIP [c00800000790857c] qla2x00_async_adisc_sp_done+0x294/0x2b0 [qla2xxx]
+LR [c008000007908578] qla2x00_async_adisc_sp_done+0x290/0x2b0 [qla2xxx]
+Call Trace:
+[c00000001cdc3620] [c008000007908578] qla2x00_async_adisc_sp_done+0x290/0x2b0 [qla2xxx] (unreliable)
+[c00000001cdc3710] [c0080000078f3080] __qla2x00_abort_all_cmds+0x1b8/0x580 [qla2xxx]
+[c00000001cdc3840] [c0080000078f589c] qla2x00_abort_all_cmds+0x34/0xd0 [qla2xxx]
+[c00000001cdc3880] [c0080000079153d8] qla2x00_abort_isp_cleanup+0x3f0/0x570 [qla2xxx]
+[c00000001cdc3920] [c0080000078fb7e8] qla2x00_remove_one+0x3d0/0x480 [qla2xxx]
+[c00000001cdc39b0] [c00000000071c274] pci_device_remove+0x64/0x120
+[c00000001cdc39f0] [c0000000007fb818] device_release_driver_internal+0x168/0x2a0
+[c00000001cdc3a30] [c00000000070e304] pci_stop_bus_device+0xb4/0x100
+[c00000001cdc3a70] [c00000000070e4f0] pci_stop_and_remove_bus_device+0x20/0x40
+[c00000001cdc3aa0] [c000000000073940] pci_hp_remove_devices+0x90/0x130
+[c00000001cdc3b30] [c0080000070704d0] disable_slot+0x38/0x90 [rpaphp] [
+c00000001cdc3b60] [c00000000073eb4c] power_write_file+0xcc/0x180
+[c00000001cdc3be0] [c0000000007354bc] pci_slot_attr_store+0x3c/0x60
+[c00000001cdc3c00] [c00000000055f820] sysfs_kf_write+0x60/0x80 [c00000001cdc3c20]
+[c00000000055df10] kernfs_fop_write_iter+0x1a0/0x290
+[c00000001cdc3c70] [c000000000447c4c] new_sync_write+0x14c/0x1d0
+[c00000001cdc3d10] [c00000000044b134] vfs_write+0x224/0x330
+[c00000001cdc3d60] [c00000000044b3f4] ksys_write+0x74/0x130
+[c00000001cdc3db0] [c00000000002df70] system_call_exception+0x150/0x2d0
+[c00000001cdc3e10] [c00000000000d45c] system_call_common+0xec/0x278
+
+Link: https://lore.kernel.org/r/20220110050218.3958-5-njavali@marvell.com
+Cc: stable@vger.kernel.org
+Reported-by: Abdul Haleem <abdhalee@linux.vnet.ibm.com>
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+[ kovalev: bp to fix CVE-2022-49158; in qla2x00_async_prli_sp_done used
+  'if (res)' instead of 'else if (res)' due to the older kernel not having
+  the preceding QLA_OS_TIMER_EXPIRED check (see upstream commit 4de067e5df12) ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_init.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 7b6227fde7beb..79b9571f63508 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -283,6 +283,8 @@ static void qla2x00_async_login_sp_done(srb_t *sp, int res)
+               ea.iop[0] = lio->u.logio.iop[0];
+               ea.iop[1] = lio->u.logio.iop[1];
+               ea.sp = sp;
++              if (res)
++                      ea.data[0] = MBS_COMMAND_ERROR;
+               qla24xx_handle_plogi_done_event(vha, &ea);
+       }
+@@ -563,6 +565,8 @@ static void qla2x00_async_adisc_sp_done(srb_t *sp, int res)
+       ea.iop[1] = lio->u.logio.iop[1];
+       ea.fcport = sp->fcport;
+       ea.sp = sp;
++      if (res)
++              ea.data[0] = MBS_COMMAND_ERROR;
+       qla24xx_handle_adisc_event(vha, &ea);
+@@ -1238,6 +1242,8 @@ static void qla2x00_async_prli_sp_done(srb_t *sp, int res)
+               ea.iop[0] = lio->u.logio.iop[0];
+               ea.iop[1] = lio->u.logio.iop[1];
+               ea.sp = sp;
++              if (res)
++                      ea.data[0] = MBS_COMMAND_ERROR;
+               qla24xx_handle_prli_done_event(vha, &ea);
+       }
+-- 
+2.53.0
+
diff --git a/queue-5.10/scsi-ufs-core-improve-scsi-abort-handling.patch b/queue-5.10/scsi-ufs-core-improve-scsi-abort-handling.patch
new file mode 100644 (file)
index 0000000..f31056a
--- /dev/null
@@ -0,0 +1,56 @@
+From 5a2afeda3b653b526b28333764e532c5cd1f929e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:19:41 +0300
+Subject: scsi: ufs: core: Improve SCSI abort handling
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+commit 3ff1f6b6ba6f97f50862aa50e79959cc8ddc2566 upstream.
+
+The following has been observed on a test setup:
+
+WARNING: CPU: 4 PID: 250 at drivers/scsi/ufs/ufshcd.c:2737 ufshcd_queuecommand+0x468/0x65c
+Call trace:
+ ufshcd_queuecommand+0x468/0x65c
+ scsi_send_eh_cmnd+0x224/0x6a0
+ scsi_eh_test_devices+0x248/0x418
+ scsi_eh_ready_devs+0xc34/0xe58
+ scsi_error_handler+0x204/0x80c
+ kthread+0x150/0x1b4
+ ret_from_fork+0x10/0x30
+
+That warning is triggered by the following statement:
+
+       WARN_ON(lrbp->cmd);
+
+Fix this warning by clearing lrbp->cmd from the abort handler.
+
+Link: https://lore.kernel.org/r/20211104181059.4129537-1-bvanassche@acm.org
+Fixes: 7a3e97b0dc4b ("[SCSI] ufshcd: UFS Host controller driver")
+Reviewed-by: Bean Huo <beanhuo@micron.com>
+Reviewed-by: Stanley Chu <stanley.chu@mediatek.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+[ kovalev: bp to fix CVE-2021-47188; adapted placement of
+  lrbp->cmd = NULL for 5.10 function structure ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ufs/ufshcd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
+index c7bf0e6bc303d..1b8072f47e7e8 100644
+--- a/drivers/scsi/ufs/ufshcd.c
++++ b/drivers/scsi/ufs/ufshcd.c
+@@ -6788,6 +6788,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
+               __ufshcd_transfer_req_compl(hba, (1UL << tag));
+               spin_unlock_irqrestore(host->host_lock, flags);
+ out:
++              lrbp->cmd = NULL;
+               err = SUCCESS;
+       } else {
+               dev_err(hba->dev, "%s: failed with err %d\n", __func__, err);
+-- 
+2.53.0
+
index 74c1b215db9b1293c19f276e13937a4a1661e947..296a6bc7b24f814d673c8a75041ce1144166eb54 100644 (file)
@@ -82,3 +82,18 @@ media-as102-fix-to-not-free-memory-after-the-device-is-registered-in-as102_usb_p
 nilfs2-fix-null-i_assoc_inode-dereference-in-nilfs_mdt_save_to_shadow_map.patch
 media-vidtv-fix-pass-by-value-structs-causing-msan-warnings.patch
 media-hackrf-fix-to-not-free-memory-after-the-device-is-registered-in-hackrf_probe.patch
+net-tap-null-pointer-derefence-in-dev_parse_header_p.patch
+scsi-qla2xxx-fix-warning-message-due-to-adisc-being-.patch
+scsi-qla2xxx-fix-crash-when-i-o-abort-times-out.patch
+net-sched-act_ct-fix-ref-leak-when-switching-zones.patch
+bpf-sockmap-fix-an-infinite-loop-error-when-len-is-0.patch
+ipv6-add-null-checks-for-idev-in-srv6-paths.patch
+drm-amd-display-add-null-checker-before-passing-vari.patch
+wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
+cifs-fix-connections-leak-when-tlink-setup-failed.patch
+drm-amd-display-fix-memory-leak.patch
+thermal-int340x_thermal-handle-data_vault-when-the-v.patch
+blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-.patch
+alsa-usb-audio-fix-null-pointer-dereference-on-point.patch
+scsi-ufs-core-improve-scsi-abort-handling.patch
+ib-mad-don-t-call-to-function-that-might-sleep-while.patch
diff --git a/queue-5.10/thermal-int340x_thermal-handle-data_vault-when-the-v.patch b/queue-5.10/thermal-int340x_thermal-handle-data_vault-when-the-v.patch
new file mode 100644 (file)
index 0000000..53ba33f
--- /dev/null
@@ -0,0 +1,75 @@
+From ab20b150597d6322a7e833c42ea1a23d70673a13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:21:30 +0300
+Subject: thermal/int340x_thermal: handle data_vault when the value is
+ ZERO_SIZE_PTR
+
+From: Lee, Chun-Yi <joeyli.kernel@gmail.com>
+
+commit 7931e28098a4c1a2a6802510b0cbe57546d2049d upstream.
+
+In some case, the GDDV returns a package with a buffer which has
+zero length. It causes that kmemdup() returns ZERO_SIZE_PTR (0x10).
+
+Then the data_vault_read() got NULL point dereference problem when
+accessing the 0x10 value in data_vault.
+
+[   71.024560] BUG: kernel NULL pointer dereference, address:
+0000000000000010
+
+This patch uses ZERO_OR_NULL_PTR() for checking ZERO_SIZE_PTR or
+NULL value in data_vault.
+
+Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+[ kovalev: bp to fix CVE-2022-48703 ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/intel/int340x_thermal/int3400_thermal.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
+index 28913867cd4bc..a064a4eb31fba 100644
+--- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
++++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
+@@ -466,7 +466,7 @@ static void int3400_setup_gddv(struct int3400_thermal_priv *priv)
+       priv->data_vault = kmemdup(obj->package.elements[0].buffer.pointer,
+                                  obj->package.elements[0].buffer.length,
+                                  GFP_KERNEL);
+-      if (!priv->data_vault) {
++      if (ZERO_OR_NULL_PTR(priv->data_vault)) {
+               kfree(buffer.pointer);
+               return;
+       }
+@@ -531,7 +531,7 @@ static int int3400_thermal_probe(struct platform_device *pdev)
+       if (result)
+               goto free_rel_misc;
+-      if (priv->data_vault) {
++      if (!ZERO_OR_NULL_PTR(priv->data_vault)) {
+               result = sysfs_create_group(&pdev->dev.kobj,
+                                           &data_attribute_group);
+               if (result)
+@@ -549,7 +549,8 @@ static int int3400_thermal_probe(struct platform_device *pdev)
+ free_sysfs:
+       cleanup_odvp(priv);
+       if (priv->data_vault) {
+-              sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group);
++              if (!ZERO_OR_NULL_PTR(priv->data_vault))
++                      sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group);
+               kfree(priv->data_vault);
+       }
+ free_uuid:
+@@ -579,7 +580,7 @@ static int int3400_thermal_remove(struct platform_device *pdev)
+       if (!priv->rel_misc_dev_res)
+               acpi_thermal_rel_misc_device_remove(priv->adev->handle);
+-      if (priv->data_vault)
++      if (!ZERO_OR_NULL_PTR(priv->data_vault))
+               sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group);
+       sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group);
+       thermal_zone_device_unregister(priv->thermal);
+-- 
+2.53.0
+
diff --git a/queue-5.10/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch b/queue-5.10/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
new file mode 100644 (file)
index 0000000..3c5224b
--- /dev/null
@@ -0,0 +1,107 @@
+From 105fafbfdf62b72afad64d3ab58d103540cb5273 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 10:44:25 +0800
+Subject: wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
+
+ieee80211_tx_prepare_skb() has three error paths, but only two of them
+free the skb. The first error path (ieee80211_tx_prepare() returning
+TX_DROP) does not free it, while invoke_tx_handlers() failure and the
+fragmentation check both do.
+
+Add kfree_skb() to the first error path so all three are consistent,
+and remove the now-redundant frees in callers (ath9k, mt76,
+mac80211_hwsim) to avoid double-free.
+
+Document the skb ownership guarantee in the function's kdoc.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name
+Fixes: 06be6b149f7e ("mac80211: add ieee80211_tx_prepare_skb() helper function")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
+ introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning")
+ after linux-6.14.]
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/channel.c | 6 ++----
+ drivers/net/wireless/mac80211_hwsim.c    | 1 -
+ include/net/mac80211.h                   | 4 ++++
+ net/mac80211/tx.c                        | 4 +++-
+ 4 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
+index 6cf0875221572..31b7921bf34f3 100644
+--- a/drivers/net/wireless/ath/ath9k/channel.c
++++ b/drivers/net/wireless/ath/ath9k/channel.c
+@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
+       skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+       if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
+-              goto error;
++              return;
+       txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
+       if (ath_tx_start(sc->hw, skb, &txctl))
+@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
+               skb->priority = 7;
+               skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+-              if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
+-                      dev_kfree_skb_any(skb);
++              if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
+                       return false;
+-              }
+               break;
+       default:
+               return false;
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index 037358606a51a..865bbe0293436 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -2275,7 +2275,6 @@ static void hw_scan_work(struct work_struct *work)
+                                                     hwsim->tmp_chan->band,
+                                                     NULL)) {
+                               rcu_read_unlock();
+-                              kfree_skb(probe);
+                               continue;
+                       }
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 8f91609f928c1..70ee982f08d9d 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -6337,6 +6337,10 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
+  * @band: the band to transmit on
+  * @sta: optional pointer to get the station to send the frame to
+  *
++ * Return: %true if the skb was prepared, %false otherwise.
++ * On failure, the skb is freed by this function; callers must not
++ * free it again.
++ *
+  * Note: must be called under RCU lock
+  */
+ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 30ad46cfcad86..b923cd755a68c 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1869,8 +1869,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
+       struct ieee80211_tx_data tx;
+       struct sk_buff *skb2;
+-      if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
++      if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
++              kfree_skb(skb);
+               return false;
++      }
+       info->band = band;
+       info->control.vif = vif;
+-- 
+2.53.0
+
diff --git a/queue-5.15/gfs2-improve-gfs2_consist_inode-usage.patch b/queue-5.15/gfs2-improve-gfs2_consist_inode-usage.patch
new file mode 100644 (file)
index 0000000..9ef9464
--- /dev/null
@@ -0,0 +1,213 @@
+From cd5479151b7db88bc636e9e58835cd4b3514dd75 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Apr 2026 18:40:20 +0800
+Subject: gfs2: Improve gfs2_consist_inode() usage
+
+From: Andrew Price <anprice@redhat.com>
+
+[ Upstream commit 10398ef57aa189153406c110f5957145030f08fe ]
+
+gfs2_consist_inode() logs an error message with the source file and line
+number. When we jump before calling it, the line number becomes less
+useful as it no longer relates to the source of the error. To aid
+troubleshooting, replace the gotos with the gfs2_consist_inode() calls
+so that the error messages are more informative.
+
+Signed-off-by: Andrew Price <anprice@redhat.com>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Ruohan Lan <ruohanlan@aliyun.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/dir.c   | 31 +++++++++++++++++--------------
+ fs/gfs2/glops.c | 34 ++++++++++++++++++++--------------
+ fs/gfs2/xattr.c | 28 ++++++++++++++++------------
+ 3 files changed, 53 insertions(+), 40 deletions(-)
+
+diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
+index 42b7dfffb5e7e..e1bdc4b0608c2 100644
+--- a/fs/gfs2/dir.c
++++ b/fs/gfs2/dir.c
+@@ -562,15 +562,18 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
+       int ret = 0;
+       ret = gfs2_dirent_offset(GFS2_SB(inode), buf);
+-      if (ret < 0)
+-              goto consist_inode;
+-
++      if (ret < 0) {
++              gfs2_consist_inode(GFS2_I(inode));
++              return ERR_PTR(-EIO);
++      }
+       offset = ret;
+       prev = NULL;
+       dent = buf + offset;
+       size = be16_to_cpu(dent->de_rec_len);
+-      if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, len, 1))
+-              goto consist_inode;
++      if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, len, 1)) {
++              gfs2_consist_inode(GFS2_I(inode));
++              return ERR_PTR(-EIO);
++      }
+       do {
+               ret = scan(dent, name, opaque);
+               if (ret)
+@@ -582,8 +585,10 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
+               dent = buf + offset;
+               size = be16_to_cpu(dent->de_rec_len);
+               if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size,
+-                                    len, 0))
+-                      goto consist_inode;
++                                    len, 0)) {
++                      gfs2_consist_inode(GFS2_I(inode));
++                      return ERR_PTR(-EIO);
++              }
+       } while(1);
+       switch(ret) {
+@@ -597,10 +602,6 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
+               BUG_ON(ret > 0);
+               return ERR_PTR(ret);
+       }
+-
+-consist_inode:
+-      gfs2_consist_inode(GFS2_I(inode));
+-      return ERR_PTR(-EIO);
+ }
+ static int dirent_check_reclen(struct gfs2_inode *dip,
+@@ -609,14 +610,16 @@ static int dirent_check_reclen(struct gfs2_inode *dip,
+       const void *ptr = d;
+       u16 rec_len = be16_to_cpu(d->de_rec_len);
+-      if (unlikely(rec_len < sizeof(struct gfs2_dirent)))
+-              goto broken;
++      if (unlikely(rec_len < sizeof(struct gfs2_dirent))) {
++              gfs2_consist_inode(dip);
++              return -EIO;
++      }
+       ptr += rec_len;
+       if (ptr < end_p)
+               return rec_len;
+       if (ptr == end_p)
+               return -ENOENT;
+-broken:
++
+       gfs2_consist_inode(dip);
+       return -EIO;
+ }
+diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
+index 5a4b3550d833f..fdbae357727b2 100644
+--- a/fs/gfs2/glops.c
++++ b/fs/gfs2/glops.c
+@@ -405,10 +405,14 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
+       struct inode *inode = &ip->i_inode;
+       bool is_new = inode->i_state & I_NEW;
+-      if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
+-              goto corrupt;
+-      if (unlikely(!is_new && inode_wrong_type(inode, mode)))
+-              goto corrupt;
++      if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
++      if (unlikely(!is_new && inode_wrong_type(inode, mode))) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
+       ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
+       inode->i_mode = mode;
+       if (is_new) {
+@@ -444,26 +448,28 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
+       /* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */
+       gfs2_set_inode_flags(inode);
+       height = be16_to_cpu(str->di_height);
+-      if (unlikely(height > sdp->sd_max_height))
+-              goto corrupt;
++      if (unlikely(height > sdp->sd_max_height)) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
+       ip->i_height = (u8)height;
+       depth = be16_to_cpu(str->di_depth);
+-      if (unlikely(depth > GFS2_DIR_MAX_DEPTH))
+-              goto corrupt;
++      if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
+       ip->i_depth = (u8)depth;
+       ip->i_entries = be32_to_cpu(str->di_entries);
+-      if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip))
+-              goto corrupt;
+-
++      if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip)) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
+       if (S_ISREG(inode->i_mode))
+               gfs2_set_aops(inode);
+       return 0;
+-corrupt:
+-      gfs2_consist_inode(ip);
+-      return -EIO;
+ }
+ /**
+diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
+index 0c5650fe1fd18..2b0fe8cf2173a 100644
+--- a/fs/gfs2/xattr.c
++++ b/fs/gfs2/xattr.c
+@@ -96,30 +96,34 @@ static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
+               return -EIO;
+       for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
+-              if (!GFS2_EA_REC_LEN(ea))
+-                      goto fail;
++              if (!GFS2_EA_REC_LEN(ea)) {
++                      gfs2_consist_inode(ip);
++                      return -EIO;
++              }
+               if (!(bh->b_data <= (char *)ea && (char *)GFS2_EA2NEXT(ea) <=
+-                                                bh->b_data + bh->b_size))
+-                      goto fail;
+-              if (!gfs2_eatype_valid(sdp, ea->ea_type))
+-                      goto fail;
++                                                bh->b_data + bh->b_size)) {
++                      gfs2_consist_inode(ip);
++                      return -EIO;
++              }
++              if (!gfs2_eatype_valid(sdp, ea->ea_type)) {
++                      gfs2_consist_inode(ip);
++                      return -EIO;
++              }
+               error = ea_call(ip, bh, ea, prev, data);
+               if (error)
+                       return error;
+               if (GFS2_EA_IS_LAST(ea)) {
+                       if ((char *)GFS2_EA2NEXT(ea) !=
+-                          bh->b_data + bh->b_size)
+-                              goto fail;
++                          bh->b_data + bh->b_size) {
++                              gfs2_consist_inode(ip);
++                              return -EIO;
++                      }
+                       break;
+               }
+       }
+       return error;
+-
+-fail:
+-      gfs2_consist_inode(ip);
+-      return -EIO;
+ }
+ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
+-- 
+2.53.0
+
diff --git a/queue-5.15/gfs2-validate-i_depth-for-exhash-directories.patch b/queue-5.15/gfs2-validate-i_depth-for-exhash-directories.patch
new file mode 100644 (file)
index 0000000..d0c74b0
--- /dev/null
@@ -0,0 +1,95 @@
+From d8ebb52ffe41a26abae6c8b3c697b6da0646e6d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Apr 2026 18:40:21 +0800
+Subject: gfs2: Validate i_depth for exhash directories
+
+From: Andrew Price <anprice@redhat.com>
+
+[ Upstream commit 557c024ca7250bb65ae60f16c02074106c2f197b ]
+
+A fuzzer test introduced corruption that ends up with a depth of 0 in
+dir_e_read(), causing an undefined shift by 32 at:
+
+  index = hash >> (32 - dip->i_depth);
+
+As calculated in an open-coded way in dir_make_exhash(), the minimum
+depth for an exhash directory is ilog2(sdp->sd_hash_ptrs) and 0 is
+invalid as sdp->sd_hash_ptrs is fixed as sdp->bsize / 16 at mount time.
+
+So we can avoid the undefined behaviour by checking for depth values
+lower than the minimum in gfs2_dinode_in(). Values greater than the
+maximum are already being checked for there.
+
+Also switch the calculation in dir_make_exhash() to use ilog2() to
+clarify how the depth is calculated.
+
+Tested with the syzkaller repro.c and xfstests '-g quick'.
+
+Reported-by: syzbot+4708579bb230a0582a57@syzkaller.appspotmail.com
+Signed-off-by: Andrew Price <anprice@redhat.com>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Ruohan Lan <ruohanlan@aliyun.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/dir.c   | 6 ++----
+ fs/gfs2/glops.c | 6 ++++++
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
+index e1bdc4b0608c2..559cad553db62 100644
+--- a/fs/gfs2/dir.c
++++ b/fs/gfs2/dir.c
+@@ -60,6 +60,7 @@
+ #include <linux/crc32.h>
+ #include <linux/vmalloc.h>
+ #include <linux/bio.h>
++#include <linux/log2.h>
+ #include "gfs2.h"
+ #include "incore.h"
+@@ -912,7 +913,6 @@ static int dir_make_exhash(struct inode *inode)
+       struct qstr args;
+       struct buffer_head *bh, *dibh;
+       struct gfs2_leaf *leaf;
+-      int y;
+       u32 x;
+       __be64 *lp;
+       u64 bn;
+@@ -979,9 +979,7 @@ static int dir_make_exhash(struct inode *inode)
+       i_size_write(inode, sdp->sd_sb.sb_bsize / 2);
+       gfs2_add_inode_blocks(&dip->i_inode, 1);
+       dip->i_diskflags |= GFS2_DIF_EXHASH;
+-
+-      for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ;
+-      dip->i_depth = y;
++      dip->i_depth = ilog2(sdp->sd_hash_ptrs);
+       gfs2_dinode_out(dip, dibh->b_data);
+diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
+index fdbae357727b2..8a077de9ee0a4 100644
+--- a/fs/gfs2/glops.c
++++ b/fs/gfs2/glops.c
+@@ -11,6 +11,7 @@
+ #include <linux/bio.h>
+ #include <linux/posix_acl.h>
+ #include <linux/security.h>
++#include <linux/log2.h>
+ #include "gfs2.h"
+ #include "incore.h"
+@@ -459,6 +460,11 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
+               gfs2_consist_inode(ip);
+               return -EIO;
+       }
++      if ((ip->i_diskflags & GFS2_DIF_EXHASH) &&
++          depth < ilog2(sdp->sd_hash_ptrs)) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
+       ip->i_depth = (u8)depth;
+       ip->i_entries = be32_to_cpu(str->di_entries);
+-- 
+2.53.0
+
diff --git a/queue-5.15/ipv6-add-null-checks-for-idev-in-srv6-paths.patch b/queue-5.15/ipv6-add-null-checks-for-idev-in-srv6-paths.patch
new file mode 100644 (file)
index 0000000..473c34d
--- /dev/null
@@ -0,0 +1,60 @@
+From d2c76cfe8401165b523489f1af820b690190108c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 13:43:21 +0800
+Subject: ipv6: add NULL checks for idev in SRv6 paths
+
+From: Minhong He <heminhong@kylinos.cn>
+
+[ Upstream commit 06413793526251870e20402c39930804f14d59c0 ]
+
+__in6_dev_get() can return NULL when the device has no IPv6 configuration
+(e.g. MTU < IPV6_MIN_MTU or after NETDEV_UNREGISTER).
+
+Add NULL checks for idev returned by __in6_dev_get() in both
+seg6_hmac_validate_skb() and ipv6_srh_rcv() to prevent potential NULL
+pointer dereferences.
+
+Fixes: 1ababeba4a21 ("ipv6: implement dataplane support for rthdr type 4 (Segment Routing Header)")
+Fixes: bf355b8d2c30 ("ipv6: sr: add core files for SR HMAC support")
+Signed-off-by: Minhong He <heminhong@kylinos.cn>
+Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it>
+Link: https://patch.msgid.link/20260316073301.106643-1-heminhong@kylinos.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c   | 4 ++++
+ net/ipv6/seg6_hmac.c | 2 ++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 10772dab66bbd..3d249c10e3e9b 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -373,6 +373,10 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
+       hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
+       idev = __in6_dev_get(skb->dev);
++      if (!idev) {
++              kfree_skb(skb);
++              return -1;
++      }
+       accept_seg6 = net->ipv6.devconf_all->seg6_enabled;
+       if (accept_seg6 > idev->cnf.seg6_enabled)
+diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
+index 7e3a857699322..68acff337e414 100644
+--- a/net/ipv6/seg6_hmac.c
++++ b/net/ipv6/seg6_hmac.c
+@@ -244,6 +244,8 @@ bool seg6_hmac_validate_skb(struct sk_buff *skb)
+       struct inet6_dev *idev;
+       idev = __in6_dev_get(skb->dev);
++      if (!idev)
++              return false;
+       srh = (struct ipv6_sr_hdr *)skb_transport_header(skb);
+-- 
+2.53.0
+
diff --git a/queue-5.15/net-tap-null-pointer-derefence-in-dev_parse_header_p.patch b/queue-5.15/net-tap-null-pointer-derefence-in-dev_parse_header_p.patch
new file mode 100644 (file)
index 0000000..dd7b448
--- /dev/null
@@ -0,0 +1,116 @@
+From b66b87094b3ac935c867c707736562d16a66605b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:27:02 +0300
+Subject: net: tap: NULL pointer derefence in dev_parse_header_protocol when
+ skb->dev is null
+
+From: Cezar Bulinaru <cbulinaru@gmail.com>
+
+commit 4f61f133f354853bc394ec7d6028adb9b02dd701 upstream.
+
+Fixes a NULL pointer derefence bug triggered from tap driver.
+When tap_get_user calls virtio_net_hdr_to_skb the skb->dev is null
+(in tap.c skb->dev is set after the call to virtio_net_hdr_to_skb)
+virtio_net_hdr_to_skb calls dev_parse_header_protocol which
+needs skb->dev field to be valid.
+
+The line that trigers the bug is in dev_parse_header_protocol
+(dev is at offset 0x10 from skb and is stored in RAX register)
+  if (!dev->header_ops || !dev->header_ops->parse_protocol)
+  22e1:   mov    0x10(%rbx),%rax
+  22e5:          mov    0x230(%rax),%rax
+
+Setting skb->dev before the call in tap.c fixes the issue.
+
+BUG: kernel NULL pointer dereference, address: 0000000000000230
+RIP: 0010:virtio_net_hdr_to_skb.constprop.0+0x335/0x410 [tap]
+Code: c0 0f 85 b7 fd ff ff eb d4 41 39 c6 77 cf 29 c6 48 89 df 44 01 f6 e8 7a 79 83 c1 48 85 c0 0f 85 d9 fd ff ff eb b7 48 8b 43 10 <48> 8b 80 30 02 00 00 48 85 c0 74 55 48 8b 40 28 48 85 c0 74 4c 48
+RSP: 0018:ffffc90005c27c38 EFLAGS: 00010246
+RAX: 0000000000000000 RBX: ffff888298f25300 RCX: 0000000000000010
+RDX: 0000000000000005 RSI: ffffc90005c27cb6 RDI: ffff888298f25300
+RBP: ffffc90005c27c80 R08: 00000000ffffffea R09: 00000000000007e8
+R10: ffff88858ec77458 R11: 0000000000000000 R12: 0000000000000001
+R13: 0000000000000014 R14: ffffc90005c27e08 R15: ffffc90005c27cb6
+FS:  0000000000000000(0000) GS:ffff88858ec40000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000000000230 CR3: 0000000281408006 CR4: 00000000003706e0
+Call Trace:
+ tap_get_user+0x3f1/0x540 [tap]
+ tap_sendmsg+0x56/0x362 [tap]
+ ? get_tx_bufs+0xc2/0x1e0 [vhost_net]
+ handle_tx_copy+0x114/0x670 [vhost_net]
+ handle_tx+0xb0/0xe0 [vhost_net]
+ handle_tx_kick+0x15/0x20 [vhost_net]
+ vhost_worker+0x7b/0xc0 [vhost]
+ ? vhost_vring_call_reset+0x40/0x40 [vhost]
+ kthread+0xfa/0x120
+ ? kthread_complete_and_exit+0x20/0x20
+ ret_from_fork+0x1f/0x30
+
+Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
+Signed-off-by: Cezar Bulinaru <cbulinaru@gmail.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[ kovalev: bp to fix CVE-2022-50073 ]
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tap.c | 23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/tap.c b/drivers/net/tap.c
+index 53eadd82f9b8c..a08adca412b41 100644
+--- a/drivers/net/tap.c
++++ b/drivers/net/tap.c
+@@ -703,11 +703,22 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,
+       skb_reset_mac_header(skb);
+       skb->protocol = eth_hdr(skb)->h_proto;
++      rcu_read_lock();
++      tap = rcu_dereference(q->tap);
++      if (!tap) {
++              kfree_skb(skb);
++              rcu_read_unlock();
++              return total_len;
++      }
++      skb->dev = tap->dev;
++
+       if (vnet_hdr_len) {
+               err = virtio_net_hdr_to_skb(skb, &vnet_hdr,
+                                           tap_is_little_endian(q));
+-              if (err)
++              if (err) {
++                      rcu_read_unlock();
+                       goto err_kfree;
++              }
+       }
+       skb_probe_transport_header(skb);
+@@ -717,8 +728,6 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,
+           vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0)
+               skb_set_network_header(skb, depth);
+-      rcu_read_lock();
+-      tap = rcu_dereference(q->tap);
+       /* copy skb_ubuf_info for callback when skb has no error */
+       if (zerocopy) {
+               skb_zcopy_init(skb, msg_control);
+@@ -727,14 +736,8 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,
+               uarg->callback(NULL, uarg, false);
+       }
+-      if (tap) {
+-              skb->dev = tap->dev;
+-              dev_queue_xmit(skb);
+-      } else {
+-              kfree_skb(skb);
+-      }
++      dev_queue_xmit(skb);
+       rcu_read_unlock();
+-
+       return total_len;
+ err_kfree:
+-- 
+2.53.0
+
diff --git a/queue-5.15/pci-acpi-restrict-program_hpx_type2-to-aer-bits.patch b/queue-5.15/pci-acpi-restrict-program_hpx_type2-to-aer-bits.patch
new file mode 100644 (file)
index 0000000..4a143ee
--- /dev/null
@@ -0,0 +1,202 @@
+From 46496c852cbf7eee54bc5356b906b829003f1f47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Mar 2026 18:17:36 +0100
+Subject: PCI/ACPI: Restrict program_hpx_type2() to AER bits
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Håkon Bugge <haakon.bugge@oracle.com>
+
+commit 9abf79c8d7b40db0e5a34aa8c744ea60ff9a3fcf upstream.
+
+Previously program_hpx_type2() applied PCIe settings unconditionally,
+which could incorrectly change bits like Extended Tag Field Enable and
+Enable Relaxed Ordering.
+
+When _HPX was added to ACPI r3.0, the intent of the PCIe Setting
+Record (Type 2) in sec 6.2.7.3 was to configure AER registers when the
+OS does not own the AER Capability:
+
+  The PCI Express setting record contains ... [the AER] Uncorrectable
+  Error Mask, Uncorrectable Error Severity, Correctable Error Mask
+  ... to be used when configuring registers in the Advanced Error
+  Reporting Extended Capability Structure ...
+
+  OSPM [1] will only evaluate _HPX with Setting Record – Type 2 if
+  OSPM is not controlling the PCI Express Advanced Error Reporting
+  capability.
+
+ACPI r3.0b, sec 6.2.7.3, added more AER registers, including registers
+in the PCIe Capability with AER-related bits, and the restriction that
+the OS use this only when it owns PCIe native hotplug:
+
+  ... when configuring PCI Express registers in the Advanced Error
+  Reporting Extended Capability Structure *or PCI Express Capability
+  Structure* ...
+
+  An OS that has assumed ownership of native hot plug but does not
+  ... have ownership of the AER register set must use ... the Type 2
+  record to program the AER registers ...
+
+  However, since the Type 2 record also includes register bits that
+  have functions other than AER, the OS must ignore values ... that
+  are not applicable.
+
+Restrict program_hpx_type2() to only the intended purpose:
+
+  - Apply settings only when OS owns PCIe native hotplug but not AER,
+
+  - Only touch the AER-related bits (Error Reporting Enables) in Device
+    Control
+
+  - Don't touch Link Control at all, since nothing there seems AER-related,
+    but log _HPX settings for debugging purposes
+
+Note that Read Completion Boundary is now configured elsewhere, since it is
+unrelated to _HPX.
+
+[1] Operating System-directed configuration and Power Management
+
+Fixes: 40abb96c51bb ("[PATCH] pciehp: Fix programming hotplug parameters")
+Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Link: https://patch.msgid.link/20260129175237.727059-3-haakon.bugge@oracle.com
+[ Conflict in drivers/pci.h because the context has changed. ]
+Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/pci-acpi.c | 59 +++++++++++++++++-------------------------
+ drivers/pci/pci.h      |  3 +++
+ drivers/pci/pcie/aer.c |  3 ---
+ 3 files changed, 27 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
+index 268ca998443af..5e86038f2ea5f 100644
+--- a/drivers/pci/pci-acpi.c
++++ b/drivers/pci/pci-acpi.c
+@@ -245,21 +245,6 @@ static acpi_status decode_type1_hpx_record(union acpi_object *record,
+       return AE_OK;
+ }
+-static bool pcie_root_rcb_set(struct pci_dev *dev)
+-{
+-      struct pci_dev *rp = pcie_find_root_port(dev);
+-      u16 lnkctl;
+-
+-      if (!rp)
+-              return false;
+-
+-      pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &lnkctl);
+-      if (lnkctl & PCI_EXP_LNKCTL_RCB)
+-              return true;
+-
+-      return false;
+-}
+-
+ /* _HPX PCI Express Setting Record (Type 2) */
+ struct hpx_type2 {
+       u32 revision;
+@@ -285,6 +270,7 @@ static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
+ {
+       int pos;
+       u32 reg32;
++      const struct pci_host_bridge *host;
+       if (!hpx)
+               return;
+@@ -292,6 +278,15 @@ static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
+       if (!pci_is_pcie(dev))
+               return;
++      host = pci_find_host_bridge(dev->bus);
++
++      /*
++       * Only do the _HPX Type 2 programming if OS owns PCIe native
++       * hotplug but not AER.
++       */
++      if (!host->native_pcie_hotplug || host->native_aer)
++              return;
++
+       if (hpx->revision > 1) {
+               pci_warn(dev, "PCIe settings rev %d not supported\n",
+                        hpx->revision);
+@@ -299,33 +294,27 @@ static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
+       }
+       /*
+-       * Don't allow _HPX to change MPS or MRRS settings.  We manage
+-       * those to make sure they're consistent with the rest of the
+-       * platform.
++       * We only allow _HPX to program DEVCTL bits related to AER, namely
++       * PCI_EXP_DEVCTL_CERE, PCI_EXP_DEVCTL_NFERE, PCI_EXP_DEVCTL_FERE,
++       * and PCI_EXP_DEVCTL_URRE.
++       *
++       * The rest of DEVCTL is managed by the OS to make sure it's
++       * consistent with the rest of the platform.
+        */
+-      hpx->pci_exp_devctl_and |= PCI_EXP_DEVCTL_PAYLOAD |
+-                                  PCI_EXP_DEVCTL_READRQ;
+-      hpx->pci_exp_devctl_or &= ~(PCI_EXP_DEVCTL_PAYLOAD |
+-                                  PCI_EXP_DEVCTL_READRQ);
++      hpx->pci_exp_devctl_and |= ~PCI_EXP_AER_FLAGS;
++      hpx->pci_exp_devctl_or &= PCI_EXP_AER_FLAGS;
+       /* Initialize Device Control Register */
+       pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
+                       ~hpx->pci_exp_devctl_and, hpx->pci_exp_devctl_or);
+-      /* Initialize Link Control Register */
++      /* Log if _HPX attempts to modify Link Control Register */
+       if (pcie_cap_has_lnkctl(dev)) {
+-
+-              /*
+-               * If the Root Port supports Read Completion Boundary of
+-               * 128, set RCB to 128.  Otherwise, clear it.
+-               */
+-              hpx->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
+-              hpx->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
+-              if (pcie_root_rcb_set(dev))
+-                      hpx->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
+-
+-              pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
+-                      ~hpx->pci_exp_lnkctl_and, hpx->pci_exp_lnkctl_or);
++              if (hpx->pci_exp_lnkctl_and != 0xffff ||
++                  hpx->pci_exp_lnkctl_or != 0)
++                      pci_info(dev, "_HPX attempts Link Control setting (AND %#06x OR %#06x)\n",
++                               hpx->pci_exp_lnkctl_and,
++                               hpx->pci_exp_lnkctl_or);
+       }
+       /* Find Advanced Error Reporting Enhanced Capability */
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+index 4a8f499d278be..adae3e04c8c30 100644
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -11,6 +11,9 @@
+ #define PCI_VSEC_ID_INTEL_TBT 0x1234  /* Thunderbolt */
++#define PCI_EXP_AER_FLAGS     (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
++                               PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
++
+ extern const unsigned char pcie_link_speed[];
+ extern bool pci_early_dump;
+diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
+index a8bec1c3c769a..9b86df5b82359 100644
+--- a/drivers/pci/pcie/aer.c
++++ b/drivers/pci/pcie/aer.c
+@@ -214,9 +214,6 @@ void pcie_ecrc_get_policy(char *str)
+ }
+ #endif        /* CONFIG_PCIE_ECRC */
+-#define       PCI_EXP_AER_FLAGS       (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
+-                               PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
+-
+ int pcie_aer_is_native(struct pci_dev *dev)
+ {
+       struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
+-- 
+2.53.0
+
diff --git a/queue-5.15/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch b/queue-5.15/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch
new file mode 100644 (file)
index 0000000..b94bad2
--- /dev/null
@@ -0,0 +1,97 @@
+From b42d9f6bff33b62ab3fe5bb81ced69dc7fcd2319 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 12:06:45 -0400
+Subject: PCI: endpoint: pci-epf-vntb: Remove duplicate resource teardown
+
+From: Koichiro Den <den@valinux.co.jp>
+
+[ Upstream commit 0da63230d3ec1ec5fcc443a2314233e95bfece54 ]
+
+epf_ntb_epc_destroy() duplicates the teardown that the caller is
+supposed to perform later. This leads to an oops when .allow_link fails
+or when .drop_link is performed. The following is an example oops of the
+former case:
+
+  Unable to handle kernel paging request at virtual address dead000000000108
+  [...]
+  [dead000000000108] address between user and kernel address ranges
+  Internal error: Oops: 0000000096000044 [#1]  SMP
+  [...]
+  Call trace:
+   pci_epc_remove_epf+0x78/0xe0 (P)
+   pci_primary_epc_epf_link+0x88/0xa8
+   configfs_symlink+0x1f4/0x5a0
+   vfs_symlink+0x134/0x1d8
+   do_symlinkat+0x88/0x138
+   __arm64_sys_symlinkat+0x74/0xe0
+  [...]
+
+Remove the helper, and drop pci_epc_put(). EPC device refcounting is
+tied to the configfs EPC group lifetime, and pci_epc_put() in the
+.drop_link path is sufficient.
+
+Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
+Signed-off-by: Koichiro Den <den@valinux.co.jp>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260226084142.2226875-2-den@valinux.co.jp
+[ context mismatch in deletion hunk ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-vntb.c | 18 +-----------------
+ 1 file changed, 1 insertion(+), 17 deletions(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+index 45530bca50fb8..e9402b5dc8359 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
++++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+@@ -650,18 +650,6 @@ static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb)
+       }
+ }
+-/**
+- * epf_ntb_epc_destroy() - Cleanup NTB EPC interface
+- * @ntb: NTB device that facilitates communication between HOST and vHOST
+- *
+- * Wrapper for epf_ntb_epc_destroy_interface() to cleanup all the NTB interfaces
+- */
+-static void epf_ntb_epc_destroy(struct epf_ntb *ntb)
+-{
+-      pci_epc_remove_epf(ntb->epf->epc, ntb->epf, 0);
+-      pci_epc_put(ntb->epf->epc);
+-}
+-
+ /**
+  * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
+  * constructs (scratchpad region, doorbell, memorywindow)
+@@ -1289,7 +1277,7 @@ static int epf_ntb_bind(struct pci_epf *epf)
+       ret = epf_ntb_init_epc_bar(ntb);
+       if (ret) {
+               dev_err(dev, "Failed to create NTB EPC\n");
+-              goto err_bar_init;
++              return ret;
+       }
+       ret = epf_ntb_config_spad_bar_alloc(ntb);
+@@ -1326,9 +1314,6 @@ static int epf_ntb_bind(struct pci_epf *epf)
+ err_bar_alloc:
+       epf_ntb_config_spad_bar_free(ntb);
+-err_bar_init:
+-      epf_ntb_epc_destroy(ntb);
+-
+       return ret;
+ }
+@@ -1344,7 +1329,6 @@ static void epf_ntb_unbind(struct pci_epf *epf)
+       epf_ntb_epc_cleanup(ntb);
+       epf_ntb_config_spad_bar_free(ntb);
+-      epf_ntb_epc_destroy(ntb);
+       pci_unregister_driver(&vntb_pci_driver);
+ }
+-- 
+2.53.0
+
diff --git a/queue-5.15/revert-net-ethernet-xscale-check-for-ptp-support-pro.patch b/queue-5.15/revert-net-ethernet-xscale-check-for-ptp-support-pro.patch
new file mode 100644 (file)
index 0000000..f9f3a4f
--- /dev/null
@@ -0,0 +1,53 @@
+From aca3e71aad71148dfc040f9eaa5c5d168f0607f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Apr 2026 13:17:31 -0400
+Subject: Revert "net: ethernet: xscale: Check for PTP support properly"
+
+This reverts commit 144dde3146985b25fa84d4e4b7c3d11e0f5fc5a4.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xscale/ixp4xx_eth.c | 5 ++++-
+ drivers/net/ethernet/xscale/ptp_ixp46x.c | 3 ---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+index ad6384a1e6b21..9951006f1bc77 100644
+--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
++++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+@@ -380,6 +380,9 @@ static int ixp4xx_hwtstamp_set(struct net_device *netdev,
+       int ret;
+       int ch;
++      if (!cpu_is_ixp46x())
++              return -EOPNOTSUPP;
++
+       if (!netif_running(netdev))
+               return -EINVAL;
+@@ -388,7 +391,7 @@ static int ixp4xx_hwtstamp_set(struct net_device *netdev,
+       ret = ixp46x_ptp_find(&port->timesync_regs, &port->phc_index);
+       if (ret)
+-              return -EOPNOTSUPP;
++              return ret;
+       ch = PORT2CHANNEL(port);
+       regs = port->timesync_regs;
+diff --git a/drivers/net/ethernet/xscale/ptp_ixp46x.c b/drivers/net/ethernet/xscale/ptp_ixp46x.c
+index 422946c1e65b7..20f6aa508003b 100644
+--- a/drivers/net/ethernet/xscale/ptp_ixp46x.c
++++ b/drivers/net/ethernet/xscale/ptp_ixp46x.c
+@@ -244,9 +244,6 @@ static struct ixp_clock ixp_clock;
+ int ixp46x_ptp_find(struct ixp46x_ts_regs *__iomem *regs, int *phc_index)
+ {
+-      if (!cpu_is_ixp46x())
+-              return -ENODEV;
+-
+       *regs = ixp_clock.regs;
+       *phc_index = ptp_clock_index(ixp_clock.ptp_clock);
+-- 
+2.53.0
+
diff --git a/queue-5.15/revert-net-ixp4xx_eth-convert-to-ndo_hwtstamp_get-an.patch b/queue-5.15/revert-net-ixp4xx_eth-convert-to-ndo_hwtstamp_get-an.patch
new file mode 100644 (file)
index 0000000..2b1e8a5
--- /dev/null
@@ -0,0 +1,149 @@
+From fc659850e3d20ec10c0737bfb2efdd0f381a17de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Apr 2026 13:17:38 -0400
+Subject: Revert "net: ixp4xx_eth: convert to ndo_hwtstamp_get() and
+ ndo_hwtstamp_set()"
+
+This reverts commit 612c622ab8efe9033a33eaad874ae69c090a53e1.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xscale/ixp4xx_eth.c | 61 +++++++++++++-----------
+ 1 file changed, 32 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+index 9951006f1bc77..931494cc1c39e 100644
+--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
++++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+@@ -371,20 +371,16 @@ static void ixp_tx_timestamp(struct port *port, struct sk_buff *skb)
+       __raw_writel(TX_SNAPSHOT_LOCKED, &regs->channel[ch].ch_event);
+ }
+-static int ixp4xx_hwtstamp_set(struct net_device *netdev,
+-                             struct kernel_hwtstamp_config *cfg,
+-                             struct netlink_ext_ack *extack)
++static int hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
+ {
++      struct hwtstamp_config cfg;
+       struct ixp46x_ts_regs *regs;
+       struct port *port = netdev_priv(netdev);
+       int ret;
+       int ch;
+-      if (!cpu_is_ixp46x())
+-              return -EOPNOTSUPP;
+-
+-      if (!netif_running(netdev))
+-              return -EINVAL;
++      if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
++              return -EFAULT;
+       if (cfg.flags) /* reserved for future extensions */
+               return -EINVAL;
+@@ -396,10 +392,10 @@ static int ixp4xx_hwtstamp_set(struct net_device *netdev,
+       ch = PORT2CHANNEL(port);
+       regs = port->timesync_regs;
+-      if (cfg->tx_type != HWTSTAMP_TX_OFF && cfg->tx_type != HWTSTAMP_TX_ON)
++      if (cfg.tx_type != HWTSTAMP_TX_OFF && cfg.tx_type != HWTSTAMP_TX_ON)
+               return -ERANGE;
+-      switch (cfg->rx_filter) {
++      switch (cfg.rx_filter) {
+       case HWTSTAMP_FILTER_NONE:
+               port->hwts_rx_en = 0;
+               break;
+@@ -415,45 +411,39 @@ static int ixp4xx_hwtstamp_set(struct net_device *netdev,
+               return -ERANGE;
+       }
+-      port->hwts_tx_en = cfg->tx_type == HWTSTAMP_TX_ON;
++      port->hwts_tx_en = cfg.tx_type == HWTSTAMP_TX_ON;
+       /* Clear out any old time stamps. */
+       __raw_writel(TX_SNAPSHOT_LOCKED | RX_SNAPSHOT_LOCKED,
+                    &regs->channel[ch].ch_event);
+-      return 0;
++      return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+ }
+-static int ixp4xx_hwtstamp_get(struct net_device *netdev,
+-                             struct kernel_hwtstamp_config *cfg)
++static int hwtstamp_get(struct net_device *netdev, struct ifreq *ifr)
+ {
++      struct hwtstamp_config cfg;
+       struct port *port = netdev_priv(netdev);
+-      if (!cpu_is_ixp46x())
+-              return -EOPNOTSUPP;
+-
+-      if (!netif_running(netdev))
+-              return -EINVAL;
+-
+-      cfg->flags = 0;
+-      cfg->tx_type = port->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
++      cfg.flags = 0;
++      cfg.tx_type = port->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+       switch (port->hwts_rx_en) {
+       case 0:
+-              cfg->rx_filter = HWTSTAMP_FILTER_NONE;
++              cfg.rx_filter = HWTSTAMP_FILTER_NONE;
+               break;
+       case PTP_SLAVE_MODE:
+-              cfg->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
++              cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
+               break;
+       case PTP_MASTER_MODE:
+-              cfg->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
++              cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               return -ERANGE;
+       }
+-      return 0;
++      return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+ }
+ static int ixp4xx_mdio_cmd(struct mii_bus *bus, int phy_id, int location,
+@@ -975,6 +965,21 @@ static void eth_set_mcast_list(struct net_device *dev)
+ }
++static int eth_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
++{
++      if (!netif_running(dev))
++              return -EINVAL;
++
++      if (cpu_is_ixp46x()) {
++              if (cmd == SIOCSHWTSTAMP)
++                      return hwtstamp_set(dev, req);
++              if (cmd == SIOCGHWTSTAMP)
++                      return hwtstamp_get(dev, req);
++      }
++
++      return phy_mii_ioctl(dev->phydev, req, cmd);
++}
++
+ /* ethtool support */
+ static void ixp4xx_get_drvinfo(struct net_device *dev,
+@@ -1360,11 +1365,9 @@ static const struct net_device_ops ixp4xx_netdev_ops = {
+       .ndo_stop = eth_close,
+       .ndo_start_xmit = eth_xmit,
+       .ndo_set_rx_mode = eth_set_mcast_list,
+-      .ndo_eth_ioctl = phy_do_ioctl_running,
++      .ndo_eth_ioctl = eth_ioctl,
+       .ndo_set_mac_address = eth_mac_addr,
+       .ndo_validate_addr = eth_validate_addr,
+-      .ndo_hwtstamp_get = ixp4xx_hwtstamp_get,
+-      .ndo_hwtstamp_set = ixp4xx_hwtstamp_set,
+ };
+ #ifdef CONFIG_OF
+-- 
+2.53.0
+
index 7c9839f3084c48952bea05a036c1511aafc20811..0fee0122cfdd2469e9cb985eae72c2b733acf2e5 100644 (file)
@@ -88,3 +88,12 @@ media-as102-fix-to-not-free-memory-after-the-device-is-registered-in-as102_usb_p
 nilfs2-fix-null-i_assoc_inode-dereference-in-nilfs_mdt_save_to_shadow_map.patch
 media-vidtv-fix-pass-by-value-structs-causing-msan-warnings.patch
 media-hackrf-fix-to-not-free-memory-after-the-device-is-registered-in-hackrf_probe.patch
+net-tap-null-pointer-derefence-in-dev_parse_header_p.patch
+pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch
+revert-net-ethernet-xscale-check-for-ptp-support-pro.patch
+revert-net-ixp4xx_eth-convert-to-ndo_hwtstamp_get-an.patch
+ipv6-add-null-checks-for-idev-in-srv6-paths.patch
+gfs2-improve-gfs2_consist_inode-usage.patch
+gfs2-validate-i_depth-for-exhash-directories.patch
+wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
+pci-acpi-restrict-program_hpx_type2-to-aer-bits.patch
diff --git a/queue-5.15/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch b/queue-5.15/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
new file mode 100644 (file)
index 0000000..db30e3c
--- /dev/null
@@ -0,0 +1,107 @@
+From 7f0abca43ad56902d5cde1a480e08aec8d3ed512 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 10:44:03 +0800
+Subject: wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
+
+ieee80211_tx_prepare_skb() has three error paths, but only two of them
+free the skb. The first error path (ieee80211_tx_prepare() returning
+TX_DROP) does not free it, while invoke_tx_handlers() failure and the
+fragmentation check both do.
+
+Add kfree_skb() to the first error path so all three are consistent,
+and remove the now-redundant frees in callers (ath9k, mt76,
+mac80211_hwsim) to avoid double-free.
+
+Document the skb ownership guarantee in the function's kdoc.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name
+Fixes: 06be6b149f7e ("mac80211: add ieee80211_tx_prepare_skb() helper function")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
+ introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning")
+ after linux-6.14.]
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/channel.c | 6 ++----
+ drivers/net/wireless/mac80211_hwsim.c    | 1 -
+ include/net/mac80211.h                   | 4 ++++
+ net/mac80211/tx.c                        | 4 +++-
+ 4 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
+index 6cf0875221572..31b7921bf34f3 100644
+--- a/drivers/net/wireless/ath/ath9k/channel.c
++++ b/drivers/net/wireless/ath/ath9k/channel.c
+@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
+       skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+       if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
+-              goto error;
++              return;
+       txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
+       if (ath_tx_start(sc->hw, skb, &txctl))
+@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
+               skb->priority = 7;
+               skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+-              if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
+-                      dev_kfree_skb_any(skb);
++              if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
+                       return false;
+-              }
+               break;
+       default:
+               return false;
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index 7d73502586839..ed4d83775fe70 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -2347,7 +2347,6 @@ static void hw_scan_work(struct work_struct *work)
+                                                     hwsim->tmp_chan->band,
+                                                     NULL)) {
+                               rcu_read_unlock();
+-                              kfree_skb(probe);
+                               continue;
+                       }
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index f101ef4a1fd69..a4ef9f93a53c4 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -6454,6 +6454,10 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
+  * @band: the band to transmit on
+  * @sta: optional pointer to get the station to send the frame to
+  *
++ * Return: %true if the skb was prepared, %false otherwise.
++ * On failure, the skb is freed by this function; callers must not
++ * free it again.
++ *
+  * Note: must be called under RCU lock
+  */
+ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index a5be5fe5c6b4e..0544931613763 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1882,8 +1882,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
+       struct ieee80211_tx_data tx;
+       struct sk_buff *skb2;
+-      if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
++      if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
++              kfree_skb(skb);
+               return false;
++      }
+       info->band = band;
+       info->control.vif = vif;
+-- 
+2.53.0
+
diff --git a/queue-6.1/gfs2-improve-gfs2_consist_inode-usage.patch b/queue-6.1/gfs2-improve-gfs2_consist_inode-usage.patch
new file mode 100644 (file)
index 0000000..107dabc
--- /dev/null
@@ -0,0 +1,213 @@
+From 4c15a97ba9607c8facfff8a14a4b1f66e700427b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Apr 2026 18:37:16 +0800
+Subject: gfs2: Improve gfs2_consist_inode() usage
+
+From: Andrew Price <anprice@redhat.com>
+
+[ Upstream commit 10398ef57aa189153406c110f5957145030f08fe ]
+
+gfs2_consist_inode() logs an error message with the source file and line
+number. When we jump before calling it, the line number becomes less
+useful as it no longer relates to the source of the error. To aid
+troubleshooting, replace the gotos with the gfs2_consist_inode() calls
+so that the error messages are more informative.
+
+Signed-off-by: Andrew Price <anprice@redhat.com>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Ruohan Lan <ruohanlan@aliyun.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/dir.c   | 31 +++++++++++++++++--------------
+ fs/gfs2/glops.c | 34 ++++++++++++++++++++--------------
+ fs/gfs2/xattr.c | 28 ++++++++++++++++------------
+ 3 files changed, 53 insertions(+), 40 deletions(-)
+
+diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
+index 54a6d17b8c252..96924af95c8ef 100644
+--- a/fs/gfs2/dir.c
++++ b/fs/gfs2/dir.c
+@@ -562,15 +562,18 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
+       int ret = 0;
+       ret = gfs2_dirent_offset(GFS2_SB(inode), buf);
+-      if (ret < 0)
+-              goto consist_inode;
+-
++      if (ret < 0) {
++              gfs2_consist_inode(GFS2_I(inode));
++              return ERR_PTR(-EIO);
++      }
+       offset = ret;
+       prev = NULL;
+       dent = buf + offset;
+       size = be16_to_cpu(dent->de_rec_len);
+-      if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, len, 1))
+-              goto consist_inode;
++      if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, len, 1)) {
++              gfs2_consist_inode(GFS2_I(inode));
++              return ERR_PTR(-EIO);
++      }
+       do {
+               ret = scan(dent, name, opaque);
+               if (ret)
+@@ -582,8 +585,10 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
+               dent = buf + offset;
+               size = be16_to_cpu(dent->de_rec_len);
+               if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size,
+-                                    len, 0))
+-                      goto consist_inode;
++                                    len, 0)) {
++                      gfs2_consist_inode(GFS2_I(inode));
++                      return ERR_PTR(-EIO);
++              }
+       } while(1);
+       switch(ret) {
+@@ -597,10 +602,6 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
+               BUG_ON(ret > 0);
+               return ERR_PTR(ret);
+       }
+-
+-consist_inode:
+-      gfs2_consist_inode(GFS2_I(inode));
+-      return ERR_PTR(-EIO);
+ }
+ static int dirent_check_reclen(struct gfs2_inode *dip,
+@@ -609,14 +610,16 @@ static int dirent_check_reclen(struct gfs2_inode *dip,
+       const void *ptr = d;
+       u16 rec_len = be16_to_cpu(d->de_rec_len);
+-      if (unlikely(rec_len < sizeof(struct gfs2_dirent)))
+-              goto broken;
++      if (unlikely(rec_len < sizeof(struct gfs2_dirent))) {
++              gfs2_consist_inode(dip);
++              return -EIO;
++      }
+       ptr += rec_len;
+       if (ptr < end_p)
+               return rec_len;
+       if (ptr == end_p)
+               return -ENOENT;
+-broken:
++
+       gfs2_consist_inode(dip);
+       return -EIO;
+ }
+diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
+index bb5bc32a5eea5..f4bd487a9b3b0 100644
+--- a/fs/gfs2/glops.c
++++ b/fs/gfs2/glops.c
+@@ -404,10 +404,14 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
+       struct inode *inode = &ip->i_inode;
+       bool is_new = inode->i_state & I_NEW;
+-      if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
+-              goto corrupt;
+-      if (unlikely(!is_new && inode_wrong_type(inode, mode)))
+-              goto corrupt;
++      if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
++      if (unlikely(!is_new && inode_wrong_type(inode, mode))) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
+       ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
+       inode->i_mode = mode;
+       if (is_new) {
+@@ -443,26 +447,28 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
+       /* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */
+       gfs2_set_inode_flags(inode);
+       height = be16_to_cpu(str->di_height);
+-      if (unlikely(height > sdp->sd_max_height))
+-              goto corrupt;
++      if (unlikely(height > sdp->sd_max_height)) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
+       ip->i_height = (u8)height;
+       depth = be16_to_cpu(str->di_depth);
+-      if (unlikely(depth > GFS2_DIR_MAX_DEPTH))
+-              goto corrupt;
++      if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
+       ip->i_depth = (u8)depth;
+       ip->i_entries = be32_to_cpu(str->di_entries);
+-      if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip))
+-              goto corrupt;
+-
++      if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip)) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
+       if (S_ISREG(inode->i_mode))
+               gfs2_set_aops(inode);
+       return 0;
+-corrupt:
+-      gfs2_consist_inode(ip);
+-      return -EIO;
+ }
+ /**
+diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
+index f6a66050380e9..6590aad6720b4 100644
+--- a/fs/gfs2/xattr.c
++++ b/fs/gfs2/xattr.c
+@@ -96,30 +96,34 @@ static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
+               return -EIO;
+       for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
+-              if (!GFS2_EA_REC_LEN(ea))
+-                      goto fail;
++              if (!GFS2_EA_REC_LEN(ea)) {
++                      gfs2_consist_inode(ip);
++                      return -EIO;
++              }
+               if (!(bh->b_data <= (char *)ea && (char *)GFS2_EA2NEXT(ea) <=
+-                                                bh->b_data + bh->b_size))
+-                      goto fail;
+-              if (!gfs2_eatype_valid(sdp, ea->ea_type))
+-                      goto fail;
++                                                bh->b_data + bh->b_size)) {
++                      gfs2_consist_inode(ip);
++                      return -EIO;
++              }
++              if (!gfs2_eatype_valid(sdp, ea->ea_type)) {
++                      gfs2_consist_inode(ip);
++                      return -EIO;
++              }
+               error = ea_call(ip, bh, ea, prev, data);
+               if (error)
+                       return error;
+               if (GFS2_EA_IS_LAST(ea)) {
+                       if ((char *)GFS2_EA2NEXT(ea) !=
+-                          bh->b_data + bh->b_size)
+-                              goto fail;
++                          bh->b_data + bh->b_size) {
++                              gfs2_consist_inode(ip);
++                              return -EIO;
++                      }
+                       break;
+               }
+       }
+       return error;
+-
+-fail:
+-      gfs2_consist_inode(ip);
+-      return -EIO;
+ }
+ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
+-- 
+2.53.0
+
diff --git a/queue-6.1/gfs2-validate-i_depth-for-exhash-directories.patch b/queue-6.1/gfs2-validate-i_depth-for-exhash-directories.patch
new file mode 100644 (file)
index 0000000..4657065
--- /dev/null
@@ -0,0 +1,95 @@
+From 84ed1e95085fe049c908d7d7bedba8ea2ebc1e99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Apr 2026 18:37:17 +0800
+Subject: gfs2: Validate i_depth for exhash directories
+
+From: Andrew Price <anprice@redhat.com>
+
+[ Upstream commit 557c024ca7250bb65ae60f16c02074106c2f197b ]
+
+A fuzzer test introduced corruption that ends up with a depth of 0 in
+dir_e_read(), causing an undefined shift by 32 at:
+
+  index = hash >> (32 - dip->i_depth);
+
+As calculated in an open-coded way in dir_make_exhash(), the minimum
+depth for an exhash directory is ilog2(sdp->sd_hash_ptrs) and 0 is
+invalid as sdp->sd_hash_ptrs is fixed as sdp->bsize / 16 at mount time.
+
+So we can avoid the undefined behaviour by checking for depth values
+lower than the minimum in gfs2_dinode_in(). Values greater than the
+maximum are already being checked for there.
+
+Also switch the calculation in dir_make_exhash() to use ilog2() to
+clarify how the depth is calculated.
+
+Tested with the syzkaller repro.c and xfstests '-g quick'.
+
+Reported-by: syzbot+4708579bb230a0582a57@syzkaller.appspotmail.com
+Signed-off-by: Andrew Price <anprice@redhat.com>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Ruohan Lan <ruohanlan@aliyun.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/dir.c   | 6 ++----
+ fs/gfs2/glops.c | 6 ++++++
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
+index 96924af95c8ef..3716d89d8af6f 100644
+--- a/fs/gfs2/dir.c
++++ b/fs/gfs2/dir.c
+@@ -60,6 +60,7 @@
+ #include <linux/crc32.h>
+ #include <linux/vmalloc.h>
+ #include <linux/bio.h>
++#include <linux/log2.h>
+ #include "gfs2.h"
+ #include "incore.h"
+@@ -912,7 +913,6 @@ static int dir_make_exhash(struct inode *inode)
+       struct qstr args;
+       struct buffer_head *bh, *dibh;
+       struct gfs2_leaf *leaf;
+-      int y;
+       u32 x;
+       __be64 *lp;
+       u64 bn;
+@@ -979,9 +979,7 @@ static int dir_make_exhash(struct inode *inode)
+       i_size_write(inode, sdp->sd_sb.sb_bsize / 2);
+       gfs2_add_inode_blocks(&dip->i_inode, 1);
+       dip->i_diskflags |= GFS2_DIF_EXHASH;
+-
+-      for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ;
+-      dip->i_depth = y;
++      dip->i_depth = ilog2(sdp->sd_hash_ptrs);
+       gfs2_dinode_out(dip, dibh->b_data);
+diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
+index f4bd487a9b3b0..e7904c1c985f6 100644
+--- a/fs/gfs2/glops.c
++++ b/fs/gfs2/glops.c
+@@ -11,6 +11,7 @@
+ #include <linux/bio.h>
+ #include <linux/posix_acl.h>
+ #include <linux/security.h>
++#include <linux/log2.h>
+ #include "gfs2.h"
+ #include "incore.h"
+@@ -458,6 +459,11 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
+               gfs2_consist_inode(ip);
+               return -EIO;
+       }
++      if ((ip->i_diskflags & GFS2_DIF_EXHASH) &&
++          depth < ilog2(sdp->sd_hash_ptrs)) {
++              gfs2_consist_inode(ip);
++              return -EIO;
++      }
+       ip->i_depth = (u8)depth;
+       ip->i_entries = be32_to_cpu(str->di_entries);
+-- 
+2.53.0
+
diff --git a/queue-6.1/ipv6-add-null-checks-for-idev-in-srv6-paths.patch b/queue-6.1/ipv6-add-null-checks-for-idev-in-srv6-paths.patch
new file mode 100644 (file)
index 0000000..7bbc478
--- /dev/null
@@ -0,0 +1,60 @@
+From b5e751308ea27a5fdd5d7a46dc4e18af545dde0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 13:43:09 +0800
+Subject: ipv6: add NULL checks for idev in SRv6 paths
+
+From: Minhong He <heminhong@kylinos.cn>
+
+[ Upstream commit 06413793526251870e20402c39930804f14d59c0 ]
+
+__in6_dev_get() can return NULL when the device has no IPv6 configuration
+(e.g. MTU < IPV6_MIN_MTU or after NETDEV_UNREGISTER).
+
+Add NULL checks for idev returned by __in6_dev_get() in both
+seg6_hmac_validate_skb() and ipv6_srh_rcv() to prevent potential NULL
+pointer dereferences.
+
+Fixes: 1ababeba4a21 ("ipv6: implement dataplane support for rthdr type 4 (Segment Routing Header)")
+Fixes: bf355b8d2c30 ("ipv6: sr: add core files for SR HMAC support")
+Signed-off-by: Minhong He <heminhong@kylinos.cn>
+Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it>
+Link: https://patch.msgid.link/20260316073301.106643-1-heminhong@kylinos.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c   | 4 ++++
+ net/ipv6/seg6_hmac.c | 2 ++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 61e0060185f4b..5fb97a87d2cb5 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -381,6 +381,10 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
+       hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
+       idev = __in6_dev_get(skb->dev);
++      if (!idev) {
++              kfree_skb(skb);
++              return -1;
++      }
+       accept_seg6 = net->ipv6.devconf_all->seg6_enabled;
+       if (accept_seg6 > idev->cnf.seg6_enabled)
+diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
+index b90c286d77ed4..e784f539194ad 100644
+--- a/net/ipv6/seg6_hmac.c
++++ b/net/ipv6/seg6_hmac.c
+@@ -244,6 +244,8 @@ bool seg6_hmac_validate_skb(struct sk_buff *skb)
+       struct inet6_dev *idev;
+       idev = __in6_dev_get(skb->dev);
++      if (!idev)
++              return false;
+       srh = (struct ipv6_sr_hdr *)skb_transport_header(skb);
+-- 
+2.53.0
+
diff --git a/queue-6.1/net-dsa-clean-up-fdb-mdb-vlan-entries-on-unbind.patch b/queue-6.1/net-dsa-clean-up-fdb-mdb-vlan-entries-on-unbind.patch
new file mode 100644 (file)
index 0000000..9146e37
--- /dev/null
@@ -0,0 +1,121 @@
+From 3958a276a473db5c8c6aa7e3167a3898a66a182c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 15:36:35 +0800
+Subject: net: dsa: clean up FDB, MDB, VLAN entries on unbind
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 7afb5fb42d4950f33af2732b8147c552659f79b7 ]
+
+As explained in many places such as commit b117e1e8a86d ("net: dsa:
+delete dsa_legacy_fdb_add and dsa_legacy_fdb_del"), DSA is written given
+the assumption that higher layers have balanced additions/deletions.
+As such, it only makes sense to be extremely vocal when those
+assumptions are violated and the driver unbinds with entries still
+present.
+
+But Ido Schimmel points out a very simple situation where that is wrong:
+https://lore.kernel.org/netdev/ZDazSM5UsPPjQuKr@shredder/
+(also briefly discussed by me in the aforementioned commit).
+
+Basically, while the bridge bypass operations are not something that DSA
+explicitly documents, and for the majority of DSA drivers this API
+simply causes them to go to promiscuous mode, that isn't the case for
+all drivers. Some have the necessary requirements for bridge bypass
+operations to do something useful - see dsa_switch_supports_uc_filtering().
+
+Although in tools/testing/selftests/net/forwarding/local_termination.sh,
+we made an effort to popularize better mechanisms to manage address
+filters on DSA interfaces from user space - namely macvlan for unicast,
+and setsockopt(IP_ADD_MEMBERSHIP) - through mtools - for multicast, the
+fact is that 'bridge fdb add ... self static local' also exists as
+kernel UAPI, and might be useful to someone, even if only for a quick
+hack.
+
+It seems counter-productive to block that path by implementing shim
+.ndo_fdb_add and .ndo_fdb_del operations which just return -EOPNOTSUPP
+in order to prevent the ndo_dflt_fdb_add() and ndo_dflt_fdb_del() from
+running, although we could do that.
+
+Accepting that cleanup is necessary seems to be the only option.
+Especially since we appear to be coming back at this from a different
+angle as well. Russell King is noticing that the WARN_ON() triggers even
+for VLANs:
+https://lore.kernel.org/netdev/Z_li8Bj8bD4-BYKQ@shell.armlinux.org.uk/
+
+What happens in the bug report above is that dsa_port_do_vlan_del() fails,
+then the VLAN entry lingers on, and then we warn on unbind and leak it.
+
+This is not a straight revert of the blamed commit, but we now add an
+informational print to the kernel log (to still have a way to see
+that bugs exist), and some extra comments gathered from past years'
+experience, to justify the logic.
+
+Fixes: 0832cd9f1f02 ("net: dsa: warn if port lists aren't empty in dsa_port_teardown")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250414212930.2956310-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Apply the patch to net/dsa/dsa2.c in v6.1 since commit
+47d2ce03dcfb ("net: dsa: rename dsa2.c back into dsa.c and create its header")
+renamed this file to net/dsa/dsa.c starting from v6.2. ]
+Signed-off-by: Alva Lan <alvalan9@foxmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dsa/dsa2.c | 38 +++++++++++++++++++++++++++++++++++---
+ 1 file changed, 35 insertions(+), 3 deletions(-)
+
+diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
+index 415e856ba0acf..9ecb5e34e484e 100644
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -1738,12 +1738,44 @@ static int dsa_switch_parse(struct dsa_switch *ds, struct dsa_chip_data *cd)
+ static void dsa_switch_release_ports(struct dsa_switch *ds)
+ {
++      struct dsa_mac_addr *a, *tmp;
+       struct dsa_port *dp, *next;
++      struct dsa_vlan *v, *n;
+       dsa_switch_for_each_port_safe(dp, next, ds) {
+-              WARN_ON(!list_empty(&dp->fdbs));
+-              WARN_ON(!list_empty(&dp->mdbs));
+-              WARN_ON(!list_empty(&dp->vlans));
++              /* These are either entries that upper layers lost track of
++               * (probably due to bugs), or installed through interfaces
++               * where one does not necessarily have to remove them, like
++               * ndo_dflt_fdb_add().
++               */
++              list_for_each_entry_safe(a, tmp, &dp->fdbs, list) {
++                      dev_info(ds->dev,
++                               "Cleaning up unicast address %pM vid %u from port %d\n",
++                               a->addr, a->vid, dp->index);
++                      list_del(&a->list);
++                      kfree(a);
++              }
++
++              list_for_each_entry_safe(a, tmp, &dp->mdbs, list) {
++                      dev_info(ds->dev,
++                               "Cleaning up multicast address %pM vid %u from port %d\n",
++                               a->addr, a->vid, dp->index);
++                      list_del(&a->list);
++                      kfree(a);
++              }
++
++              /* These are entries that upper layers have lost track of,
++               * probably due to bugs, but also due to dsa_port_do_vlan_del()
++               * having failed and the VLAN entry still lingering on.
++               */
++              list_for_each_entry_safe(v, n, &dp->vlans, list) {
++                      dev_info(ds->dev,
++                               "Cleaning up vid %u from port %d\n",
++                               v->vid, dp->index);
++                      list_del(&v->list);
++                      kfree(v);
++              }
++
+               list_del(&dp->list);
+               kfree(dp);
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.1/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch b/queue-6.1/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch
new file mode 100644 (file)
index 0000000..c9fdc20
--- /dev/null
@@ -0,0 +1,97 @@
+From 05271a53447a15e48b5de20736beca47e7205a9c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 10:58:35 -0400
+Subject: PCI: endpoint: pci-epf-vntb: Remove duplicate resource teardown
+
+From: Koichiro Den <den@valinux.co.jp>
+
+[ Upstream commit 0da63230d3ec1ec5fcc443a2314233e95bfece54 ]
+
+epf_ntb_epc_destroy() duplicates the teardown that the caller is
+supposed to perform later. This leads to an oops when .allow_link fails
+or when .drop_link is performed. The following is an example oops of the
+former case:
+
+  Unable to handle kernel paging request at virtual address dead000000000108
+  [...]
+  [dead000000000108] address between user and kernel address ranges
+  Internal error: Oops: 0000000096000044 [#1]  SMP
+  [...]
+  Call trace:
+   pci_epc_remove_epf+0x78/0xe0 (P)
+   pci_primary_epc_epf_link+0x88/0xa8
+   configfs_symlink+0x1f4/0x5a0
+   vfs_symlink+0x134/0x1d8
+   do_symlinkat+0x88/0x138
+   __arm64_sys_symlinkat+0x74/0xe0
+  [...]
+
+Remove the helper, and drop pci_epc_put(). EPC device refcounting is
+tied to the configfs EPC group lifetime, and pci_epc_put() in the
+.drop_link path is sufficient.
+
+Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
+Signed-off-by: Koichiro Den <den@valinux.co.jp>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260226084142.2226875-2-den@valinux.co.jp
+[ adjusted context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-vntb.c | 18 +-----------------
+ 1 file changed, 1 insertion(+), 17 deletions(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+index d057537781f60..eee49a3eec04c 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
++++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+@@ -676,18 +676,6 @@ static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb, int num_mws)
+       }
+ }
+-/**
+- * epf_ntb_epc_destroy() - Cleanup NTB EPC interface
+- * @ntb: NTB device that facilitates communication between HOST and VHOST
+- *
+- * Wrapper for epf_ntb_epc_destroy_interface() to cleanup all the NTB interfaces
+- */
+-static void epf_ntb_epc_destroy(struct epf_ntb *ntb)
+-{
+-      pci_epc_remove_epf(ntb->epf->epc, ntb->epf, 0);
+-      pci_epc_put(ntb->epf->epc);
+-}
+-
+ /**
+  * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
+  * constructs (scratchpad region, doorbell, memorywindow)
+@@ -1331,7 +1319,7 @@ static int epf_ntb_bind(struct pci_epf *epf)
+       ret = epf_ntb_init_epc_bar(ntb);
+       if (ret) {
+               dev_err(dev, "Failed to create NTB EPC\n");
+-              goto err_bar_init;
++              return ret;
+       }
+       ret = epf_ntb_config_spad_bar_alloc(ntb);
+@@ -1371,9 +1359,6 @@ static int epf_ntb_bind(struct pci_epf *epf)
+ err_bar_alloc:
+       epf_ntb_config_spad_bar_free(ntb);
+-err_bar_init:
+-      epf_ntb_epc_destroy(ntb);
+-
+       return ret;
+ }
+@@ -1389,7 +1374,6 @@ static void epf_ntb_unbind(struct pci_epf *epf)
+       epf_ntb_epc_cleanup(ntb);
+       epf_ntb_config_spad_bar_free(ntb);
+-      epf_ntb_epc_destroy(ntb);
+       pci_unregister_driver(&vntb_pci_driver);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.1/revert-net-ethernet-xscale-check-for-ptp-support-pro.patch b/queue-6.1/revert-net-ethernet-xscale-check-for-ptp-support-pro.patch
new file mode 100644 (file)
index 0000000..52b50e6
--- /dev/null
@@ -0,0 +1,51 @@
+From 77d8aa732776b13c2e9b95abb2a0bff4e9b638ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Apr 2026 13:19:24 -0400
+Subject: Revert "net: ethernet: xscale: Check for PTP support properly"
+
+This reverts commit 5195b10c34b8993194ad12ad7d8f54d861be084b.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xscale/ixp4xx_eth.c | 5 ++++-
+ drivers/net/ethernet/xscale/ptp_ixp46x.c | 3 ---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+index aa6d30dd35c38..a5e03e66cfd38 100644
+--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
++++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+@@ -395,12 +395,15 @@ static int ixp4xx_hwtstamp_set(struct net_device *netdev,
+       int ret;
+       int ch;
++      if (!cpu_is_ixp46x())
++              return -EOPNOTSUPP;
++
+       if (!netif_running(netdev))
+               return -EINVAL;
+       ret = ixp46x_ptp_find(&port->timesync_regs, &port->phc_index);
+       if (ret)
+-              return -EOPNOTSUPP;
++              return ret;
+       ch = PORT2CHANNEL(port);
+       regs = port->timesync_regs;
+diff --git a/drivers/net/ethernet/xscale/ptp_ixp46x.c b/drivers/net/ethernet/xscale/ptp_ixp46x.c
+index b8953745a9f2e..9abbdb71e629f 100644
+--- a/drivers/net/ethernet/xscale/ptp_ixp46x.c
++++ b/drivers/net/ethernet/xscale/ptp_ixp46x.c
+@@ -243,9 +243,6 @@ static struct ixp_clock ixp_clock;
+ int ixp46x_ptp_find(struct ixp46x_ts_regs *__iomem *regs, int *phc_index)
+ {
+-      if (!cpu_is_ixp46x())
+-              return -ENODEV;
+-
+       *regs = ixp_clock.regs;
+       *phc_index = ptp_clock_index(ixp_clock.ptp_clock);
+-- 
+2.53.0
+
diff --git a/queue-6.1/revert-net-ixp4xx_eth-convert-to-ndo_hwtstamp_get-an.patch b/queue-6.1/revert-net-ixp4xx_eth-convert-to-ndo_hwtstamp_get-an.patch
new file mode 100644 (file)
index 0000000..c0a946b
--- /dev/null
@@ -0,0 +1,149 @@
+From 026608f6b33a21b890efc5e47052019b4e4bc467 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Apr 2026 13:19:24 -0400
+Subject: Revert "net: ixp4xx_eth: convert to ndo_hwtstamp_get() and
+ ndo_hwtstamp_set()"
+
+This reverts commit a94d5447f6bf827bc29be2520ca636685bbc29e6.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/xscale/ixp4xx_eth.c | 61 +++++++++++++-----------
+ 1 file changed, 32 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+index a5e03e66cfd38..3b0c5f177447b 100644
+--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
++++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
+@@ -386,20 +386,16 @@ static void ixp_tx_timestamp(struct port *port, struct sk_buff *skb)
+       __raw_writel(TX_SNAPSHOT_LOCKED, &regs->channel[ch].ch_event);
+ }
+-static int ixp4xx_hwtstamp_set(struct net_device *netdev,
+-                             struct kernel_hwtstamp_config *cfg,
+-                             struct netlink_ext_ack *extack)
++static int hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
+ {
++      struct hwtstamp_config cfg;
+       struct ixp46x_ts_regs *regs;
+       struct port *port = netdev_priv(netdev);
+       int ret;
+       int ch;
+-      if (!cpu_is_ixp46x())
+-              return -EOPNOTSUPP;
+-
+-      if (!netif_running(netdev))
+-              return -EINVAL;
++      if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
++              return -EFAULT;
+       ret = ixp46x_ptp_find(&port->timesync_regs, &port->phc_index);
+       if (ret)
+@@ -408,10 +404,10 @@ static int ixp4xx_hwtstamp_set(struct net_device *netdev,
+       ch = PORT2CHANNEL(port);
+       regs = port->timesync_regs;
+-      if (cfg->tx_type != HWTSTAMP_TX_OFF && cfg->tx_type != HWTSTAMP_TX_ON)
++      if (cfg.tx_type != HWTSTAMP_TX_OFF && cfg.tx_type != HWTSTAMP_TX_ON)
+               return -ERANGE;
+-      switch (cfg->rx_filter) {
++      switch (cfg.rx_filter) {
+       case HWTSTAMP_FILTER_NONE:
+               port->hwts_rx_en = 0;
+               break;
+@@ -427,45 +423,39 @@ static int ixp4xx_hwtstamp_set(struct net_device *netdev,
+               return -ERANGE;
+       }
+-      port->hwts_tx_en = cfg->tx_type == HWTSTAMP_TX_ON;
++      port->hwts_tx_en = cfg.tx_type == HWTSTAMP_TX_ON;
+       /* Clear out any old time stamps. */
+       __raw_writel(TX_SNAPSHOT_LOCKED | RX_SNAPSHOT_LOCKED,
+                    &regs->channel[ch].ch_event);
+-      return 0;
++      return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+ }
+-static int ixp4xx_hwtstamp_get(struct net_device *netdev,
+-                             struct kernel_hwtstamp_config *cfg)
++static int hwtstamp_get(struct net_device *netdev, struct ifreq *ifr)
+ {
++      struct hwtstamp_config cfg;
+       struct port *port = netdev_priv(netdev);
+-      if (!cpu_is_ixp46x())
+-              return -EOPNOTSUPP;
+-
+-      if (!netif_running(netdev))
+-              return -EINVAL;
+-
+-      cfg->flags = 0;
+-      cfg->tx_type = port->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
++      cfg.flags = 0;
++      cfg.tx_type = port->hwts_tx_en ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+       switch (port->hwts_rx_en) {
+       case 0:
+-              cfg->rx_filter = HWTSTAMP_FILTER_NONE;
++              cfg.rx_filter = HWTSTAMP_FILTER_NONE;
+               break;
+       case PTP_SLAVE_MODE:
+-              cfg->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
++              cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
+               break;
+       case PTP_MASTER_MODE:
+-              cfg->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
++              cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               return -ERANGE;
+       }
+-      return 0;
++      return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+ }
+ static int ixp4xx_mdio_cmd(struct mii_bus *bus, int phy_id, int location,
+@@ -987,6 +977,21 @@ static void eth_set_mcast_list(struct net_device *dev)
+ }
++static int eth_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
++{
++      if (!netif_running(dev))
++              return -EINVAL;
++
++      if (cpu_is_ixp46x()) {
++              if (cmd == SIOCSHWTSTAMP)
++                      return hwtstamp_set(dev, req);
++              if (cmd == SIOCGHWTSTAMP)
++                      return hwtstamp_get(dev, req);
++      }
++
++      return phy_mii_ioctl(dev->phydev, req, cmd);
++}
++
+ /* ethtool support */
+ static void ixp4xx_get_drvinfo(struct net_device *dev,
+@@ -1371,11 +1376,9 @@ static const struct net_device_ops ixp4xx_netdev_ops = {
+       .ndo_stop = eth_close,
+       .ndo_start_xmit = eth_xmit,
+       .ndo_set_rx_mode = eth_set_mcast_list,
+-      .ndo_eth_ioctl = phy_do_ioctl_running,
++      .ndo_eth_ioctl = eth_ioctl,
+       .ndo_set_mac_address = eth_mac_addr,
+       .ndo_validate_addr = eth_validate_addr,
+-      .ndo_hwtstamp_get = ixp4xx_hwtstamp_get,
+-      .ndo_hwtstamp_set = ixp4xx_hwtstamp_set,
+ };
+ static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev)
+-- 
+2.53.0
+
index 23b8b1f93c12fbe0ca613004d0911920e0d134b5..d9b1ebe00133a3c9cb54df36422e371f2a474729 100644 (file)
@@ -107,3 +107,11 @@ media-as102-fix-to-not-free-memory-after-the-device-is-registered-in-as102_usb_p
 nilfs2-fix-null-i_assoc_inode-dereference-in-nilfs_mdt_save_to_shadow_map.patch
 media-vidtv-fix-pass-by-value-structs-causing-msan-warnings.patch
 media-hackrf-fix-to-not-free-memory-after-the-device-is-registered-in-hackrf_probe.patch
+pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch
+revert-net-ethernet-xscale-check-for-ptp-support-pro.patch
+revert-net-ixp4xx_eth-convert-to-ndo_hwtstamp_get-an.patch
+ipv6-add-null-checks-for-idev-in-srv6-paths.patch
+gfs2-improve-gfs2_consist_inode-usage.patch
+gfs2-validate-i_depth-for-exhash-directories.patch
+wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
+net-dsa-clean-up-fdb-mdb-vlan-entries-on-unbind.patch
diff --git a/queue-6.1/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch b/queue-6.1/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
new file mode 100644 (file)
index 0000000..7759645
--- /dev/null
@@ -0,0 +1,107 @@
+From 9f8569aacb9d3307e5a5f1cb8d48bca1ca21e82f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 10:43:52 +0800
+Subject: wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
+
+ieee80211_tx_prepare_skb() has three error paths, but only two of them
+free the skb. The first error path (ieee80211_tx_prepare() returning
+TX_DROP) does not free it, while invoke_tx_handlers() failure and the
+fragmentation check both do.
+
+Add kfree_skb() to the first error path so all three are consistent,
+and remove the now-redundant frees in callers (ath9k, mt76,
+mac80211_hwsim) to avoid double-free.
+
+Document the skb ownership guarantee in the function's kdoc.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name
+Fixes: 06be6b149f7e ("mac80211: add ieee80211_tx_prepare_skb() helper function")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
+ introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning")
+ after linux-6.14.]
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/channel.c | 6 ++----
+ drivers/net/wireless/mac80211_hwsim.c    | 1 -
+ include/net/mac80211.h                   | 4 ++++
+ net/mac80211/tx.c                        | 4 +++-
+ 4 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
+index 571062f2e82a7..ba8ec5112afe8 100644
+--- a/drivers/net/wireless/ath/ath9k/channel.c
++++ b/drivers/net/wireless/ath/ath9k/channel.c
+@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
+       skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+       if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
+-              goto error;
++              return;
+       txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
+       if (ath_tx_start(sc->hw, skb, &txctl))
+@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
+               skb->priority = 7;
+               skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+-              if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
+-                      dev_kfree_skb_any(skb);
++              if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
+                       return false;
+-              }
+               break;
+       default:
+               return false;
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index 80a2a668cfb9e..316b5f56b6e53 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -2743,7 +2743,6 @@ static void hw_scan_work(struct work_struct *work)
+                                                     hwsim->tmp_chan->band,
+                                                     NULL)) {
+                               rcu_read_unlock();
+-                              kfree_skb(probe);
+                               continue;
+                       }
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 62e0847d3793b..1769d03e6b1d4 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -6874,6 +6874,10 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
+  * @band: the band to transmit on
+  * @sta: optional pointer to get the station to send the frame to
+  *
++ * Return: %true if the skb was prepared, %false otherwise.
++ * On failure, the skb is freed by this function; callers must not
++ * free it again.
++ *
+  * Note: must be called under RCU lock
+  */
+ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 7333e43dfc354..2e99a1063e939 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1934,8 +1934,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
+       struct ieee80211_tx_data tx;
+       struct sk_buff *skb2;
+-      if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
++      if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
++              kfree_skb(skb);
+               return false;
++      }
+       info->band = band;
+       info->control.vif = vif;
+-- 
+2.53.0
+
diff --git a/queue-6.12/ima-do-not-copy-measurement-list-to-kdump-kernel.patch b/queue-6.12/ima-do-not-copy-measurement-list-to-kdump-kernel.patch
new file mode 100644 (file)
index 0000000..2e4aa9f
--- /dev/null
@@ -0,0 +1,43 @@
+From 5938f939a3a593e478a564a67aade59461d6f22e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 May 2025 07:31:29 -0700
+Subject: ima: do not copy measurement list to kdump kernel
+
+From: Steven Chen <chenste@linux.microsoft.com>
+
+[ Upstream commit fe3aebf27dc1875b2a0d13431e2e8cf3cf350cca ]
+
+Kdump kernel doesn't need IMA to do integrity measurement.
+Hence the measurement list in 1st kernel doesn't need to be copied to
+kdump kernel.
+
+Here skip allocating buffer for measurement list copying if loading
+kdump kernel. Then there won't be the later handling related to
+ima_kexec_buffer.
+
+Signed-off-by: Steven Chen <chenste@linux.microsoft.com>
+Tested-by: Baoquan He <bhe@redhat.com>
+Acked-by: Baoquan He <bhe@redhat.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/ima_kexec.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
+index cc418a7e27f20..501b952b36981 100644
+--- a/security/integrity/ima/ima_kexec.c
++++ b/security/integrity/ima/ima_kexec.c
+@@ -129,6 +129,9 @@ void ima_add_kexec_buffer(struct kimage *image)
+       size_t kexec_segment_size;
+       int ret;
++      if (image->type == KEXEC_TYPE_CRASH)
++              return;
++
+       /*
+        * Reserve an extra half page of memory for additional measurements
+        * added during the kexec load.
+-- 
+2.53.0
+
diff --git a/queue-6.12/ima-verify-if-the-segment-size-has-changed.patch b/queue-6.12/ima-verify-if-the-segment-size-has-changed.patch
new file mode 100644 (file)
index 0000000..3e0c50c
--- /dev/null
@@ -0,0 +1,53 @@
+From fdd39157a513b14430ef6908a75a286b54036671 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Apr 2025 15:25:13 -0700
+Subject: ima: verify if the segment size has changed
+
+From: Steven Chen <chenste@linux.microsoft.com>
+
+[ Upstream commit d0a00ce470e3ea19ba3b9f1c390aee739570a44a ]
+
+kexec 'load' may be called multiple times. Free and realloc the buffer
+only if the segment_size is changed from the previous kexec 'load' call.
+
+Signed-off-by: Steven Chen <chenste@linux.microsoft.com>
+Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
+Acked-by: Baoquan He <bhe@redhat.com>
+Tested-by: Stefan Berger <stefanb@linux.ibm.com> # ppc64/kvm
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/ima_kexec.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
+index c9e5b1d6b0ab8..cc418a7e27f20 100644
+--- a/security/integrity/ima/ima_kexec.c
++++ b/security/integrity/ima/ima_kexec.c
+@@ -34,6 +34,14 @@ static void ima_free_kexec_file_buf(struct seq_file *sf)
+ static int ima_alloc_kexec_file_buf(size_t segment_size)
+ {
++      /*
++       * kexec 'load' may be called multiple times.
++       * Free and realloc the buffer only if the segment_size is
++       * changed from the previous kexec 'load' call.
++       */
++      if (ima_kexec_file.buf && ima_kexec_file.size == segment_size)
++              goto out;
++
+       ima_free_kexec_file_buf(&ima_kexec_file);
+       /* segment size can't change between kexec load and execute */
+@@ -42,6 +50,8 @@ static int ima_alloc_kexec_file_buf(size_t segment_size)
+               return -ENOMEM;
+       ima_kexec_file.size = segment_size;
++
++out:
+       ima_kexec_file.read_pos = 0;
+       ima_kexec_file.count = sizeof(struct ima_kexec_hdr);    /* reserved space */
+-- 
+2.53.0
+
diff --git a/queue-6.12/mm-userfaultfd-fix-hugetlb-fault-mutex-hash-calculat.patch b/queue-6.12/mm-userfaultfd-fix-hugetlb-fault-mutex-hash-calculat.patch
new file mode 100644 (file)
index 0000000..8ffa281
--- /dev/null
@@ -0,0 +1,92 @@
+From 9e7e82bb078e1f76f5f6ad8c6742c971fde9d7c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 14:36:06 -0400
+Subject: mm/userfaultfd: fix hugetlb fault mutex hash calculation
+
+From: Jianhui Zhou <jianhuizzzzz@gmail.com>
+
+[ Upstream commit 0217c7fb4de4a40cee667eb21901f3204effe5ac ]
+
+In mfill_atomic_hugetlb(), linear_page_index() is used to calculate the
+page index for hugetlb_fault_mutex_hash().  However, linear_page_index()
+returns the index in PAGE_SIZE units, while hugetlb_fault_mutex_hash()
+expects the index in huge page units.  This mismatch means that different
+addresses within the same huge page can produce different hash values,
+leading to the use of different mutexes for the same huge page.  This can
+cause races between faulting threads, which can corrupt the reservation
+map and trigger the BUG_ON in resv_map_release().
+
+Fix this by introducing hugetlb_linear_page_index(), which returns the
+page index in huge page granularity, and using it in place of
+linear_page_index().
+
+Link: https://lkml.kernel.org/r/20260310110526.335749-1-jianhuizzzzz@gmail.com
+Fixes: a08c7193e4f1 ("mm/filemap: remove hugetlb special casing in filemap.c")
+Signed-off-by: Jianhui Zhou <jianhuizzzzz@gmail.com>
+Reported-by: syzbot+f525fd79634858f478e7@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=f525fd79634858f478e7
+Acked-by: SeongJae Park <sj@kernel.org>
+Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
+Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
+Cc: Jane Chu <jane.chu@oracle.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: JonasZhou <JonasZhou@zhaoxin.com>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: SeongJae Park <sj@kernel.org>
+Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ placed new `hugetlb_linear_page_index()` before `hstate_is_gigantic()` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/hugetlb.h | 17 +++++++++++++++++
+ mm/userfaultfd.c        |  2 +-
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index 81b69287ab3b0..32c9bc8c750c5 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -783,6 +783,23 @@ static inline unsigned huge_page_shift(struct hstate *h)
+       return h->order + PAGE_SHIFT;
+ }
++/**
++ * hugetlb_linear_page_index() - linear_page_index() but in hugetlb
++ *                             page size granularity.
++ * @vma: the hugetlb VMA
++ * @address: the virtual address within the VMA
++ *
++ * Return: the page offset within the mapping in huge page units.
++ */
++static inline pgoff_t hugetlb_linear_page_index(struct vm_area_struct *vma,
++              unsigned long address)
++{
++      struct hstate *h = hstate_vma(vma);
++
++      return ((address - vma->vm_start) >> huge_page_shift(h)) +
++              (vma->vm_pgoff >> huge_page_order(h));
++}
++
+ static inline bool hstate_is_gigantic(struct hstate *h)
+ {
+       return huge_page_order(h) > MAX_PAGE_ORDER;
+diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
+index 904095f69a6e3..9951b4f42c65a 100644
+--- a/mm/userfaultfd.c
++++ b/mm/userfaultfd.c
+@@ -573,7 +573,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb(
+                * in the case of shared pmds.  fault mutex prevents
+                * races with other faulting threads.
+                */
+-              idx = linear_page_index(dst_vma, dst_addr);
++              idx = hugetlb_linear_page_index(dst_vma, dst_addr);
+               mapping = dst_vma->vm_file->f_mapping;
+               hash = hugetlb_fault_mutex_hash(mapping, idx);
+               mutex_lock(&hugetlb_fault_mutex_table[hash]);
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch b/queue-6.12/net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch
new file mode 100644 (file)
index 0000000..e668f8a
--- /dev/null
@@ -0,0 +1,146 @@
+From 410558a6254cc5596c86fb8d864a8f87e837e0e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:11:22 +0100
+Subject: net: ethernet: mtk_eth_soc: initialize PPE per-tag-layer MTU
+ registers
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+commit 2dddb34dd0d07b01fa770eca89480a4da4f13153 upstream.
+
+The PPE enforces output frame size limits via per-tag-layer VLAN_MTU
+registers that the driver never initializes. The hardware defaults do
+not account for PPPoE overhead, causing the PPE to punt encapsulated
+frames back to the CPU instead of forwarding them.
+
+Initialize the registers at PPE start and on MTU changes using the
+maximum GMAC MTU. This is a conservative approximation -- the actual
+per-PPE requirement depends on egress path, but using the global
+maximum ensures the limits are never too small.
+
+Fixes: ba37b7caf1ed ("net: ethernet: mtk_eth_soc: add support for initializing the PPE")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://patch.msgid.link/ec995ab8ce8be423267a1cc093147a74d2eb9d82.1775789829.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++++++++++-
+ drivers/net/ethernet/mediatek/mtk_ppe.c     | 30 +++++++++++++++++++++
+ drivers/net/ethernet/mediatek/mtk_ppe.h     |  1 +
+ 3 files changed, 52 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 45d4bac984a52..7406b706fb753 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3384,12 +3384,23 @@ static int mtk_device_event(struct notifier_block *n, unsigned long event, void
+       return NOTIFY_DONE;
+ }
++static int mtk_max_gmac_mtu(struct mtk_eth *eth)
++{
++      int i, max_mtu = ETH_DATA_LEN;
++
++      for (i = 0; i < ARRAY_SIZE(eth->netdev); i++)
++              if (eth->netdev[i] && eth->netdev[i]->mtu > max_mtu)
++                      max_mtu = eth->netdev[i]->mtu;
++
++      return max_mtu;
++}
++
+ static int mtk_open(struct net_device *dev)
+ {
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
+       struct mtk_mac *target_mac;
+-      int i, err, ppe_num;
++      int i, err, ppe_num, mtu;
+       ppe_num = eth->soc->ppe_num;
+@@ -3436,6 +3447,10 @@ static int mtk_open(struct net_device *dev)
+                       mtk_gdm_config(eth, target_mac->id, gdm_config);
+               }
++              mtu = mtk_max_gmac_mtu(eth);
++              for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
++                      mtk_ppe_update_mtu(eth->ppe[i], mtu);
++
+               napi_enable(&eth->tx_napi);
+               napi_enable(&eth->rx_napi);
+               mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
+@@ -4129,6 +4144,7 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)
+       int length = new_mtu + MTK_RX_ETH_HLEN;
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
++      int max_mtu, i;
+       if (rcu_access_pointer(eth->prog) &&
+           length > MTK_PP_MAX_BUF_SIZE) {
+@@ -4139,6 +4155,10 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)
+       mtk_set_mcr_max_rx(mac, length);
+       WRITE_ONCE(dev->mtu, new_mtu);
++      max_mtu = mtk_max_gmac_mtu(eth);
++      for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
++              mtk_ppe_update_mtu(eth->ppe[i], max_mtu);
++
+       return 0;
+ }
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
+index ada852adc5f70..fa688a42a22f5 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -973,6 +973,36 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
+       }
+ }
++void mtk_ppe_update_mtu(struct mtk_ppe *ppe, int mtu)
++{
++      int base;
++      u32 val;
++
++      if (!ppe)
++              return;
++
++      /* The PPE checks output frame size against per-tag-layer MTU limits,
++       * treating PPPoE and DSA tags just like 802.1Q VLAN tags. The Linux
++       * device MTU already accounts for PPPoE (PPPOE_SES_HLEN) and DSA tag
++       * overhead, but 802.1Q VLAN tags are handled transparently without
++       * being reflected by the lower device MTU being increased by 4.
++       * Use the maximum MTU across all GMAC interfaces so that PPE output
++       * frame limits are sufficiently high regardless of which port a flow
++       * egresses through.
++       */
++      base = ETH_HLEN + mtu;
++
++      val = FIELD_PREP(MTK_PPE_VLAN_MTU0_NONE, base) |
++            FIELD_PREP(MTK_PPE_VLAN_MTU0_1TAG, base + VLAN_HLEN);
++      ppe_w32(ppe, MTK_PPE_VLAN_MTU0, val);
++
++      val = FIELD_PREP(MTK_PPE_VLAN_MTU1_2TAG,
++                       base + 2 * VLAN_HLEN) |
++            FIELD_PREP(MTK_PPE_VLAN_MTU1_3TAG,
++                       base + 3 * VLAN_HLEN);
++      ppe_w32(ppe, MTK_PPE_VLAN_MTU1, val);
++}
++
+ void mtk_ppe_start(struct mtk_ppe *ppe)
+ {
+       u32 val;
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
+index 223f709e2704f..ba85e39a155bf 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -346,6 +346,7 @@ struct mtk_ppe {
+ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
+ void mtk_ppe_deinit(struct mtk_eth *eth);
++void mtk_ppe_update_mtu(struct mtk_ppe *ppe, int mtu);
+ void mtk_ppe_start(struct mtk_ppe *ppe);
+ int mtk_ppe_stop(struct mtk_ppe *ppe);
+ int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
+-- 
+2.53.0
+
diff --git a/queue-6.12/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch b/queue-6.12/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch
new file mode 100644 (file)
index 0000000..2fb3699
--- /dev/null
@@ -0,0 +1,97 @@
+From 367c33632b188040b727d112835533313c457180 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 10:31:05 -0400
+Subject: PCI: endpoint: pci-epf-vntb: Remove duplicate resource teardown
+
+From: Koichiro Den <den@valinux.co.jp>
+
+[ Upstream commit 0da63230d3ec1ec5fcc443a2314233e95bfece54 ]
+
+epf_ntb_epc_destroy() duplicates the teardown that the caller is
+supposed to perform later. This leads to an oops when .allow_link fails
+or when .drop_link is performed. The following is an example oops of the
+former case:
+
+  Unable to handle kernel paging request at virtual address dead000000000108
+  [...]
+  [dead000000000108] address between user and kernel address ranges
+  Internal error: Oops: 0000000096000044 [#1]  SMP
+  [...]
+  Call trace:
+   pci_epc_remove_epf+0x78/0xe0 (P)
+   pci_primary_epc_epf_link+0x88/0xa8
+   configfs_symlink+0x1f4/0x5a0
+   vfs_symlink+0x134/0x1d8
+   do_symlinkat+0x88/0x138
+   __arm64_sys_symlinkat+0x74/0xe0
+  [...]
+
+Remove the helper, and drop pci_epc_put(). EPC device refcounting is
+tied to the configfs EPC group lifetime, and pci_epc_put() in the
+.drop_link path is sufficient.
+
+Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
+Signed-off-by: Koichiro Den <den@valinux.co.jp>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260226084142.2226875-2-den@valinux.co.jp
+[ adjusted context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-vntb.c | 18 +-----------------
+ 1 file changed, 1 insertion(+), 17 deletions(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+index be2277cb9b637..6875af691b2de 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
++++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+@@ -662,18 +662,6 @@ static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb, int num_mws)
+       }
+ }
+-/**
+- * epf_ntb_epc_destroy() - Cleanup NTB EPC interface
+- * @ntb: NTB device that facilitates communication between HOST and VHOST
+- *
+- * Wrapper for epf_ntb_epc_destroy_interface() to cleanup all the NTB interfaces
+- */
+-static void epf_ntb_epc_destroy(struct epf_ntb *ntb)
+-{
+-      pci_epc_remove_epf(ntb->epf->epc, ntb->epf, 0);
+-      pci_epc_put(ntb->epf->epc);
+-}
+-
+ /**
+  * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
+  * constructs (scratchpad region, doorbell, memorywindow)
+@@ -1315,7 +1303,7 @@ static int epf_ntb_bind(struct pci_epf *epf)
+       ret = epf_ntb_init_epc_bar(ntb);
+       if (ret) {
+               dev_err(dev, "Failed to create NTB EPC\n");
+-              goto err_bar_init;
++              return ret;
+       }
+       ret = epf_ntb_config_spad_bar_alloc(ntb);
+@@ -1355,9 +1343,6 @@ static int epf_ntb_bind(struct pci_epf *epf)
+ err_bar_alloc:
+       epf_ntb_config_spad_bar_free(ntb);
+-err_bar_init:
+-      epf_ntb_epc_destroy(ntb);
+-
+       return ret;
+ }
+@@ -1373,7 +1358,6 @@ static void epf_ntb_unbind(struct pci_epf *epf)
+       epf_ntb_epc_cleanup(ntb);
+       epf_ntb_config_spad_bar_free(ntb);
+-      epf_ntb_epc_destroy(ntb);
+       pci_unregister_driver(&vntb_pci_driver);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/rust-warn-on-bindgen-0.69.5-and-libclang-19.1.patch b/queue-6.12/rust-warn-on-bindgen-0.69.5-and-libclang-19.1.patch
new file mode 100644 (file)
index 0000000..c69f307
--- /dev/null
@@ -0,0 +1,194 @@
+From 0727b4a81addc1e542f9aefc24ef2bf0c3236dc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Nov 2024 21:16:07 +0100
+Subject: rust: warn on bindgen < 0.69.5 and libclang >= 19.1
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit b2603f8ac8217bc59f5c7f248ac248423b9b99cb ]
+
+When testing a `clang` upgrade with Rust Binder, Alice encountered [1] a
+build failure caused by `bindgen` not translating some symbols related to
+tracepoints. This was caused by commit 2e770edd8ce1 ("[libclang] Compute
+the right spelling location") changing the behavior of a function exposed
+by `libclang`. `bindgen` fixed the regression in commit 600f63895f73
+("Use clang_getFileLocation instead of clang_getSpellingLocation").
+
+However, the regression fix is only available in `bindgen` versions
+0.69.5 or later (it was backported for 0.69.x). This means that when
+older bindgen versions are used with new versions of `libclang`, `bindgen`
+may do the wrong thing, which could lead to a build failure.
+
+Alice encountered the bug with some header files related to tracepoints,
+but it could also cause build failures in other circumstances. Thus,
+always emit a warning when using an old `bindgen` with a new `libclang`
+so that other people do not have to spend time chasing down the same
+bug.
+
+However, testing just the version is inconvenient, since distributions
+do patch their packages without changing the version, so I reduced the
+issue into the following piece of code that can trigger the issue:
+
+    #define F(x) int x##x
+    F(foo);
+
+In particular, an unpatched `bindgen` will ignore the macro expansion
+and thus not provide a declaration for the exported `int`.
+
+Thus add a build test to `rust_is_available.sh` using the code above
+(that is only triggered if the versions appear to be affected), following
+what we did for the 0.66.x issue.
+
+Moreover, I checked the status in the major distributions we have
+instructions for:
+
+  - Fedora 41 was affected but is now OK, since it now ships `bindgen`
+    0.69.5.
+
+    Thanks Ben for the quick reply on the updates that were ongoing.
+
+    Fedora 40 and earlier are OK (older `libclang`, and they also now
+    carry `bindgen` 0.69.5).
+
+  - Debian Sid was affected but is now OK, since they now ship a patched
+    `bindgen` binary (0.66.1-7+b3). The issue was reported to Debian by
+    email and then as a bug report [2].
+
+    Thanks NoisyCoil and Matthias for the quick replies. NoisyCoil handled
+    the needed updates. Debian may upgrade to `bindgen` 0.70.x, too.
+
+    Debian Testing is OK (older `libclang` so far).
+
+  - Ubuntu non-LTS (oracular) is affected. The issue was reported to Ubuntu
+    by email and then as a bug report [3].
+
+    Ubuntu LTS is not affected (older `libclang` so far).
+
+  - Arch Linux, Gentoo Linux and openSUSE should be OK (newer `bindgen` is
+    provided). Nix as well (older `libclang` so far).
+
+This issue was also added to our "live list" that tracks issues around
+distributions [4].
+
+Cc: Ben Beasley <code@musicinmybrain.net>
+Cc: NoisyCoil <noisycoil@tutanota.com>
+Cc: Matthias Geiger <werdahias@riseup.net>
+Link: https://lore.kernel.org/rust-for-linux/20241030-bindgen-libclang-warn-v1-1-3a7ba9fedcfe@google.com/ [1]
+Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1086510 [2]
+Link: https://bugs.launchpad.net/ubuntu/+source/rust-bindgen-cli/+bug/2086639 [3]
+Link: https://github.com/Rust-for-Linux/linux/issues/1127 [4]
+Co-developed-by: Alice Ryhl <aliceryhl@google.com>
+Signed-off-by: Alice Ryhl <aliceryhl@google.com>
+Link: https://lore.kernel.org/r/20241111201607.653149-1-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ scripts/rust_is_available.sh                  | 15 ++++++++
+ ...ust_is_available_bindgen_libclang_concat.h |  3 ++
+ scripts/rust_is_available_test.py             | 34 ++++++++++++++++++-
+ 3 files changed, 51 insertions(+), 1 deletion(-)
+ create mode 100644 scripts/rust_is_available_bindgen_libclang_concat.h
+
+diff --git a/scripts/rust_is_available.sh b/scripts/rust_is_available.sh
+index 5262c56dd674e..93c0ef7fb3fb2 100755
+--- a/scripts/rust_is_available.sh
++++ b/scripts/rust_is_available.sh
+@@ -225,6 +225,21 @@ if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then
+       exit 1
+ fi
++if [ "$bindgen_libclang_cversion" -ge 1900100 ] &&
++      [ "$rust_bindings_generator_cversion" -lt 6905 ]; then
++      # Distributions may have patched the issue (e.g. Debian did).
++      if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang_concat.h | grep -q foofoo; then
++              echo >&2 "***"
++              echo >&2 "*** Rust bindings generator '$BINDGEN' < 0.69.5 together with libclang >= 19.1"
++              echo >&2 "*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2824),"
++              echo >&2 "*** unless patched (like Debian's)."
++              echo >&2 "***   Your bindgen version:  $rust_bindings_generator_version"
++              echo >&2 "***   Your libclang version: $bindgen_libclang_version"
++              echo >&2 "***"
++              warning=1
++      fi
++fi
++
+ # If the C compiler is Clang, then we can also check whether its version
+ # matches the `libclang` version used by the Rust bindings generator.
+ #
+diff --git a/scripts/rust_is_available_bindgen_libclang_concat.h b/scripts/rust_is_available_bindgen_libclang_concat.h
+new file mode 100644
+index 0000000000000..efc6e98d0f1d0
+--- /dev/null
++++ b/scripts/rust_is_available_bindgen_libclang_concat.h
+@@ -0,0 +1,3 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#define F(x) int x##x
++F(foo);
+diff --git a/scripts/rust_is_available_test.py b/scripts/rust_is_available_test.py
+index 413741037fb30..4fcc319dea84e 100755
+--- a/scripts/rust_is_available_test.py
++++ b/scripts/rust_is_available_test.py
+@@ -54,7 +54,7 @@ else:
+ """)
+     @classmethod
+-    def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False):
++    def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False, libclang_concat_patched=False):
+         if libclang_stderr is None:
+             libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})"
+         else:
+@@ -65,12 +65,19 @@ else:
+         else:
+             version_0_66_case = "raise SystemExit(1)"
++        if libclang_concat_patched:
++            libclang_concat_case = "print('pub static mut foofoo: ::std::os::raw::c_int;')"
++        else:
++            libclang_concat_case = "pass"
++
+         return cls.generate_executable(f"""#!/usr/bin/env python3
+ import sys
+ if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv):
+     {libclang_case}
+ elif "rust_is_available_bindgen_0_66.h" in " ".join(sys.argv):
+     {version_0_66_case}
++elif "rust_is_available_bindgen_libclang_concat.h" in " ".join(sys.argv):
++    {libclang_concat_case}
+ else:
+     print({repr(version_stdout)})
+ """)
+@@ -268,6 +275,31 @@ else:
+         result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen })
+         self.assertIn(f"libclang (used by the Rust bindings generator '{bindgen}') is too old.", result.stderr)
++    def test_bindgen_bad_libclang_concat(self):
++        for (bindgen_version, libclang_version, expected_not_patched) in (
++            ("0.69.4", "18.0.0", self.Expected.SUCCESS),
++            ("0.69.4", "19.1.0", self.Expected.SUCCESS_WITH_WARNINGS),
++            ("0.69.4", "19.2.0", self.Expected.SUCCESS_WITH_WARNINGS),
++
++            ("0.69.5", "18.0.0", self.Expected.SUCCESS),
++            ("0.69.5", "19.1.0", self.Expected.SUCCESS),
++            ("0.69.5", "19.2.0", self.Expected.SUCCESS),
++
++            ("0.70.0", "18.0.0", self.Expected.SUCCESS),
++            ("0.70.0", "19.1.0", self.Expected.SUCCESS),
++            ("0.70.0", "19.2.0", self.Expected.SUCCESS),
++        ):
++            with self.subTest(bindgen_version=bindgen_version, libclang_version=libclang_version):
++                cc = self.generate_clang(f"clang version {libclang_version}")
++                libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {libclang_version} [-W#pragma-messages], err: false"
++                bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr)
++                result = self.run_script(expected_not_patched, { "BINDGEN": bindgen, "CC": cc })
++                if expected_not_patched == self.Expected.SUCCESS_WITH_WARNINGS:
++                    self.assertIn(f"Rust bindings generator '{bindgen}' < 0.69.5 together with libclang >= 19.1", result.stderr)
++
++                bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_concat_patched=True)
++                result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc })
++
+     def test_clang_matches_bindgen_libclang_different_bindgen(self):
+         bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version 999.0.0 [-W#pragma-messages], err: false")
+         result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
+-- 
+2.53.0
+
diff --git a/queue-6.12/series b/queue-6.12/series
new file mode 100644 (file)
index 0000000..ba8c819
--- /dev/null
@@ -0,0 +1,7 @@
+mm-userfaultfd-fix-hugetlb-fault-mutex-hash-calculat.patch
+pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch
+ima-verify-if-the-segment-size-has-changed.patch
+ima-do-not-copy-measurement-list-to-kdump-kernel.patch
+wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
+rust-warn-on-bindgen-0.69.5-and-libclang-19.1.patch
+net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch
diff --git a/queue-6.12/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch b/queue-6.12/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
new file mode 100644 (file)
index 0000000..83218ce
--- /dev/null
@@ -0,0 +1,107 @@
+From 6ea5f128742a1c1076de92dcb130a32c6e80665c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 10:42:50 +0800
+Subject: wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
+
+ieee80211_tx_prepare_skb() has three error paths, but only two of them
+free the skb. The first error path (ieee80211_tx_prepare() returning
+TX_DROP) does not free it, while invoke_tx_handlers() failure and the
+fragmentation check both do.
+
+Add kfree_skb() to the first error path so all three are consistent,
+and remove the now-redundant frees in callers (ath9k, mt76,
+mac80211_hwsim) to avoid double-free.
+
+Document the skb ownership guarantee in the function's kdoc.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name
+Fixes: 06be6b149f7e ("mac80211: add ieee80211_tx_prepare_skb() helper function")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
+ introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning")
+ after linux-6.14.]
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/channel.c      | 6 ++----
+ drivers/net/wireless/virtual/mac80211_hwsim.c | 1 -
+ include/net/mac80211.h                        | 4 +++-
+ net/mac80211/tx.c                             | 4 +++-
+ 4 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
+index 571062f2e82a7..ba8ec5112afe8 100644
+--- a/drivers/net/wireless/ath/ath9k/channel.c
++++ b/drivers/net/wireless/ath/ath9k/channel.c
+@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
+       skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+       if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
+-              goto error;
++              return;
+       txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
+       if (ath_tx_start(sc->hw, skb, &txctl))
+@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
+               skb->priority = 7;
+               skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+-              if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
+-                      dev_kfree_skb_any(skb);
++              if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
+                       return false;
+-              }
+               break;
+       default:
+               return false;
+diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
+index 8b4fd5fd11b0e..e992e59b59189 100644
+--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
++++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
+@@ -2977,7 +2977,6 @@ static void hw_scan_work(struct work_struct *work)
+                                                     hwsim->tmp_chan->band,
+                                                     NULL)) {
+                               rcu_read_unlock();
+-                              kfree_skb(probe);
+                               continue;
+                       }
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index 80259a37e7247..7d71a4149cdf9 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -7208,7 +7208,9 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
+  * @band: the band to transmit on
+  * @sta: optional pointer to get the station to send the frame to
+  *
+- * Return: %true if the skb was prepared, %false otherwise
++ * Return: %true if the skb was prepared, %false otherwise.
++ * On failure, the skb is freed by this function; callers must not
++ * free it again.
+  *
+  * Note: must be called under RCU lock
+  */
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 9142d748a6a70..0458cbba232e2 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1897,8 +1897,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
+       struct ieee80211_tx_data tx;
+       struct sk_buff *skb2;
+-      if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
++      if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
++              kfree_skb(skb);
+               return false;
++      }
+       info->band = band;
+       info->control.vif = vif;
+-- 
+2.53.0
+
diff --git a/queue-6.18/arm64-cputype-add-c1-pro-definitions.patch b/queue-6.18/arm64-cputype-add-c1-pro-definitions.patch
new file mode 100644 (file)
index 0000000..af34240
--- /dev/null
@@ -0,0 +1,50 @@
+From 66ca32af358c11a23108700529612bfd0206a44b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 11:00:16 +0100
+Subject: arm64: cputype: Add C1-Pro definitions
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit 2c99561016c591f4c3d5ad7d22a61b8726e79735 upstream.
+
+Add cputype definitions for C1-Pro. These will be used for errata
+detection in subsequent patches.
+
+These values can be found in "Table A-303: MIDR_EL1 bit descriptions" in
+issue 07 of the C1-Pro TRM:
+
+  https://documentation-service.arm.com/static/6930126730f8f55a656570af
+
+Acked-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Cc: James Morse <james.morse@arm.com>
+Reviewed-by: Will Deacon <will@kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/cputype.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
+index 9b00b75acbf29..18f98fb7ee783 100644
+--- a/arch/arm64/include/asm/cputype.h
++++ b/arch/arm64/include/asm/cputype.h
+@@ -98,6 +98,7 @@
+ #define ARM_CPU_PART_CORTEX_A725      0xD87
+ #define ARM_CPU_PART_CORTEX_A720AE    0xD89
+ #define ARM_CPU_PART_NEOVERSE_N3      0xD8E
++#define ARM_CPU_PART_C1_PRO           0xD8B
+ #define APM_CPU_PART_XGENE            0x000
+ #define APM_CPU_VAR_POTENZA           0x00
+@@ -189,6 +190,7 @@
+ #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
+ #define MIDR_CORTEX_A720AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720AE)
+ #define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
++#define MIDR_C1_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_PRO)
+ #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
+ #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
+ #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
+-- 
+2.53.0
+
diff --git a/queue-6.18/arm64-errata-work-around-early-cme-dvmsync-acknowled.patch b/queue-6.18/arm64-errata-work-around-early-cme-dvmsync-acknowled.patch
new file mode 100644 (file)
index 0000000..4e1d54e
--- /dev/null
@@ -0,0 +1,531 @@
+From faa8d2c214b68a6e5a2650041f3e05b0ce27b6a6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 11:00:17 +0100
+Subject: arm64: errata: Work around early CME DVMSync acknowledgement
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit 0baba94a9779c13c857f6efc55807e6a45b1d4e4 upstream.
+
+C1-Pro acknowledges DVMSync messages before completing the SME/CME
+memory accesses. Work around this by issuing an IPI to the affected CPUs
+if they are running in EL0 with SME enabled.
+
+Note that we avoid the local DSB in the IPI handler as the kernel runs
+with SCTLR_EL1.IESB=1. This is sufficient to complete SME memory
+accesses at EL0 on taking an exception to EL1. On the return to user
+path, no barrier is necessary either. See the comment in
+sme_set_active() and the more detailed explanation in the link below.
+
+To avoid a potential IPI flood from malicious applications (e.g.
+madvise(MADV_PAGEOUT) in a tight loop), track where a process is active
+via mm_cpumask() and only interrupt those CPUs.
+
+Link: https://lore.kernel.org/r/ablEXwhfKyJW1i7l@J2N7QTR9R3
+Cc: Will Deacon <will@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: James Morse <james.morse@arm.com>
+Cc: Mark Brown <broonie@kernel.org>
+Reviewed-by: Will Deacon <will@kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/arch/arm64/silicon-errata.rst |  2 +
+ arch/arm64/Kconfig                          | 12 ++++
+ arch/arm64/include/asm/cpucaps.h            |  2 +
+ arch/arm64/include/asm/fpsimd.h             | 21 ++++++
+ arch/arm64/include/asm/tlbbatch.h           | 10 ++-
+ arch/arm64/include/asm/tlbflush.h           | 72 ++++++++++++++++++-
+ arch/arm64/kernel/cpu_errata.c              | 30 ++++++++
+ arch/arm64/kernel/entry-common.c            |  3 +
+ arch/arm64/kernel/fpsimd.c                  | 79 +++++++++++++++++++++
+ arch/arm64/kernel/process.c                 | 36 ++++++++++
+ arch/arm64/tools/cpucaps                    |  1 +
+ 11 files changed, 264 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
+index a7ec57060f64f..93cdf16937159 100644
+--- a/Documentation/arch/arm64/silicon-errata.rst
++++ b/Documentation/arch/arm64/silicon-errata.rst
+@@ -202,6 +202,8 @@ stable kernels.
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM            | Neoverse-V3AE   | #3312417        | ARM64_ERRATUM_3194386       |
+ +----------------+-----------------+-----------------+-----------------------------+
++| ARM            | C1-Pro          | #4193714        | ARM64_ERRATUM_4193714       |
+++----------------+-----------------+-----------------+-----------------------------+
+ | ARM            | MMU-500         | #841119,826419  | ARM_SMMU_MMU_500_CPRE_ERRATA|
+ |                |                 | #562869,1047329 |                             |
+ +----------------+-----------------+-----------------+-----------------------------+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 6663ffd23f252..840a945cb4acd 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -1154,6 +1154,18 @@ config ARM64_ERRATUM_3194386
+         If unsure, say Y.
++config ARM64_ERRATUM_4193714
++      bool "C1-Pro: 4193714: SME DVMSync early acknowledgement"
++      depends on ARM64_SME
++      default y
++      help
++        Enable workaround for C1-Pro acknowledging the DVMSync before
++        the SME memory accesses are complete. This will cause TLB
++        maintenance for processes using SME to also issue an IPI to
++        the affected CPUs.
++
++        If unsure, say Y.
++
+ config CAVIUM_ERRATUM_22375
+       bool "Cavium erratum 22375, 24313"
+       default y
+diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
+index 9d769291a3067..121210b7ffd0b 100644
+--- a/arch/arm64/include/asm/cpucaps.h
++++ b/arch/arm64/include/asm/cpucaps.h
+@@ -66,6 +66,8 @@ cpucap_is_possible(const unsigned int cap)
+               return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI);
+       case ARM64_WORKAROUND_SPECULATIVE_SSBS:
+               return IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386);
++      case ARM64_WORKAROUND_4193714:
++              return IS_ENABLED(CONFIG_ARM64_ERRATUM_4193714);
+       case ARM64_MPAM:
+               /*
+                * KVM MPAM support doesn't rely on the host kernel supporting MPAM.
+diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
+index b8cf0ea43cc05..0fa8d1d5722e0 100644
+--- a/arch/arm64/include/asm/fpsimd.h
++++ b/arch/arm64/include/asm/fpsimd.h
+@@ -428,6 +428,24 @@ static inline size_t sme_state_size(struct task_struct const *task)
+       return __sme_state_size(task_get_sme_vl(task));
+ }
++void sme_enable_dvmsync(void);
++void sme_set_active(void);
++void sme_clear_active(void);
++
++static inline void sme_enter_from_user_mode(void)
++{
++      if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714) &&
++          test_thread_flag(TIF_SME))
++              sme_clear_active();
++}
++
++static inline void sme_exit_to_user_mode(void)
++{
++      if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714) &&
++          test_thread_flag(TIF_SME))
++              sme_set_active();
++}
++
+ #else
+ static inline void sme_user_disable(void) { BUILD_BUG(); }
+@@ -456,6 +474,9 @@ static inline size_t sme_state_size(struct task_struct const *task)
+       return 0;
+ }
++static inline void sme_enter_from_user_mode(void) { }
++static inline void sme_exit_to_user_mode(void) { }
++
+ #endif /* ! CONFIG_ARM64_SME */
+ /* For use by EFI runtime services calls only */
+diff --git a/arch/arm64/include/asm/tlbbatch.h b/arch/arm64/include/asm/tlbbatch.h
+index fedb0b87b8db4..6297631532e59 100644
+--- a/arch/arm64/include/asm/tlbbatch.h
++++ b/arch/arm64/include/asm/tlbbatch.h
+@@ -2,11 +2,17 @@
+ #ifndef _ARCH_ARM64_TLBBATCH_H
+ #define _ARCH_ARM64_TLBBATCH_H
++#include <linux/cpumask.h>
++
+ struct arch_tlbflush_unmap_batch {
++#ifdef CONFIG_ARM64_ERRATUM_4193714
+       /*
+-       * For arm64, HW can do tlb shootdown, so we don't
+-       * need to record cpumask for sending IPI
++       * Track CPUs that need SME DVMSync on completion of this batch.
++       * Otherwise, the arm64 HW can do tlb shootdown, so we don't need to
++       * record cpumask for sending IPI
+        */
++      cpumask_var_t cpumask;
++#endif
+ };
+ #endif /* _ARCH_ARM64_TLBBATCH_H */
+diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
+index ba36e91aefb82..f53ab3ba0c48b 100644
+--- a/arch/arm64/include/asm/tlbflush.h
++++ b/arch/arm64/include/asm/tlbflush.h
+@@ -80,6 +80,71 @@ static inline unsigned long get_trans_granule(void)
+       }
+ }
++#ifdef CONFIG_ARM64_ERRATUM_4193714
++
++void sme_do_dvmsync(const struct cpumask *mask);
++
++static inline void sme_dvmsync(struct mm_struct *mm)
++{
++      if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
++              return;
++
++      sme_do_dvmsync(mm_cpumask(mm));
++}
++
++static inline void sme_dvmsync_add_pending(struct arch_tlbflush_unmap_batch *batch,
++                                         struct mm_struct *mm)
++{
++      if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
++              return;
++
++      /*
++       * Order the mm_cpumask() read after the hardware DVMSync.
++       */
++      dsb(ish);
++      if (cpumask_empty(mm_cpumask(mm)))
++              return;
++
++      /*
++       * Allocate the batch cpumask on first use. Fall back to an immediate
++       * IPI for this mm in case of failure.
++       */
++      if (!cpumask_available(batch->cpumask) &&
++          !zalloc_cpumask_var(&batch->cpumask, GFP_ATOMIC)) {
++              sme_do_dvmsync(mm_cpumask(mm));
++              return;
++      }
++
++      cpumask_or(batch->cpumask, batch->cpumask, mm_cpumask(mm));
++}
++
++static inline void sme_dvmsync_batch(struct arch_tlbflush_unmap_batch *batch)
++{
++      if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
++              return;
++
++      if (!cpumask_available(batch->cpumask))
++              return;
++
++      sme_do_dvmsync(batch->cpumask);
++      cpumask_clear(batch->cpumask);
++}
++
++#else
++
++static inline void sme_dvmsync(struct mm_struct *mm)
++{
++}
++static inline void sme_dvmsync_add_pending(struct arch_tlbflush_unmap_batch *batch,
++                                         struct mm_struct *mm)
++{
++}
++static inline void sme_dvmsync_batch(struct arch_tlbflush_unmap_batch *batch)
++{
++}
++
++#endif /* CONFIG_ARM64_ERRATUM_4193714 */
++
+ /*
+  * Level-based TLBI operations.
+  *
+@@ -189,12 +254,14 @@ static inline void __tlbi_sync_s1ish(struct mm_struct *mm)
+ {
+       dsb(ish);
+       __repeat_tlbi_sync(vale1is, 0);
++      sme_dvmsync(mm);
+ }
+-static inline void __tlbi_sync_s1ish_batch(void)
++static inline void __tlbi_sync_s1ish_batch(struct arch_tlbflush_unmap_batch *batch)
+ {
+       dsb(ish);
+       __repeat_tlbi_sync(vale1is, 0);
++      sme_dvmsync_batch(batch);
+ }
+ static inline void __tlbi_sync_s1ish_kernel(void)
+@@ -357,7 +424,7 @@ static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
+  */
+ static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
+ {
+-      __tlbi_sync_s1ish_batch();
++      __tlbi_sync_s1ish_batch(batch);
+ }
+ /*
+@@ -546,6 +613,7 @@ static inline void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *b
+               struct mm_struct *mm, unsigned long start, unsigned long end)
+ {
+       __flush_tlb_range_nosync(mm, start, end, PAGE_SIZE, true, 3);
++      sme_dvmsync_add_pending(batch, mm);
+ }
+ #endif
+diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
+index 8cb3b575a0316..6c8c4301d9c6d 100644
+--- a/arch/arm64/kernel/cpu_errata.c
++++ b/arch/arm64/kernel/cpu_errata.c
+@@ -11,6 +11,7 @@
+ #include <asm/cpu.h>
+ #include <asm/cputype.h>
+ #include <asm/cpufeature.h>
++#include <asm/fpsimd.h>
+ #include <asm/kvm_asm.h>
+ #include <asm/smp_plat.h>
+@@ -551,6 +552,23 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
+ };
+ #endif
++#ifdef CONFIG_ARM64_ERRATUM_4193714
++static bool has_sme_dvmsync_erratum(const struct arm64_cpu_capabilities *entry,
++                                  int scope)
++{
++      if (!id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1)))
++              return false;
++
++      return is_affected_midr_range(entry, scope);
++}
++
++static void cpu_enable_sme_dvmsync(const struct arm64_cpu_capabilities *__unused)
++{
++      if (this_cpu_has_cap(ARM64_WORKAROUND_4193714))
++              sme_enable_dvmsync();
++}
++#endif
++
+ #ifdef CONFIG_AMPERE_ERRATUM_AC03_CPU_38
+ static const struct midr_range erratum_ac03_cpu_38_list[] = {
+       MIDR_ALL_VERSIONS(MIDR_AMPERE1),
+@@ -870,6 +888,18 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
+               ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list),
+       },
+ #endif
++#ifdef CONFIG_ARM64_ERRATUM_4193714
++      {
++              .desc = "C1-Pro SME DVMSync early acknowledgement",
++              .capability = ARM64_WORKAROUND_4193714,
++              .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
++              .matches = has_sme_dvmsync_erratum,
++              .cpu_enable = cpu_enable_sme_dvmsync,
++              /* C1-Pro r0p0 - r1p2 (the latter only when REVIDR_EL1[0]==0) */
++              .midr_range = MIDR_RANGE(MIDR_C1_PRO, 0, 0, 1, 2),
++              MIDR_FIXED(MIDR_CPU_VAR_REV(1, 2), BIT(0)),
++      },
++#endif
+ #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
+       {
+               .desc = "ARM errata 2966298, 3117295",
+diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
+index a9c81715ce59e..5b97dfcf796d9 100644
+--- a/arch/arm64/kernel/entry-common.c
++++ b/arch/arm64/kernel/entry-common.c
+@@ -21,6 +21,7 @@
+ #include <asm/daifflags.h>
+ #include <asm/esr.h>
+ #include <asm/exception.h>
++#include <asm/fpsimd.h>
+ #include <asm/irq_regs.h>
+ #include <asm/kprobes.h>
+ #include <asm/mmu.h>
+@@ -84,6 +85,7 @@ static __always_inline void __enter_from_user_mode(struct pt_regs *regs)
+ {
+       enter_from_user_mode(regs);
+       mte_disable_tco_entry(current);
++      sme_enter_from_user_mode();
+ }
+ static __always_inline void arm64_enter_from_user_mode(struct pt_regs *regs)
+@@ -102,6 +104,7 @@ static __always_inline void arm64_exit_to_user_mode(struct pt_regs *regs)
+       local_irq_disable();
+       exit_to_user_mode_prepare(regs);
+       local_daif_mask();
++      sme_exit_to_user_mode();
+       mte_check_tfsr_exit();
+       exit_to_user_mode();
+ }
+diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
+index e3f8f51748bc9..ca18214ce2abe 100644
+--- a/arch/arm64/kernel/fpsimd.c
++++ b/arch/arm64/kernel/fpsimd.c
+@@ -15,6 +15,7 @@
+ #include <linux/compiler.h>
+ #include <linux/cpu.h>
+ #include <linux/cpu_pm.h>
++#include <linux/cpumask.h>
+ #include <linux/ctype.h>
+ #include <linux/kernel.h>
+ #include <linux/linkage.h>
+@@ -28,6 +29,7 @@
+ #include <linux/sched/task_stack.h>
+ #include <linux/signal.h>
+ #include <linux/slab.h>
++#include <linux/smp.h>
+ #include <linux/stddef.h>
+ #include <linux/sysctl.h>
+ #include <linux/swab.h>
+@@ -1384,6 +1386,83 @@ void do_sve_acc(unsigned long esr, struct pt_regs *regs)
+       put_cpu_fpsimd_context();
+ }
++#ifdef CONFIG_ARM64_ERRATUM_4193714
++
++/*
++ * SME/CME erratum handling.
++ */
++static cpumask_t sme_dvmsync_cpus;
++
++/*
++ * These helpers are only called from non-preemptible contexts, so
++ * smp_processor_id() is safe here.
++ */
++void sme_set_active(void)
++{
++      unsigned int cpu = smp_processor_id();
++
++      if (!cpumask_test_cpu(cpu, &sme_dvmsync_cpus))
++              return;
++
++      cpumask_set_cpu(cpu, mm_cpumask(current->mm));
++
++      /*
++       * A subsequent (post ERET) SME access may use a stale address
++       * translation. On C1-Pro, a TLBI+DSB on a different CPU will wait for
++       * the completion of cpumask_set_cpu() above as it appears in program
++       * order before the SME access. The post-TLBI+DSB read of mm_cpumask()
++       * will lead to the IPI being issued.
++       *
++       * https://lore.kernel.org/r/ablEXwhfKyJW1i7l@J2N7QTR9R3
++       */
++}
++
++void sme_clear_active(void)
++{
++      unsigned int cpu = smp_processor_id();
++
++      if (!cpumask_test_cpu(cpu, &sme_dvmsync_cpus))
++              return;
++
++      /*
++       * With SCTLR_EL1.IESB enabled, the SME memory transactions are
++       * completed on entering EL1.
++       */
++      cpumask_clear_cpu(cpu, mm_cpumask(current->mm));
++}
++
++static void sme_dvmsync_ipi(void *unused)
++{
++      /*
++       * With SCTLR_EL1.IESB on, taking an exception is sufficient to ensure
++       * the completion of the SME memory accesses, so no need for an
++       * explicit DSB.
++       */
++}
++
++void sme_do_dvmsync(const struct cpumask *mask)
++{
++      /*
++       * This is called from the TLB maintenance functions after the DSB ISH
++       * to send the hardware DVMSync message. If this CPU sees the mask as
++       * empty, the remote CPU executing sme_set_active() would have seen
++       * the DVMSync and no IPI required.
++       */
++      if (cpumask_empty(mask))
++              return;
++
++      preempt_disable();
++      smp_call_function_many(mask, sme_dvmsync_ipi, NULL, true);
++      preempt_enable();
++}
++
++void sme_enable_dvmsync(void)
++{
++      cpumask_set_cpu(smp_processor_id(), &sme_dvmsync_cpus);
++}
++
++#endif /* CONFIG_ARM64_ERRATUM_4193714 */
++
+ /*
+  * Trapped SME access
+  *
+diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
+index 489554931231e..4c328b7c79ba3 100644
+--- a/arch/arm64/kernel/process.c
++++ b/arch/arm64/kernel/process.c
+@@ -26,6 +26,7 @@
+ #include <linux/reboot.h>
+ #include <linux/interrupt.h>
+ #include <linux/init.h>
++#include <linux/cpumask.h>
+ #include <linux/cpu.h>
+ #include <linux/elfcore.h>
+ #include <linux/pm.h>
+@@ -339,8 +340,41 @@ void flush_thread(void)
+       flush_gcs();
+ }
++#ifdef CONFIG_ARM64_ERRATUM_4193714
++
++static void arch_dup_tlbbatch_mask(struct task_struct *dst)
++{
++      /*
++       * Clear the inherited cpumask with memset() to cover both cases where
++       * cpumask_var_t is a pointer or an array. It will be allocated lazily
++       * in sme_dvmsync_add_pending() if CPUMASK_OFFSTACK=y.
++       */
++      if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
++              memset(&dst->tlb_ubc.arch.cpumask, 0,
++                     sizeof(dst->tlb_ubc.arch.cpumask));
++}
++
++static void arch_release_tlbbatch_mask(struct task_struct *tsk)
++{
++      if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
++              free_cpumask_var(tsk->tlb_ubc.arch.cpumask);
++}
++
++#else
++
++static void arch_dup_tlbbatch_mask(struct task_struct *dst)
++{
++}
++
++static void arch_release_tlbbatch_mask(struct task_struct *tsk)
++{
++}
++
++#endif /* CONFIG_ARM64_ERRATUM_4193714 */
++
+ void arch_release_task_struct(struct task_struct *tsk)
+ {
++      arch_release_tlbbatch_mask(tsk);
+       fpsimd_release_task(tsk);
+ }
+@@ -356,6 +390,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
+       *dst = *src;
++      arch_dup_tlbbatch_mask(dst);
++
+       /*
+        * Drop stale reference to src's sve_state and convert dst to
+        * non-streaming FPSIMD mode.
+diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
+index 1b32c1232d28d..16d123088ddd4 100644
+--- a/arch/arm64/tools/cpucaps
++++ b/arch/arm64/tools/cpucaps
+@@ -101,6 +101,7 @@ WORKAROUND_2077057
+ WORKAROUND_2457168
+ WORKAROUND_2645198
+ WORKAROUND_2658417
++WORKAROUND_4193714
+ WORKAROUND_AMPERE_AC03_CPU_38
+ WORKAROUND_AMPERE_AC04_CPU_23
+ WORKAROUND_TRBE_OVERWRITE_FILL_MODE
+-- 
+2.53.0
+
diff --git a/queue-6.18/arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch b/queue-6.18/arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch
new file mode 100644 (file)
index 0000000..2119462
--- /dev/null
@@ -0,0 +1,59 @@
+From bd04b0c2c4878edbfe8b4fad3e198ce637d1be4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 11:00:12 +0100
+Subject: arm64: tlb: Allow XZR argument to TLBI ops
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit bfd9c931d19aa59fb8371d557774fa169b15db9a upstream.
+
+The TLBI instruction accepts XZR as a register argument, and for TLBI
+operations with a register argument, there is no functional difference
+between using XZR or another GPR which contains zeroes. Operations
+without a register argument are encoded as if XZR were used.
+
+Allow the __TLBI_1() macro to use XZR when a register argument is all
+zeroes.
+
+Today this only results in a trivial code saving in
+__do_compat_cache_op()'s workaround for Neoverse-N1 erratum #1542419. In
+subsequent patches this pattern will be used more generally.
+
+There should be no functional change as a result of this patch.
+
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Oliver Upton <oupton@kernel.org>
+Cc: Ryan Roberts <ryan.roberts@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/tlbflush.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
+index 18a5dc0c9a540..0ddb344f83b4e 100644
+--- a/arch/arm64/include/asm/tlbflush.h
++++ b/arch/arm64/include/asm/tlbflush.h
+@@ -38,12 +38,12 @@
+                           : : )
+ #define __TLBI_1(op, arg) asm (ARM64_ASM_PREAMBLE                            \
+-                             "tlbi " #op ", %0\n"                            \
++                             "tlbi " #op ", %x0\n"                           \
+                  ALTERNATIVE("nop\n                   nop",                  \
+-                             "dsb ish\n               tlbi " #op ", %0",     \
++                             "dsb ish\n               tlbi " #op ", %x0",    \
+                              ARM64_WORKAROUND_REPEAT_TLBI,                   \
+                              CONFIG_ARM64_WORKAROUND_REPEAT_TLBI)            \
+-                          : : "r" (arg))
++                          : : "rZ" (arg))
+ #define __TLBI_N(op, arg, n, ...) __TLBI_##n(op, arg)
+-- 
+2.53.0
+
diff --git a/queue-6.18/arm64-tlb-introduce-__tlbi_sync_s1ish_-kernel-batch-.patch b/queue-6.18/arm64-tlb-introduce-__tlbi_sync_s1ish_-kernel-batch-.patch
new file mode 100644 (file)
index 0000000..2636567
--- /dev/null
@@ -0,0 +1,91 @@
+From b0133a902703b93dd46ef288b1f91ca5a126cd20 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 11:00:14 +0100
+Subject: arm64: tlb: Introduce __tlbi_sync_s1ish_{kernel,batch}() for TLB
+ maintenance
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit 6bfbf574a39139da11af9fdf6e8d56fe1989cd3e upstream.
+
+Add __tlbi_sync_s1ish_kernel() similar to __tlbi_sync_s1ish() and use it
+for kernel TLB maintenance. Also use this function in flush_tlb_all()
+which is only used in relation to kernel mappings. Subsequent patches
+can differentiate between workarounds that apply to user only or both
+user and kernel.
+
+A subsequent patch will add mm_struct to __tlbi_sync_s1ish(). Since
+arch_tlbbatch_flush() is not specific to an mm, add a corresponding
+__tlbi_sync_s1ish_batch() helper.
+
+Acked-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Reviewed-by: Will Deacon <will@kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/tlbflush.h | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
+index c87d13bee37de..387bd86af7021 100644
+--- a/arch/arm64/include/asm/tlbflush.h
++++ b/arch/arm64/include/asm/tlbflush.h
+@@ -191,6 +191,18 @@ static inline void __tlbi_sync_s1ish(void)
+       __repeat_tlbi_sync(vale1is, 0);
+ }
++static inline void __tlbi_sync_s1ish_batch(void)
++{
++      dsb(ish);
++      __repeat_tlbi_sync(vale1is, 0);
++}
++
++static inline void __tlbi_sync_s1ish_kernel(void)
++{
++      dsb(ish);
++      __repeat_tlbi_sync(vale1is, 0);
++}
++
+ /*
+  * Complete broadcast TLB maintenance issued by hyp code which invalidates
+  * stage 1 translation information in any translation regime.
+@@ -286,7 +298,7 @@ static inline void flush_tlb_all(void)
+ {
+       dsb(ishst);
+       __tlbi(vmalle1is);
+-      __tlbi_sync_s1ish();
++      __tlbi_sync_s1ish_kernel();
+       isb();
+ }
+@@ -345,7 +357,7 @@ static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
+  */
+ static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
+ {
+-      __tlbi_sync_s1ish();
++      __tlbi_sync_s1ish_batch();
+ }
+ /*
+@@ -512,7 +524,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
+       dsb(ishst);
+       __flush_tlb_range_op(vaale1is, start, pages, stride, 0,
+                            TLBI_TTL_UNKNOWN, false, lpa2_is_enabled());
+-      __tlbi_sync_s1ish();
++      __tlbi_sync_s1ish_kernel();
+       isb();
+ }
+@@ -526,7 +538,7 @@ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr)
+       dsb(ishst);
+       __tlbi(vaae1is, addr);
+-      __tlbi_sync_s1ish();
++      __tlbi_sync_s1ish_kernel();
+       isb();
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch b/queue-6.18/arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch
new file mode 100644 (file)
index 0000000..bb305e3
--- /dev/null
@@ -0,0 +1,453 @@
+From ff4dc5561fb57e82c7d972a1faa44d736aba839b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 11:00:13 +0100
+Subject: arm64: tlb: Optimize ARM64_WORKAROUND_REPEAT_TLBI
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+commit a8f78680ee6bf795086384e8aea159a52814f827 upstream.
+
+The ARM64_WORKAROUND_REPEAT_TLBI workaround is used to mitigate several
+errata where broadcast TLBI;DSB sequences don't provide all the
+architecturally required synchronization. The workaround performs more
+work than necessary, and can have significant overhead. This patch
+optimizes the workaround, as explained below.
+
+The workaround was originally added for Qualcomm Falkor erratum 1009 in
+commit:
+
+  d9ff80f83ecb ("arm64: Work around Falkor erratum 1009")
+
+As noted in the message for that commit, the workaround is applied even
+in cases where it is not strictly necessary.
+
+The workaround was later reused without changes for:
+
+* Arm Cortex-A76 erratum #1286807
+  SDEN v33: https://developer.arm.com/documentation/SDEN-885749/33-0/
+
+* Arm Cortex-A55 erratum #2441007
+  SDEN v16: https://developer.arm.com/documentation/SDEN-859338/1600/
+
+* Arm Cortex-A510 erratum #2441009
+  SDEN v19: https://developer.arm.com/documentation/SDEN-1873351/1900/
+
+The important details to note are as follows:
+
+1. All relevant errata only affect the ordering and/or completion of
+   memory accesses which have been translated by an invalidated TLB
+   entry. The actual invalidation of TLB entries is unaffected.
+
+2. The existing workaround is applied to both broadcast and local TLB
+   invalidation, whereas for all relevant errata it is only necessary to
+   apply a workaround for broadcast invalidation.
+
+3. The existing workaround replaces every TLBI with a TLBI;DSB;TLBI
+   sequence, whereas for all relevant errata it is only necessary to
+   execute a single additional TLBI;DSB sequence after any number of
+   TLBIs are completed by a DSB.
+
+   For example, for a sequence of batched TLBIs:
+
+       TLBI <op1>[, <arg1>]
+       TLBI <op2>[, <arg2>]
+       TLBI <op3>[, <arg3>]
+       DSB ISH
+
+   ... the existing workaround will expand this to:
+
+       TLBI <op1>[, <arg1>]
+       DSB ISH                  // additional
+       TLBI <op1>[, <arg1>]     // additional
+       TLBI <op2>[, <arg2>]
+       DSB ISH                  // additional
+       TLBI <op2>[, <arg2>]     // additional
+       TLBI <op3>[, <arg3>]
+       DSB ISH                  // additional
+       TLBI <op3>[, <arg3>]     // additional
+       DSB ISH
+
+   ... whereas it is sufficient to have:
+
+       TLBI <op1>[, <arg1>]
+       TLBI <op2>[, <arg2>]
+       TLBI <op3>[, <arg3>]
+       DSB ISH
+       TLBI <opX>[, <argX>]     // additional
+       DSB ISH                  // additional
+
+   Using a single additional TBLI and DSB at the end of the sequence can
+   have significantly lower overhead as each DSB which completes a TLBI
+   must synchronize with other PEs in the system, with potential
+   performance effects both locally and system-wide.
+
+4. The existing workaround repeats each specific TLBI operation, whereas
+   for all relevant errata it is sufficient for the additional TLBI to
+   use *any* operation which will be broadcast, regardless of which
+   translation regime or stage of translation the operation applies to.
+
+   For example, for a single TLBI:
+
+       TLBI ALLE2IS
+       DSB ISH
+
+   ... the existing workaround will expand this to:
+
+       TLBI ALLE2IS
+       DSB ISH
+       TLBI ALLE2IS             // additional
+       DSB ISH                  // additional
+
+   ... whereas it is sufficient to have:
+
+       TLBI ALLE2IS
+       DSB ISH
+       TLBI VALE1IS, XZR        // additional
+       DSB ISH                  // additional
+
+   As the additional TLBI doesn't have to match a specific earlier TLBI,
+   the additional TLBI can be implemented in separate code, with no
+   memory of the earlier TLBIs. The additional TLBI can also use a
+   cheaper TLBI operation.
+
+5. The existing workaround is applied to both Stage-1 and Stage-2 TLB
+   invalidation, whereas for all relevant errata it is only necessary to
+   apply a workaround for Stage-1 invalidation.
+
+   Architecturally, TLBI operations which invalidate only Stage-2
+   information (e.g. IPAS2E1IS) are not required to invalidate TLB
+   entries which combine information from Stage-1 and Stage-2
+   translation table entries, and consequently may not complete memory
+   accesses translated by those combined entries. In these cases,
+   completion of memory accesses is only guaranteed after subsequent
+   invalidation of Stage-1 information (e.g. VMALLE1IS).
+
+Taking the above points into account, this patch reworks the workaround
+logic to reduce overhead:
+
+* New __tlbi_sync_s1ish() and __tlbi_sync_s1ish_hyp() functions are
+  added and used in place of any dsb(ish) which is used to complete
+  broadcast Stage-1 TLB maintenance. When the
+  ARM64_WORKAROUND_REPEAT_TLBI workaround is enabled, these helpers will
+  execute an additional TLBI;DSB sequence.
+
+  For consistency, it might make sense to add __tlbi_sync_*() helpers
+  for local and stage 2 maintenance. For now I've left those with
+  open-coded dsb() to keep the diff small.
+
+* The duplication of TLBIs in __TLBI_0() and __TLBI_1() is removed. This
+  is no longer needed as the necessary synchronization will happen in
+  __tlbi_sync_s1ish() or __tlbi_sync_s1ish_hyp().
+
+* The additional TLBI operation is chosen to have minimal impact:
+
+  - __tlbi_sync_s1ish() uses "TLBI VALE1IS, XZR". This is only used at
+    EL1 or at EL2 with {E2H,TGE}=={1,1}, where it will target an unused
+    entry for the reserved ASID in the kernel's own translation regime,
+    and have no adverse affect.
+
+  - __tlbi_sync_s1ish_hyp() uses "TLBI VALE2IS, XZR". This is only used
+    in hyp code, where it will target an unused entry in the hyp code's
+    TTBR0 mapping, and should have no adverse effect.
+
+* As __TLBI_0() and __TLBI_1() no longer replace each TLBI with a
+  TLBI;DSB;TLBI sequence, batching TLBIs is worthwhile, and there's no
+  need for arch_tlbbatch_should_defer() to consider
+  ARM64_WORKAROUND_REPEAT_TLBI.
+
+When building defconfig with GCC 15.1.0, compared to v6.19-rc1, this
+patch saves ~1KiB of text, makes the vmlinux ~42KiB smaller, and makes
+the resulting Image 64KiB smaller:
+
+| [mark@lakrids:~/src/linux]% size vmlinux-*
+|    text    data     bss     dec     hex filename
+| 21179831        19660919         708216 41548966        279fca6 vmlinux-after
+| 21181075        19660903         708216 41550194        27a0172 vmlinux-before
+| [mark@lakrids:~/src/linux]% ls -l vmlinux-*
+| -rwxr-xr-x 1 mark mark 157771472 Feb  4 12:05 vmlinux-after
+| -rwxr-xr-x 1 mark mark 157815432 Feb  4 12:05 vmlinux-before
+| [mark@lakrids:~/src/linux]% ls -l Image-*
+| -rw-r--r-- 1 mark mark 41007616 Feb  4 12:05 Image-after
+| -rw-r--r-- 1 mark mark 41073152 Feb  4 12:05 Image-before
+
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Marc Zyngier <maz@kernel.org>
+Cc: Oliver Upton <oupton@kernel.org>
+Cc: Ryan Roberts <ryan.roberts@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/tlbflush.h | 59 ++++++++++++++++++-------------
+ arch/arm64/kernel/sys_compat.c    |  2 +-
+ arch/arm64/kvm/hyp/nvhe/mm.c      |  2 +-
+ arch/arm64/kvm/hyp/nvhe/tlb.c     |  8 ++---
+ arch/arm64/kvm/hyp/pgtable.c      |  2 +-
+ arch/arm64/kvm/hyp/vhe/tlb.c      | 10 +++---
+ 6 files changed, 47 insertions(+), 36 deletions(-)
+
+diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
+index 0ddb344f83b4e..c87d13bee37de 100644
+--- a/arch/arm64/include/asm/tlbflush.h
++++ b/arch/arm64/include/asm/tlbflush.h
+@@ -31,18 +31,10 @@
+  */
+ #define __TLBI_0(op, arg) asm (ARM64_ASM_PREAMBLE                            \
+                              "tlbi " #op "\n"                                \
+-                 ALTERNATIVE("nop\n                   nop",                  \
+-                             "dsb ish\n               tlbi " #op,            \
+-                             ARM64_WORKAROUND_REPEAT_TLBI,                   \
+-                             CONFIG_ARM64_WORKAROUND_REPEAT_TLBI)            \
+                           : : )
+ #define __TLBI_1(op, arg) asm (ARM64_ASM_PREAMBLE                            \
+                              "tlbi " #op ", %x0\n"                           \
+-                 ALTERNATIVE("nop\n                   nop",                  \
+-                             "dsb ish\n               tlbi " #op ", %x0",    \
+-                             ARM64_WORKAROUND_REPEAT_TLBI,                   \
+-                             CONFIG_ARM64_WORKAROUND_REPEAT_TLBI)            \
+                           : : "rZ" (arg))
+ #define __TLBI_N(op, arg, n, ...) __TLBI_##n(op, arg)
+@@ -181,6 +173,34 @@ static inline unsigned long get_trans_granule(void)
+               (__pages >> (5 * (scale) + 1)) - 1;                     \
+       })
++#define __repeat_tlbi_sync(op, arg...)                                                \
++do {                                                                          \
++      if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI))        \
++              break;                                                          \
++      __tlbi(op, ##arg);                                                      \
++      dsb(ish);                                                               \
++} while (0)
++
++/*
++ * Complete broadcast TLB maintenance issued by the host which invalidates
++ * stage 1 information in the host's own translation regime.
++ */
++static inline void __tlbi_sync_s1ish(void)
++{
++      dsb(ish);
++      __repeat_tlbi_sync(vale1is, 0);
++}
++
++/*
++ * Complete broadcast TLB maintenance issued by hyp code which invalidates
++ * stage 1 translation information in any translation regime.
++ */
++static inline void __tlbi_sync_s1ish_hyp(void)
++{
++      dsb(ish);
++      __repeat_tlbi_sync(vale2is, 0);
++}
++
+ /*
+  *    TLB Invalidation
+  *    ================
+@@ -266,7 +286,7 @@ static inline void flush_tlb_all(void)
+ {
+       dsb(ishst);
+       __tlbi(vmalle1is);
+-      dsb(ish);
++      __tlbi_sync_s1ish();
+       isb();
+ }
+@@ -278,7 +298,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
+       asid = __TLBI_VADDR(0, ASID(mm));
+       __tlbi(aside1is, asid);
+       __tlbi_user(aside1is, asid);
+-      dsb(ish);
++      __tlbi_sync_s1ish();
+       mmu_notifier_arch_invalidate_secondary_tlbs(mm, 0, -1UL);
+ }
+@@ -305,20 +325,11 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
+                                 unsigned long uaddr)
+ {
+       flush_tlb_page_nosync(vma, uaddr);
+-      dsb(ish);
++      __tlbi_sync_s1ish();
+ }
+ static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
+ {
+-      /*
+-       * TLB flush deferral is not required on systems which are affected by
+-       * ARM64_WORKAROUND_REPEAT_TLBI, as __tlbi()/__tlbi_user() implementation
+-       * will have two consecutive TLBI instructions with a dsb(ish) in between
+-       * defeating the purpose (i.e save overall 'dsb ish' cost).
+-       */
+-      if (alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI))
+-              return false;
+-
+       return true;
+ }
+@@ -334,7 +345,7 @@ static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
+  */
+ static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
+ {
+-      dsb(ish);
++      __tlbi_sync_s1ish();
+ }
+ /*
+@@ -469,7 +480,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
+ {
+       __flush_tlb_range_nosync(vma->vm_mm, start, end, stride,
+                                last_level, tlb_level);
+-      dsb(ish);
++      __tlbi_sync_s1ish();
+ }
+ static inline void flush_tlb_range(struct vm_area_struct *vma,
+@@ -501,7 +512,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
+       dsb(ishst);
+       __flush_tlb_range_op(vaale1is, start, pages, stride, 0,
+                            TLBI_TTL_UNKNOWN, false, lpa2_is_enabled());
+-      dsb(ish);
++      __tlbi_sync_s1ish();
+       isb();
+ }
+@@ -515,7 +526,7 @@ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr)
+       dsb(ishst);
+       __tlbi(vaae1is, addr);
+-      dsb(ish);
++      __tlbi_sync_s1ish();
+       isb();
+ }
+diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
+index 4a609e9b65de0..b9d4998c97efa 100644
+--- a/arch/arm64/kernel/sys_compat.c
++++ b/arch/arm64/kernel/sys_compat.c
+@@ -37,7 +37,7 @@ __do_compat_cache_op(unsigned long start, unsigned long end)
+                        * We pick the reserved-ASID to minimise the impact.
+                        */
+                       __tlbi(aside1is, __TLBI_VADDR(0, 0));
+-                      dsb(ish);
++                      __tlbi_sync_s1ish();
+               }
+               ret = caches_clean_inval_user_pou(start, start + chunk);
+diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
+index ae8391baebc30..218976287d3fe 100644
+--- a/arch/arm64/kvm/hyp/nvhe/mm.c
++++ b/arch/arm64/kvm/hyp/nvhe/mm.c
+@@ -271,7 +271,7 @@ static void fixmap_clear_slot(struct hyp_fixmap_slot *slot)
+        */
+       dsb(ishst);
+       __tlbi_level(vale2is, __TLBI_VADDR(addr, 0), level);
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+       isb();
+ }
+diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c
+index 48da9ca9763f6..3dc1ce0d27fe6 100644
+--- a/arch/arm64/kvm/hyp/nvhe/tlb.c
++++ b/arch/arm64/kvm/hyp/nvhe/tlb.c
+@@ -169,7 +169,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
+        */
+       dsb(ish);
+       __tlbi(vmalle1is);
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+       isb();
+       exit_vmid_context(&cxt);
+@@ -226,7 +226,7 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
+       dsb(ish);
+       __tlbi(vmalle1is);
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+       isb();
+       exit_vmid_context(&cxt);
+@@ -240,7 +240,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
+       enter_vmid_context(mmu, &cxt, false);
+       __tlbi(vmalls12e1is);
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+       isb();
+       exit_vmid_context(&cxt);
+@@ -266,5 +266,5 @@ void __kvm_flush_vm_context(void)
+       /* Same remark as in enter_vmid_context() */
+       dsb(ish);
+       __tlbi(alle1is);
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+ }
+diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
+index c351b4abd5dbf..cbf8cd2e16735 100644
+--- a/arch/arm64/kvm/hyp/pgtable.c
++++ b/arch/arm64/kvm/hyp/pgtable.c
+@@ -483,7 +483,7 @@ static int hyp_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx,
+               *unmapped += granule;
+       }
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+       isb();
+       mm_ops->put_page(ctx->ptep);
+diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c
+index ec25698186297..35855dadfb1b3 100644
+--- a/arch/arm64/kvm/hyp/vhe/tlb.c
++++ b/arch/arm64/kvm/hyp/vhe/tlb.c
+@@ -115,7 +115,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu,
+        */
+       dsb(ish);
+       __tlbi(vmalle1is);
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+       isb();
+       exit_vmid_context(&cxt);
+@@ -176,7 +176,7 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
+       dsb(ish);
+       __tlbi(vmalle1is);
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+       isb();
+       exit_vmid_context(&cxt);
+@@ -192,7 +192,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu)
+       enter_vmid_context(mmu, &cxt);
+       __tlbi(vmalls12e1is);
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+       isb();
+       exit_vmid_context(&cxt);
+@@ -217,7 +217,7 @@ void __kvm_flush_vm_context(void)
+ {
+       dsb(ishst);
+       __tlbi(alle1is);
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+ }
+ /*
+@@ -358,7 +358,7 @@ int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding)
+       default:
+               ret = -EINVAL;
+       }
+-      dsb(ish);
++      __tlbi_sync_s1ish_hyp();
+       isb();
+       if (mmu)
+-- 
+2.53.0
+
diff --git a/queue-6.18/arm64-tlb-pass-the-corresponding-mm-to-__tlbi_sync_s.patch b/queue-6.18/arm64-tlb-pass-the-corresponding-mm-to-__tlbi_sync_s.patch
new file mode 100644 (file)
index 0000000..ac727e4
--- /dev/null
@@ -0,0 +1,78 @@
+From 4f8d2ea4fb246a4a5b379779f9bdef1190582b1e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 11:00:15 +0100
+Subject: arm64: tlb: Pass the corresponding mm to __tlbi_sync_s1ish()
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+commit d9fb08ba946a6190c371dcd9f9e465d0d52c5021 upstream.
+
+The mm structure will be used for workarounds that need limiting to
+specific tasks.
+
+Acked-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Will Deacon <will@kernel.org>
+Reviewed-by: Will Deacon <will@kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/tlbflush.h | 8 ++++----
+ arch/arm64/kernel/sys_compat.c    | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
+index 387bd86af7021..ba36e91aefb82 100644
+--- a/arch/arm64/include/asm/tlbflush.h
++++ b/arch/arm64/include/asm/tlbflush.h
+@@ -185,7 +185,7 @@ do {                                                                               \
+  * Complete broadcast TLB maintenance issued by the host which invalidates
+  * stage 1 information in the host's own translation regime.
+  */
+-static inline void __tlbi_sync_s1ish(void)
++static inline void __tlbi_sync_s1ish(struct mm_struct *mm)
+ {
+       dsb(ish);
+       __repeat_tlbi_sync(vale1is, 0);
+@@ -310,7 +310,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
+       asid = __TLBI_VADDR(0, ASID(mm));
+       __tlbi(aside1is, asid);
+       __tlbi_user(aside1is, asid);
+-      __tlbi_sync_s1ish();
++      __tlbi_sync_s1ish(mm);
+       mmu_notifier_arch_invalidate_secondary_tlbs(mm, 0, -1UL);
+ }
+@@ -337,7 +337,7 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
+                                 unsigned long uaddr)
+ {
+       flush_tlb_page_nosync(vma, uaddr);
+-      __tlbi_sync_s1ish();
++      __tlbi_sync_s1ish(vma->vm_mm);
+ }
+ static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
+@@ -492,7 +492,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
+ {
+       __flush_tlb_range_nosync(vma->vm_mm, start, end, stride,
+                                last_level, tlb_level);
+-      __tlbi_sync_s1ish();
++      __tlbi_sync_s1ish(vma->vm_mm);
+ }
+ static inline void flush_tlb_range(struct vm_area_struct *vma,
+diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
+index b9d4998c97efa..03fde2677d5be 100644
+--- a/arch/arm64/kernel/sys_compat.c
++++ b/arch/arm64/kernel/sys_compat.c
+@@ -37,7 +37,7 @@ __do_compat_cache_op(unsigned long start, unsigned long end)
+                        * We pick the reserved-ASID to minimise the impact.
+                        */
+                       __tlbi(aside1is, __TLBI_VADDR(0, 0));
+-                      __tlbi_sync_s1ish();
++                      __tlbi_sync_s1ish(current->mm);
+               }
+               ret = caches_clean_inval_user_pou(start, start + chunk);
+-- 
+2.53.0
+
diff --git a/queue-6.18/ipv6-add-null-checks-for-idev-in-srv6-paths.patch b/queue-6.18/ipv6-add-null-checks-for-idev-in-srv6-paths.patch
new file mode 100644 (file)
index 0000000..1feb348
--- /dev/null
@@ -0,0 +1,59 @@
+From e7f5dc975b2cad05b135843a662814acad72e529 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 16 Mar 2026 15:33:01 +0800
+Subject: ipv6: add NULL checks for idev in SRv6 paths
+
+From: Minhong He <heminhong@kylinos.cn>
+
+[ Upstream commit 06413793526251870e20402c39930804f14d59c0 ]
+
+__in6_dev_get() can return NULL when the device has no IPv6 configuration
+(e.g. MTU < IPV6_MIN_MTU or after NETDEV_UNREGISTER).
+
+Add NULL checks for idev returned by __in6_dev_get() in both
+seg6_hmac_validate_skb() and ipv6_srh_rcv() to prevent potential NULL
+pointer dereferences.
+
+Fixes: 1ababeba4a21 ("ipv6: implement dataplane support for rthdr type 4 (Segment Routing Header)")
+Fixes: bf355b8d2c30 ("ipv6: sr: add core files for SR HMAC support")
+Signed-off-by: Minhong He <heminhong@kylinos.cn>
+Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it>
+Link: https://patch.msgid.link/20260316073301.106643-1-heminhong@kylinos.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c   | 4 ++++
+ net/ipv6/seg6_hmac.c | 2 ++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 310836a0cf17b..1d509b6d16bbd 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -379,6 +379,10 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
+       hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
+       idev = __in6_dev_get(skb->dev);
++      if (!idev) {
++              kfree_skb(skb);
++              return -1;
++      }
+       accept_seg6 = min(READ_ONCE(net->ipv6.devconf_all->seg6_enabled),
+                         READ_ONCE(idev->cnf.seg6_enabled));
+diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
+index ee6bac0160ace..e6964c6b0d381 100644
+--- a/net/ipv6/seg6_hmac.c
++++ b/net/ipv6/seg6_hmac.c
+@@ -184,6 +184,8 @@ bool seg6_hmac_validate_skb(struct sk_buff *skb)
+       int require_hmac;
+       idev = __in6_dev_get(skb->dev);
++      if (!idev)
++              return false;
+       srh = (struct ipv6_sr_hdr *)skb_transport_header(skb);
+-- 
+2.53.0
+
diff --git a/queue-6.18/net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch b/queue-6.18/net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch
new file mode 100644 (file)
index 0000000..649487c
--- /dev/null
@@ -0,0 +1,146 @@
+From 0d8406ede5098b92ccd92a55e0fd1491a786a340 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:11:30 +0100
+Subject: net: ethernet: mtk_eth_soc: initialize PPE per-tag-layer MTU
+ registers
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+commit 2dddb34dd0d07b01fa770eca89480a4da4f13153 upstream.
+
+The PPE enforces output frame size limits via per-tag-layer VLAN_MTU
+registers that the driver never initializes. The hardware defaults do
+not account for PPPoE overhead, causing the PPE to punt encapsulated
+frames back to the CPU instead of forwarding them.
+
+Initialize the registers at PPE start and on MTU changes using the
+maximum GMAC MTU. This is a conservative approximation -- the actual
+per-PPE requirement depends on egress path, but using the global
+maximum ensures the limits are never too small.
+
+Fixes: ba37b7caf1ed2 ("net: ethernet: mtk_eth_soc: add support for initializing the PPE")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://patch.msgid.link/ec995ab8ce8be423267a1cc093147a74d2eb9d82.1775789829.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++++++++++-
+ drivers/net/ethernet/mediatek/mtk_ppe.c     | 30 +++++++++++++++++++++
+ drivers/net/ethernet/mediatek/mtk_ppe.h     |  1 +
+ 3 files changed, 52 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 8d3e15bc867d2..0f676bd72832b 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3567,12 +3567,23 @@ static int mtk_device_event(struct notifier_block *n, unsigned long event, void
+       return NOTIFY_DONE;
+ }
++static int mtk_max_gmac_mtu(struct mtk_eth *eth)
++{
++      int i, max_mtu = ETH_DATA_LEN;
++
++      for (i = 0; i < ARRAY_SIZE(eth->netdev); i++)
++              if (eth->netdev[i] && eth->netdev[i]->mtu > max_mtu)
++                      max_mtu = eth->netdev[i]->mtu;
++
++      return max_mtu;
++}
++
+ static int mtk_open(struct net_device *dev)
+ {
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
+       struct mtk_mac *target_mac;
+-      int i, err, ppe_num;
++      int i, err, ppe_num, mtu;
+       ppe_num = eth->soc->ppe_num;
+@@ -3619,6 +3630,10 @@ static int mtk_open(struct net_device *dev)
+                       mtk_gdm_config(eth, target_mac->id, gdm_config);
+               }
++              mtu = mtk_max_gmac_mtu(eth);
++              for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
++                      mtk_ppe_update_mtu(eth->ppe[i], mtu);
++
+               napi_enable(&eth->tx_napi);
+               napi_enable(&eth->rx_napi);
+               mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
+@@ -4312,6 +4327,7 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)
+       int length = new_mtu + MTK_RX_ETH_HLEN;
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
++      int max_mtu, i;
+       if (rcu_access_pointer(eth->prog) &&
+           length > MTK_PP_MAX_BUF_SIZE) {
+@@ -4322,6 +4338,10 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)
+       mtk_set_mcr_max_rx(mac, length);
+       WRITE_ONCE(dev->mtu, new_mtu);
++      max_mtu = mtk_max_gmac_mtu(eth);
++      for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
++              mtk_ppe_update_mtu(eth->ppe[i], max_mtu);
++
+       return 0;
+ }
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
+index ada852adc5f70..fa688a42a22f5 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -973,6 +973,36 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
+       }
+ }
++void mtk_ppe_update_mtu(struct mtk_ppe *ppe, int mtu)
++{
++      int base;
++      u32 val;
++
++      if (!ppe)
++              return;
++
++      /* The PPE checks output frame size against per-tag-layer MTU limits,
++       * treating PPPoE and DSA tags just like 802.1Q VLAN tags. The Linux
++       * device MTU already accounts for PPPoE (PPPOE_SES_HLEN) and DSA tag
++       * overhead, but 802.1Q VLAN tags are handled transparently without
++       * being reflected by the lower device MTU being increased by 4.
++       * Use the maximum MTU across all GMAC interfaces so that PPE output
++       * frame limits are sufficiently high regardless of which port a flow
++       * egresses through.
++       */
++      base = ETH_HLEN + mtu;
++
++      val = FIELD_PREP(MTK_PPE_VLAN_MTU0_NONE, base) |
++            FIELD_PREP(MTK_PPE_VLAN_MTU0_1TAG, base + VLAN_HLEN);
++      ppe_w32(ppe, MTK_PPE_VLAN_MTU0, val);
++
++      val = FIELD_PREP(MTK_PPE_VLAN_MTU1_2TAG,
++                       base + 2 * VLAN_HLEN) |
++            FIELD_PREP(MTK_PPE_VLAN_MTU1_3TAG,
++                       base + 3 * VLAN_HLEN);
++      ppe_w32(ppe, MTK_PPE_VLAN_MTU1, val);
++}
++
+ void mtk_ppe_start(struct mtk_ppe *ppe)
+ {
+       u32 val;
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
+index 223f709e2704f..ba85e39a155bf 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -346,6 +346,7 @@ struct mtk_ppe {
+ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
+ void mtk_ppe_deinit(struct mtk_eth *eth);
++void mtk_ppe_update_mtu(struct mtk_ppe *ppe, int mtu);
+ void mtk_ppe_start(struct mtk_ppe *ppe);
+ int mtk_ppe_stop(struct mtk_ppe *ppe);
+ int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
+-- 
+2.53.0
+
diff --git a/queue-6.18/series b/queue-6.18/series
new file mode 100644 (file)
index 0000000..6a67dad
--- /dev/null
@@ -0,0 +1,8 @@
+arm64-tlb-allow-xzr-argument-to-tlbi-ops.patch
+arm64-tlb-optimize-arm64_workaround_repeat_tlbi.patch
+arm64-tlb-introduce-__tlbi_sync_s1ish_-kernel-batch-.patch
+arm64-tlb-pass-the-corresponding-mm-to-__tlbi_sync_s.patch
+arm64-cputype-add-c1-pro-definitions.patch
+arm64-errata-work-around-early-cme-dvmsync-acknowled.patch
+ipv6-add-null-checks-for-idev-in-srv6-paths.patch
+net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch
diff --git a/queue-6.6/i40e-fix-preempt-count-leak-in-napi-poll-tracepoint.patch b/queue-6.6/i40e-fix-preempt-count-leak-in-napi-poll-tracepoint.patch
new file mode 100644 (file)
index 0000000..2784be4
--- /dev/null
@@ -0,0 +1,49 @@
+From 889b7bdce4c73577a1f8b956f1a6ea285acaf2cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 15:18:38 +0800
+Subject: i40e: Fix preempt count leak in napi poll tracepoint
+
+From: Thomas Gleixner <tglx@kernel.org>
+
+[ Upstream commit 4b3d54a85bd37ebf2d9836f0d0de775c0ff21af9 ]
+
+Using get_cpu() in the tracepoint assignment causes an obvious preempt
+count leak because nothing invokes put_cpu() to undo it:
+
+  softirq: huh, entered softirq 3 NET_RX with preempt_count 00000100, exited with 00000101?
+
+This clearly has seen a lot of testing in the last 3+ years...
+
+Use smp_processor_id() instead.
+
+Fixes: 6d4d584a7ea8 ("i40e: Add i40e_napi_poll tracepoint")
+Signed-off-by: Thomas Gleixner <tglx@kernel.org>
+Cc: Tony Nguyen <anthony.l.nguyen@intel.com>
+Cc: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Cc: intel-wired-lan@lists.osuosl.org
+Cc: netdev@vger.kernel.org
+Reviewed-by: Joe Damato <joe@dama.to>
+Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Charles Xu <charles_xu@189.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_trace.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_trace.h b/drivers/net/ethernet/intel/i40e/i40e_trace.h
+index 33b4e30f5e004..9b735a9e21140 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_trace.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_trace.h
+@@ -88,7 +88,7 @@ TRACE_EVENT(i40e_napi_poll,
+               __entry->rx_clean_complete = rx_clean_complete;
+               __entry->tx_clean_complete = tx_clean_complete;
+               __entry->irq_num = q->irq_num;
+-              __entry->curr_cpu = get_cpu();
++              __entry->curr_cpu = smp_processor_id();
+               __assign_str(qname, q->name);
+               __assign_str(dev_name, napi->dev ? napi->dev->name : NO_DEV);
+               __assign_bitmask(irq_affinity, cpumask_bits(&q->affinity_mask),
+-- 
+2.53.0
+
diff --git a/queue-6.6/ipv6-add-null-checks-for-idev-in-srv6-paths.patch b/queue-6.6/ipv6-add-null-checks-for-idev-in-srv6-paths.patch
new file mode 100644 (file)
index 0000000..c0f9d5c
--- /dev/null
@@ -0,0 +1,60 @@
+From 2b23ea97b2bbe6d82d4e0be54a70fc90d6951957 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 13:42:58 +0800
+Subject: ipv6: add NULL checks for idev in SRv6 paths
+
+From: Minhong He <heminhong@kylinos.cn>
+
+[ Upstream commit 06413793526251870e20402c39930804f14d59c0 ]
+
+__in6_dev_get() can return NULL when the device has no IPv6 configuration
+(e.g. MTU < IPV6_MIN_MTU or after NETDEV_UNREGISTER).
+
+Add NULL checks for idev returned by __in6_dev_get() in both
+seg6_hmac_validate_skb() and ipv6_srh_rcv() to prevent potential NULL
+pointer dereferences.
+
+Fixes: 1ababeba4a21 ("ipv6: implement dataplane support for rthdr type 4 (Segment Routing Header)")
+Fixes: bf355b8d2c30 ("ipv6: sr: add core files for SR HMAC support")
+Signed-off-by: Minhong He <heminhong@kylinos.cn>
+Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it>
+Link: https://patch.msgid.link/20260316073301.106643-1-heminhong@kylinos.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/exthdrs.c   | 4 ++++
+ net/ipv6/seg6_hmac.c | 2 ++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
+index 676284b6efe8b..a8790163e8b6d 100644
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -378,6 +378,10 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
+       hdr = (struct ipv6_sr_hdr *)skb_transport_header(skb);
+       idev = __in6_dev_get(skb->dev);
++      if (!idev) {
++              kfree_skb(skb);
++              return -1;
++      }
+       accept_seg6 = net->ipv6.devconf_all->seg6_enabled;
+       if (accept_seg6 > idev->cnf.seg6_enabled)
+diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
+index 6e15a65faeccd..bf97bf5ac1387 100644
+--- a/net/ipv6/seg6_hmac.c
++++ b/net/ipv6/seg6_hmac.c
+@@ -244,6 +244,8 @@ bool seg6_hmac_validate_skb(struct sk_buff *skb)
+       struct inet6_dev *idev;
+       idev = __in6_dev_get(skb->dev);
++      if (!idev)
++              return false;
+       srh = (struct ipv6_sr_hdr *)skb_transport_header(skb);
+-- 
+2.53.0
+
diff --git a/queue-6.6/md-raid1-raid10-don-t-ignore-io-flags.patch b/queue-6.6/md-raid1-raid10-don-t-ignore-io-flags.patch
new file mode 100644 (file)
index 0000000..0996d8c
--- /dev/null
@@ -0,0 +1,111 @@
+From f39d7a91b60a71420c5ef55261eb91230a62a733 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:20:53 +0800
+Subject: md/raid1,raid10: don't ignore IO flags
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+commit e879a0d9cb086c8e52ce6c04e5bfa63825a6213c upstream.
+
+If blk-wbt is enabled by default, it's found that raid write performance
+is quite bad because all IO are throttled by wbt of underlying disks,
+due to flag REQ_IDLE is ignored. And turns out this behaviour exist since
+blk-wbt is introduced.
+
+Other than REQ_IDLE, other flags should not be ignored as well, for
+example REQ_META can be set for filesystems, clearing it can cause priority
+reverse problems; And REQ_NOWAIT should not be cleared as well, because
+io will wait instead of failing directly in underlying disks.
+
+Fix those problems by keep IO flags from master bio.
+
+Fises: f51d46d0e7cb ("md: add support for REQ_NOWAIT")
+Fixes: e34cbd307477 ("blk-wbt: add general throttling mechanism")
+Fixes: 5404bc7a87b9 ("[PATCH] Allow file systems to differentiate between data and meta reads")
+Link: https://lore.kernel.org/linux-raid/20250227121657.832356-1-yukuai1@huaweicloud.com
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+[ Harshit: Resolve conflicts due to missing commit: f2a38abf5f1c
+  ("md/raid1: Atomic write support") and  commit: a1d9b4fd42d9
+  ("md/raid10: Atomic write support") in 6.12.y, we don't have Atomic
+  writes feature in 6.12.y ]
+Signed-off-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ Based on Harshit's backport for 6.12, fixed minor conflicts for 6.6. ]
+Signed-off-by: Charles Xu <charles_xu@189.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/raid1.c  | 4 ----
+ drivers/md/raid10.c | 7 -------
+ 2 files changed, 11 deletions(-)
+
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 4c1f86ca55208..d313e9834d447 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -1214,8 +1214,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
+       struct raid1_info *mirror;
+       struct bio *read_bio;
+       struct bitmap *bitmap = mddev->bitmap;
+-      const enum req_op op = bio_op(bio);
+-      const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
+       int max_sectors;
+       int rdisk;
+       bool r1bio_existed = !!r1_bio;
+@@ -1315,7 +1313,6 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio,
+       read_bio->bi_iter.bi_sector = r1_bio->sector +
+               mirror->rdev->data_offset;
+       read_bio->bi_end_io = raid1_end_read_request;
+-      read_bio->bi_opf = op | do_sync;
+       if (test_bit(FailFast, &mirror->rdev->flags) &&
+           test_bit(R1BIO_FailFast, &r1_bio->state))
+               read_bio->bi_opf |= MD_FAILFAST;
+@@ -1537,7 +1534,6 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
+               mbio->bi_iter.bi_sector = (r1_bio->sector + rdev->data_offset);
+               mbio->bi_end_io = raid1_end_write_request;
+-              mbio->bi_opf = bio_op(bio) | (bio->bi_opf & (REQ_SYNC | REQ_FUA));
+               if (test_bit(FailFast, &rdev->flags) &&
+                   !test_bit(WriteMostly, &rdev->flags) &&
+                   conf->raid_disks - mddev->degraded > 1)
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index 8546ef98bfa7e..6bcf6852c2000 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1168,8 +1168,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
+ {
+       struct r10conf *conf = mddev->private;
+       struct bio *read_bio;
+-      const enum req_op op = bio_op(bio);
+-      const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
+       int max_sectors;
+       struct md_rdev *rdev;
+       char b[BDEVNAME_SIZE];
+@@ -1250,7 +1248,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio,
+       read_bio->bi_iter.bi_sector = r10_bio->devs[slot].addr +
+               choose_data_offset(r10_bio, rdev);
+       read_bio->bi_end_io = raid10_end_read_request;
+-      read_bio->bi_opf = op | do_sync;
+       if (test_bit(FailFast, &rdev->flags) &&
+           test_bit(R10BIO_FailFast, &r10_bio->state))
+               read_bio->bi_opf |= MD_FAILFAST;
+@@ -1267,9 +1264,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
+                                 struct bio *bio, bool replacement,
+                                 int n_copy)
+ {
+-      const enum req_op op = bio_op(bio);
+-      const blk_opf_t do_sync = bio->bi_opf & REQ_SYNC;
+-      const blk_opf_t do_fua = bio->bi_opf & REQ_FUA;
+       unsigned long flags;
+       struct r10conf *conf = mddev->private;
+       struct md_rdev *rdev;
+@@ -1295,7 +1289,6 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
+       mbio->bi_iter.bi_sector = (r10_bio->devs[n_copy].addr +
+                                  choose_data_offset(r10_bio, rdev));
+       mbio->bi_end_io = raid10_end_write_request;
+-      mbio->bi_opf = op | do_sync | do_fua;
+       if (!replacement && test_bit(FailFast,
+                                    &conf->mirrors[devnum].rdev->flags)
+                        && enough(conf, devnum))
+-- 
+2.53.0
+
diff --git a/queue-6.6/net-annotate-data-races-around-sk-sk_-data_ready-wri.patch b/queue-6.6/net-annotate-data-races-around-sk-sk_-data_ready-wri.patch
new file mode 100644 (file)
index 0000000..1c38d47
--- /dev/null
@@ -0,0 +1,262 @@
+From e6d40ae68224b135b9761fbd9741769b27da648b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Apr 2026 10:16:26 +0800
+Subject: net: annotate data-races around sk->sk_{data_ready,write_space}
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 2ef2b20cf4e04ac8a6ba68493f8780776ff84300 ]
+
+skmsg (and probably other layers) are changing these pointers
+while other cpus might read them concurrently.
+
+Add corresponding READ_ONCE()/WRITE_ONCE() annotations
+for UDP, TCP and AF_UNIX.
+
+Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
+Reported-by: syzbot+87f770387a9e5dc6b79b@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/netdev/699ee9fc.050a0220.1cd54b.0009.GAE@google.com/
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: Jakub Sitnicki <jakub@cloudflare.com>
+Cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
+Link: https://patch.msgid.link/20260225131547.1085509-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Leon Chen <leonchen.oss@139.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/core/skmsg.c         | 14 +++++++-------
+ net/ipv4/tcp.c           |  4 ++--
+ net/ipv4/tcp_bpf.c       |  2 +-
+ net/ipv4/tcp_input.c     | 14 ++++++++------
+ net/ipv4/tcp_minisocks.c |  2 +-
+ net/ipv4/udp.c           |  3 ++-
+ net/ipv4/udp_bpf.c       |  2 +-
+ net/unix/af_unix.c       |  8 ++++----
+ 8 files changed, 26 insertions(+), 23 deletions(-)
+
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index e2bba1e86752e..14208d32eeaf3 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -1204,8 +1204,8 @@ void sk_psock_start_strp(struct sock *sk, struct sk_psock *psock)
+               return;
+       psock->saved_data_ready = sk->sk_data_ready;
+-      sk->sk_data_ready = sk_psock_strp_data_ready;
+-      sk->sk_write_space = sk_psock_write_space;
++      WRITE_ONCE(sk->sk_data_ready, sk_psock_strp_data_ready);
++      WRITE_ONCE(sk->sk_write_space, sk_psock_write_space);
+ }
+ void sk_psock_stop_strp(struct sock *sk, struct sk_psock *psock)
+@@ -1215,8 +1215,8 @@ void sk_psock_stop_strp(struct sock *sk, struct sk_psock *psock)
+       if (!psock->saved_data_ready)
+               return;
+-      sk->sk_data_ready = psock->saved_data_ready;
+-      psock->saved_data_ready = NULL;
++      WRITE_ONCE(sk->sk_data_ready, psock->saved_data_ready);
++      WRITE_ONCE(psock->saved_data_ready, NULL);
+       strp_stop(&psock->strp);
+ }
+@@ -1298,8 +1298,8 @@ void sk_psock_start_verdict(struct sock *sk, struct sk_psock *psock)
+               return;
+       psock->saved_data_ready = sk->sk_data_ready;
+-      sk->sk_data_ready = sk_psock_verdict_data_ready;
+-      sk->sk_write_space = sk_psock_write_space;
++      WRITE_ONCE(sk->sk_data_ready, sk_psock_verdict_data_ready);
++      WRITE_ONCE(sk->sk_write_space, sk_psock_write_space);
+ }
+ void sk_psock_stop_verdict(struct sock *sk, struct sk_psock *psock)
+@@ -1310,6 +1310,6 @@ void sk_psock_stop_verdict(struct sock *sk, struct sk_psock *psock)
+       if (!psock->saved_data_ready)
+               return;
+-      sk->sk_data_ready = psock->saved_data_ready;
++      WRITE_ONCE(sk->sk_data_ready, psock->saved_data_ready);
+       psock->saved_data_ready = NULL;
+ }
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 021e1bdbddcb8..33b724dcde6ed 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -1333,7 +1333,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size)
+       err = sk_stream_error(sk, flags, err);
+       /* make sure we wake any epoll edge trigger waiter */
+       if (unlikely(tcp_rtx_and_write_queues_empty(sk) && err == -EAGAIN)) {
+-              sk->sk_write_space(sk);
++              READ_ONCE(sk->sk_write_space)(sk);
+               tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED);
+       }
+       return err;
+@@ -3709,7 +3709,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
+               break;
+       case TCP_NOTSENT_LOWAT:
+               WRITE_ONCE(tp->notsent_lowat, val);
+-              sk->sk_write_space(sk);
++              READ_ONCE(sk->sk_write_space)(sk);
+               break;
+       case TCP_INQ:
+               if (val > 1 || val < 0)
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index 06a185bb1e35c..da5e14ec8ed6d 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -725,7 +725,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
+                       WRITE_ONCE(sk->sk_prot->unhash, psock->saved_unhash);
+                       tcp_update_ulp(sk, psock->sk_proto, psock->saved_write_space);
+               } else {
+-                      sk->sk_write_space = psock->saved_write_space;
++                      WRITE_ONCE(sk->sk_write_space, psock->saved_write_space);
+                       /* Pairs with lockless read in sk_clone_lock() */
+                       sock_replace_proto(sk, psock->sk_proto);
+               }
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index bec3bbf57a4f1..359d36be04829 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -4936,7 +4936,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
+       if (unlikely(tcp_try_rmem_schedule(sk, skb, skb->truesize))) {
+               NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPOFODROP);
+-              sk->sk_data_ready(sk);
++              READ_ONCE(sk->sk_data_ready)(sk);
+               tcp_drop_reason(sk, skb, SKB_DROP_REASON_PROTO_MEM);
+               return;
+       }
+@@ -5143,7 +5143,7 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
+ void tcp_data_ready(struct sock *sk)
+ {
+       if (tcp_epollin_ready(sk, sk->sk_rcvlowat) || sock_flag(sk, SOCK_DONE))
+-              sk->sk_data_ready(sk);
++              READ_ONCE(sk->sk_data_ready)(sk);
+ }
+ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
+@@ -5189,7 +5189,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
+                       inet_csk(sk)->icsk_ack.pending |=
+                                       (ICSK_ACK_NOMEM | ICSK_ACK_NOW);
+                       inet_csk_schedule_ack(sk);
+-                      sk->sk_data_ready(sk);
++                      READ_ONCE(sk->sk_data_ready)(sk);
+                       if (skb_queue_len(&sk->sk_receive_queue)) {
+                               reason = SKB_DROP_REASON_PROTO_MEM;
+@@ -5626,7 +5626,9 @@ static void tcp_new_space(struct sock *sk)
+               tp->snd_cwnd_stamp = tcp_jiffies32;
+       }
+-      INDIRECT_CALL_1(sk->sk_write_space, sk_stream_write_space, sk);
++      INDIRECT_CALL_1(READ_ONCE(sk->sk_write_space),
++                      sk_stream_write_space,
++                      sk);
+ }
+ /* Caller made space either from:
+@@ -5832,7 +5834,7 @@ static void tcp_urg(struct sock *sk, struct sk_buff *skb, const struct tcphdr *t
+                               BUG();
+                       WRITE_ONCE(tp->urg_data, TCP_URG_VALID | tmp);
+                       if (!sock_flag(sk, SOCK_DEAD))
+-                              sk->sk_data_ready(sk);
++                              READ_ONCE(sk->sk_data_ready)(sk);
+               }
+       }
+ }
+@@ -7216,7 +7218,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
+                       sock_put(fastopen_sk);
+                       goto drop_and_free;
+               }
+-              sk->sk_data_ready(sk);
++              READ_ONCE(sk->sk_data_ready)(sk);
+               bh_unlock_sock(fastopen_sk);
+               sock_put(fastopen_sk);
+       } else {
+diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
+index ddb90b9057e75..2eea9672ca01e 100644
+--- a/net/ipv4/tcp_minisocks.c
++++ b/net/ipv4/tcp_minisocks.c
+@@ -876,7 +876,7 @@ int tcp_child_process(struct sock *parent, struct sock *child,
+               ret = tcp_rcv_state_process(child, skb);
+               /* Wakeup parent, send SIGIO */
+               if (state == TCP_SYN_RECV && child->sk_state != state)
+-                      parent->sk_data_ready(parent);
++                      READ_ONCE(parent->sk_data_ready)(parent);
+       } else {
+               /* Alas, it is possible again, because we do lookup
+                * in main socket hash table and lock on listening
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index f301871fa2b1a..3bc1ba937a212 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1560,7 +1560,8 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
+       spin_unlock(&list->lock);
+       if (!sock_flag(sk, SOCK_DEAD))
+-              INDIRECT_CALL_1(sk->sk_data_ready, sock_def_readable, sk);
++              INDIRECT_CALL_1(READ_ONCE(sk->sk_data_ready),
++                              sock_def_readable, sk);
+       busylock_release(busy);
+       return 0;
+diff --git a/net/ipv4/udp_bpf.c b/net/ipv4/udp_bpf.c
+index 91233e37cd97a..779a3a03762f1 100644
+--- a/net/ipv4/udp_bpf.c
++++ b/net/ipv4/udp_bpf.c
+@@ -158,7 +158,7 @@ int udp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
+       int family = sk->sk_family == AF_INET ? UDP_BPF_IPV4 : UDP_BPF_IPV6;
+       if (restore) {
+-              sk->sk_write_space = psock->saved_write_space;
++              WRITE_ONCE(sk->sk_write_space, psock->saved_write_space);
+               sock_replace_proto(sk, psock->sk_proto);
+               return 0;
+       }
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index f89cd01247f6b..6bc7aef06a5be 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1678,7 +1678,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
+       __skb_queue_tail(&other->sk_receive_queue, skb);
+       spin_unlock(&other->sk_receive_queue.lock);
+       unix_state_unlock(other);
+-      other->sk_data_ready(other);
++      READ_ONCE(other->sk_data_ready)(other);
+       sock_put(other);
+       return 0;
+@@ -2138,7 +2138,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
+       scm_stat_add(other, skb);
+       skb_queue_tail(&other->sk_receive_queue, skb);
+       unix_state_unlock(other);
+-      other->sk_data_ready(other);
++      READ_ONCE(other->sk_data_ready)(other);
+       sock_put(other);
+       scm_destroy(&scm);
+       return len;
+@@ -2206,7 +2206,7 @@ static int queue_oob(struct socket *sock, struct msghdr *msg, struct sock *other
+       sk_send_sigurg(other);
+       unix_state_unlock(other);
+-      other->sk_data_ready(other);
++      READ_ONCE(other->sk_data_ready)(other);
+       return err;
+ }
+@@ -2317,7 +2317,7 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
+               scm_stat_add(other, skb);
+               skb_queue_tail(&other->sk_receive_queue, skb);
+               unix_state_unlock(other);
+-              other->sk_data_ready(other);
++              READ_ONCE(other->sk_data_ready)(other);
+               sent += size;
+       }
+-- 
+2.53.0
+
diff --git a/queue-6.6/net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch b/queue-6.6/net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch
new file mode 100644 (file)
index 0000000..b0e0859
--- /dev/null
@@ -0,0 +1,145 @@
+From 3b7c17677dd8d2db1677766cf35128aa5ca9e50b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 16:11:06 +0100
+Subject: net: ethernet: mtk_eth_soc: initialize PPE per-tag-layer MTU
+ registers
+
+From: Daniel Golle <daniel@makrotopia.org>
+
+commit 2dddb34dd0d07b01fa770eca89480a4da4f13153 upstream.
+
+The PPE enforces output frame size limits via per-tag-layer VLAN_MTU
+registers that the driver never initializes. The hardware defaults do
+not account for PPPoE overhead, causing the PPE to punt encapsulated
+frames back to the CPU instead of forwarding them.
+
+Initialize the registers at PPE start and on MTU changes using the
+maximum GMAC MTU. This is a conservative approximation -- the actual
+per-PPE requirement depends on egress path, but using the global
+maximum ensures the limits are never too small.
+
+Fixes: ba37b7caf1ed ("net: ethernet: mtk_eth_soc: add support for initializing the PPE")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://patch.msgid.link/ec995ab8ce8be423267a1cc093147a74d2eb9d82.1775789829.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++++++++++-
+ drivers/net/ethernet/mediatek/mtk_ppe.c     | 30 +++++++++++++++++++++
+ drivers/net/ethernet/mediatek/mtk_ppe.h     |  1 +
+ 3 files changed, 52 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index e2d3bda1dc923..74cb96dbff9ee 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3368,11 +3368,22 @@ static int mtk_device_event(struct notifier_block *n, unsigned long event, void
+       return NOTIFY_DONE;
+ }
++static int mtk_max_gmac_mtu(struct mtk_eth *eth)
++{
++      int i, max_mtu = ETH_DATA_LEN;
++
++      for (i = 0; i < ARRAY_SIZE(eth->netdev); i++)
++              if (eth->netdev[i] && eth->netdev[i]->mtu > max_mtu)
++                      max_mtu = eth->netdev[i]->mtu;
++
++      return max_mtu;
++}
++
+ static int mtk_open(struct net_device *dev)
+ {
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
+-      int i, err;
++      int i, err, mtu;
+       err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
+       if (err) {
+@@ -3400,6 +3411,10 @@ static int mtk_open(struct net_device *dev)
+                                                 : MTK_GDMA_TO_PDMA;
+               mtk_gdm_config(eth, gdm_config);
++              mtu = mtk_max_gmac_mtu(eth);
++              for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
++                      mtk_ppe_update_mtu(eth->ppe[i], mtu);
++
+               napi_enable(&eth->tx_napi);
+               napi_enable(&eth->rx_napi);
+               mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
+@@ -4088,6 +4103,7 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)
+       int length = new_mtu + MTK_RX_ETH_HLEN;
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
++      int max_mtu, i;
+       if (rcu_access_pointer(eth->prog) &&
+           length > MTK_PP_MAX_BUF_SIZE) {
+@@ -4098,6 +4114,10 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)
+       mtk_set_mcr_max_rx(mac, length);
+       dev->mtu = new_mtu;
++      max_mtu = mtk_max_gmac_mtu(eth);
++      for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
++              mtk_ppe_update_mtu(eth->ppe[i], max_mtu);
++
+       return 0;
+ }
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
+index 6e222a000bf7e..1e033d63b4510 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -971,6 +971,36 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
+       }
+ }
++void mtk_ppe_update_mtu(struct mtk_ppe *ppe, int mtu)
++{
++      int base;
++      u32 val;
++
++      if (!ppe)
++              return;
++
++      /* The PPE checks output frame size against per-tag-layer MTU limits,
++       * treating PPPoE and DSA tags just like 802.1Q VLAN tags. The Linux
++       * device MTU already accounts for PPPoE (PPPOE_SES_HLEN) and DSA tag
++       * overhead, but 802.1Q VLAN tags are handled transparently without
++       * being reflected by the lower device MTU being increased by 4.
++       * Use the maximum MTU across all GMAC interfaces so that PPE output
++       * frame limits are sufficiently high regardless of which port a flow
++       * egresses through.
++       */
++      base = ETH_HLEN + mtu;
++
++      val = FIELD_PREP(MTK_PPE_VLAN_MTU0_NONE, base) |
++            FIELD_PREP(MTK_PPE_VLAN_MTU0_1TAG, base + VLAN_HLEN);
++      ppe_w32(ppe, MTK_PPE_VLAN_MTU0, val);
++
++      val = FIELD_PREP(MTK_PPE_VLAN_MTU1_2TAG,
++                       base + 2 * VLAN_HLEN) |
++            FIELD_PREP(MTK_PPE_VLAN_MTU1_3TAG,
++                       base + 3 * VLAN_HLEN);
++      ppe_w32(ppe, MTK_PPE_VLAN_MTU1, val);
++}
++
+ void mtk_ppe_start(struct mtk_ppe *ppe)
+ {
+       u32 val;
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
+index e3d0ec72bc699..11c76fb8289ac 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -346,6 +346,7 @@ struct mtk_ppe {
+ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
+ void mtk_ppe_deinit(struct mtk_eth *eth);
++void mtk_ppe_update_mtu(struct mtk_ppe *ppe, int mtu);
+ void mtk_ppe_start(struct mtk_ppe *ppe);
+ int mtk_ppe_stop(struct mtk_ppe *ppe);
+ int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
+-- 
+2.53.0
+
diff --git a/queue-6.6/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch b/queue-6.6/pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch
new file mode 100644 (file)
index 0000000..5d1d440
--- /dev/null
@@ -0,0 +1,97 @@
+From d391355ba7f404ed48f52f2d29838b2e4c649602 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 10:41:52 -0400
+Subject: PCI: endpoint: pci-epf-vntb: Remove duplicate resource teardown
+
+From: Koichiro Den <den@valinux.co.jp>
+
+[ Upstream commit 0da63230d3ec1ec5fcc443a2314233e95bfece54 ]
+
+epf_ntb_epc_destroy() duplicates the teardown that the caller is
+supposed to perform later. This leads to an oops when .allow_link fails
+or when .drop_link is performed. The following is an example oops of the
+former case:
+
+  Unable to handle kernel paging request at virtual address dead000000000108
+  [...]
+  [dead000000000108] address between user and kernel address ranges
+  Internal error: Oops: 0000000096000044 [#1]  SMP
+  [...]
+  Call trace:
+   pci_epc_remove_epf+0x78/0xe0 (P)
+   pci_primary_epc_epf_link+0x88/0xa8
+   configfs_symlink+0x1f4/0x5a0
+   vfs_symlink+0x134/0x1d8
+   do_symlinkat+0x88/0x138
+   __arm64_sys_symlinkat+0x74/0xe0
+  [...]
+
+Remove the helper, and drop pci_epc_put(). EPC device refcounting is
+tied to the configfs EPC group lifetime, and pci_epc_put() in the
+.drop_link path is sufficient.
+
+Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
+Signed-off-by: Koichiro Den <den@valinux.co.jp>
+Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260226084142.2226875-2-den@valinux.co.jp
+[ adjusted context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-vntb.c | 18 +-----------------
+ 1 file changed, 1 insertion(+), 17 deletions(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+index 33c3f9b980e68..b0cc081490853 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
++++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+@@ -673,18 +673,6 @@ static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb, int num_mws)
+       }
+ }
+-/**
+- * epf_ntb_epc_destroy() - Cleanup NTB EPC interface
+- * @ntb: NTB device that facilitates communication between HOST and VHOST
+- *
+- * Wrapper for epf_ntb_epc_destroy_interface() to cleanup all the NTB interfaces
+- */
+-static void epf_ntb_epc_destroy(struct epf_ntb *ntb)
+-{
+-      pci_epc_remove_epf(ntb->epf->epc, ntb->epf, 0);
+-      pci_epc_put(ntb->epf->epc);
+-}
+-
+ /**
+  * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
+  * constructs (scratchpad region, doorbell, memorywindow)
+@@ -1328,7 +1316,7 @@ static int epf_ntb_bind(struct pci_epf *epf)
+       ret = epf_ntb_init_epc_bar(ntb);
+       if (ret) {
+               dev_err(dev, "Failed to create NTB EPC\n");
+-              goto err_bar_init;
++              return ret;
+       }
+       ret = epf_ntb_config_spad_bar_alloc(ntb);
+@@ -1368,9 +1356,6 @@ static int epf_ntb_bind(struct pci_epf *epf)
+ err_bar_alloc:
+       epf_ntb_config_spad_bar_free(ntb);
+-err_bar_init:
+-      epf_ntb_epc_destroy(ntb);
+-
+       return ret;
+ }
+@@ -1386,7 +1371,6 @@ static void epf_ntb_unbind(struct pci_epf *epf)
+       epf_ntb_epc_cleanup(ntb);
+       epf_ntb_config_spad_bar_free(ntb);
+-      epf_ntb_epc_destroy(ntb);
+       pci_unregister_driver(&vntb_pci_driver);
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.6/revert-perf-unwind-libdw-fix-invalid-reference-count.patch b/queue-6.6/revert-perf-unwind-libdw-fix-invalid-reference-count.patch
new file mode 100644 (file)
index 0000000..1fc4ac1
--- /dev/null
@@ -0,0 +1,53 @@
+From 30d2933e88c73898bff227d5d2c06a31689c1274 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 01:32:22 +0900
+Subject: Revert "perf unwind-libdw: Fix invalid reference counts"
+
+From: Kenta Akagi <k@mgml.me>
+
+This reverts commit eddddf4ed7f69697cb54e714e773f764c8d3b67e.
+
+Upstream commit f815fc0c66e7 ("perf unwind-libdw: Fix invalid reference counts"),
+was backported to v6.6.128 as eddddf4ed7f6.
+
+However, this commit depends on map_symbol__exit, which was introduced
+in v6.7 as commit 56e144fe9826 ("perf mem_info: Add and use
+map_symbol__exit and addr_map_symbol__exit") and is absent in v6.6.y.
+This results in a build failure.
+
+This is a revert of a backport, so there is no upstream commit.
+
+Signed-off-by: Kenta Akagi <k@mgml.me>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/unwind-libdw.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
+index bd027fdf6af17..6013335a8daea 100644
+--- a/tools/perf/util/unwind-libdw.c
++++ b/tools/perf/util/unwind-libdw.c
+@@ -133,8 +133,8 @@ static int entry(u64 ip, struct unwind_info *ui)
+       }
+       e->ip     = ip;
+-      e->ms.maps = maps__get(al.maps);
+-      e->ms.map = map__get(al.map);
++      e->ms.maps = al.maps;
++      e->ms.map = al.map;
+       e->ms.sym = al.sym;
+       pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
+@@ -319,9 +319,6 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
+       if (err)
+               pr_debug("unwind: failed with '%s'\n", dwfl_errmsg(-1));
+-      for (i = 0; i < ui->idx; i++)
+-              map_symbol__exit(&ui->entries[i].ms);
+-
+       dwfl_end(ui->dwfl);
+       free(ui);
+       return 0;
+-- 
+2.53.0
+
index d7660f72a4499071fd06192b3781bdcb821aa55f..06f10262c7bc87f8b4505739f4230f0dee8d7b53 100644 (file)
@@ -123,3 +123,11 @@ media-as102-fix-to-not-free-memory-after-the-device-is-registered-in-as102_usb_p
 nilfs2-fix-null-i_assoc_inode-dereference-in-nilfs_mdt_save_to_shadow_map.patch
 media-vidtv-fix-pass-by-value-structs-causing-msan-warnings.patch
 media-hackrf-fix-to-not-free-memory-after-the-device-is-registered-in-hackrf_probe.patch
+revert-perf-unwind-libdw-fix-invalid-reference-count.patch
+pci-endpoint-pci-epf-vntb-remove-duplicate-resource-.patch
+ipv6-add-null-checks-for-idev-in-srv6-paths.patch
+md-raid1-raid10-don-t-ignore-io-flags.patch
+wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
+net-ethernet-mtk_eth_soc-initialize-ppe-per-tag-laye.patch
+i40e-fix-preempt-count-leak-in-napi-poll-tracepoint.patch
+net-annotate-data-races-around-sk-sk_-data_ready-wri.patch
diff --git a/queue-6.6/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch b/queue-6.6/wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
new file mode 100644 (file)
index 0000000..5db5125
--- /dev/null
@@ -0,0 +1,107 @@
+From 36620529580ac67e7ab56ac7211d049adaf015f4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Apr 2026 10:43:09 +0800
+Subject: wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
+
+From: Felix Fietkau <nbd@nbd.name>
+
+[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
+
+ieee80211_tx_prepare_skb() has three error paths, but only two of them
+free the skb. The first error path (ieee80211_tx_prepare() returning
+TX_DROP) does not free it, while invoke_tx_handlers() failure and the
+fragmentation check both do.
+
+Add kfree_skb() to the first error path so all three are consistent,
+and remove the now-redundant frees in callers (ath9k, mt76,
+mac80211_hwsim) to avoid double-free.
+
+Document the skb ownership guarantee in the function's kdoc.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name
+Fixes: 06be6b149f7e ("mac80211: add ieee80211_tx_prepare_skb() helper function")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
+ introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning")
+ after linux-6.14.]
+Signed-off-by: Li hongliang <1468888505@139.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wireless/ath/ath9k/channel.c      | 6 ++----
+ drivers/net/wireless/virtual/mac80211_hwsim.c | 1 -
+ include/net/mac80211.h                        | 4 ++++
+ net/mac80211/tx.c                             | 4 +++-
+ 4 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
+index 571062f2e82a7..ba8ec5112afe8 100644
+--- a/drivers/net/wireless/ath/ath9k/channel.c
++++ b/drivers/net/wireless/ath/ath9k/channel.c
+@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
+       skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+       if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
+-              goto error;
++              return;
+       txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
+       if (ath_tx_start(sc->hw, skb, &txctl))
+@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
+               skb->priority = 7;
+               skb_set_queue_mapping(skb, IEEE80211_AC_VO);
+-              if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
+-                      dev_kfree_skb_any(skb);
++              if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
+                       return false;
+-              }
+               break;
+       default:
+               return false;
+diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
+index 1214e7dcc8124..bf12ff0ab06ab 100644
+--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
++++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
+@@ -2892,7 +2892,6 @@ static void hw_scan_work(struct work_struct *work)
+                                                     hwsim->tmp_chan->band,
+                                                     NULL)) {
+                               rcu_read_unlock();
+-                              kfree_skb(probe);
+                               continue;
+                       }
+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
+index adaa1b2323d2c..85d785060e761 100644
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -7032,6 +7032,10 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
+  * @band: the band to transmit on
+  * @sta: optional pointer to get the station to send the frame to
+  *
++ * Return: %true if the skb was prepared, %false otherwise.
++ * On failure, the skb is freed by this function; callers must not
++ * free it again.
++ *
+  * Note: must be called under RCU lock
+  */
+ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 7eddcb6f96455..2a708132320c4 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1911,8 +1911,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
+       struct ieee80211_tx_data tx;
+       struct sk_buff *skb2;
+-      if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
++      if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
++              kfree_skb(skb);
+               return false;
++      }
+       info->band = band;
+       info->control.vif = vif;
+-- 
+2.53.0
+
diff --git a/queue-7.0/pwm-th1520-fix-clippy-1-warning.patch b/queue-7.0/pwm-th1520-fix-clippy-1-warning.patch
new file mode 100644 (file)
index 0000000..b0ca65d
--- /dev/null
@@ -0,0 +1,75 @@
+From 11ff874582ebed2ed85bd6d1a64ad66ebf5ca8f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 21 Jan 2026 19:37:19 +0100
+Subject: pwm: th1520: fix `CLIPPY=1` warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit aa8f35172ab66c57d4355a8c4e28d05b44c938e3 ]
+
+The Rust kernel code should be kept `CLIPPY=1`-clean [1].
+
+Clippy reports:
+
+    error: this pattern reimplements `Option::unwrap_or`
+      --> drivers/pwm/pwm_th1520.rs:64:5
+       |
+    64 | /     (match ns.checked_mul(rate_hz) {
+    65 | |         Some(product) => product,
+    66 | |         None => u64::MAX,
+    67 | |     }) / NSEC_PER_SEC_U64
+       | |______^ help: replace with: `ns.checked_mul(rate_hz).unwrap_or(u64::MAX)`
+       |
+       = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#manual_unwrap_or
+       = note: `-D clippy::manual-unwrap-or` implied by `-D warnings`
+       = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or)]`
+
+Applying the suggestion then triggers:
+
+    error: manual saturating arithmetic
+      --> drivers/pwm/pwm_th1520.rs:64:5
+       |
+    64 |     ns.checked_mul(rate_hz).unwrap_or(u64::MAX) / NSEC_PER_SEC_U64
+       |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_mul`: `ns.saturating_mul(rate_hz)`
+       |
+       = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#manual_saturating_arithmetic
+       = note: `-D clippy::manual-saturating-arithmetic` implied by `-D warnings`
+       = help: to override `-D warnings` add `#[allow(clippy::manual_saturating_arithmetic)]`
+
+Thus fix it by using saturating arithmetic, which simplifies the code
+as well.
+
+Link: https://rust-for-linux.com/contributing#submit-checklist-addendum [1]
+Fixes: e03724aac758 ("pwm: Add Rust driver for T-HEAD TH1520 SoC")
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Reviewed-by: Danilo Krummrich <dakr@kernel.org>
+Reviewed-by: Michal Wilczynski <m.wilczynski@samsung.com>
+Link: https://patch.msgid.link/20260121183719.71659-1-ojeda@kernel.org
+Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pwm/pwm_th1520.rs | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/pwm/pwm_th1520.rs b/drivers/pwm/pwm_th1520.rs
+index b0e24ee724e45..36567fc17dcc8 100644
+--- a/drivers/pwm/pwm_th1520.rs
++++ b/drivers/pwm/pwm_th1520.rs
+@@ -64,10 +64,7 @@ const fn th1520_pwm_fp(n: u32) -> usize {
+ fn ns_to_cycles(ns: u64, rate_hz: u64) -> u64 {
+     const NSEC_PER_SEC_U64: u64 = time::NSEC_PER_SEC as u64;
+-    (match ns.checked_mul(rate_hz) {
+-        Some(product) => product,
+-        None => u64::MAX,
+-    }) / NSEC_PER_SEC_U64
++    ns.saturating_mul(rate_hz) / NSEC_PER_SEC_U64
+ }
+ fn cycles_to_ns(cycles: u64, rate_hz: u64) -> u64 {
+-- 
+2.53.0
+
diff --git a/queue-7.0/series b/queue-7.0/series
new file mode 100644 (file)
index 0000000..65df281
--- /dev/null
@@ -0,0 +1 @@
+pwm-th1520-fix-clippy-1-warning.patch