--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
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
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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, ®s->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,
+ ®s->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
+
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
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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, ®s->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,
+ ®s->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
+
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
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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(ð->tx_napi);
+ napi_enable(ð->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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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(ð->tx_napi);
+ napi_enable(ð->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
+
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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(ð->tx_napi);
+ napi_enable(ð->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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
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
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+pwm-th1520-fix-clippy-1-warning.patch