--- /dev/null
+From matttbe@kernel.org Thu Apr 9 13:45:35 2026
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Thu, 9 Apr 2026 13:45:26 +0200
+Subject: mptcp: fix soft lockup in mptcp_recvmsg()
+To: stable@vger.kernel.org, gregkh@linuxfoundation.org, sashal@kernel.org
+Cc: MPTCP Upstream <mptcp@lists.linux.dev>, Li Xiasong <lixiasong1@huawei.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20260409114525.1159899-2-matttbe@kernel.org>
+
+From: Li Xiasong <lixiasong1@huawei.com>
+
+commit 5dd8025a49c268ab6b94d978532af3ad341132a7 upstream.
+
+syzbot reported a soft lockup in mptcp_recvmsg() [0].
+
+When receiving data with MSG_PEEK | MSG_WAITALL flags, the skb is not
+removed from the sk_receive_queue. This causes sk_wait_data() to always
+find available data and never perform actual waiting, leading to a soft
+lockup.
+
+Fix this by adding a 'last' parameter to track the last peeked skb.
+This allows sk_wait_data() to make informed waiting decisions and prevent
+infinite loops when MSG_PEEK is used.
+
+[0]:
+watchdog: BUG: soft lockup - CPU#2 stuck for 156s! [server:1963]
+Modules linked in:
+CPU: 2 UID: 0 PID: 1963 Comm: server Not tainted 6.19.0-rc8 #61 PREEMPT(none)
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+RIP: 0010:sk_wait_data+0x15/0x190
+Code: 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 41 56 41 55 41 54 49 89 f4 55 48 89 d5 53 48 89 fb <48> 83 ec 30 65 48 8b 05 17 a4 6b 01 48 89 44 24 28 31 c0 65 48 8b
+RSP: 0018:ffffc90000603ca0 EFLAGS: 00000246
+RAX: 0000000000000000 RBX: ffff888102bf0800 RCX: 0000000000000001
+RDX: 0000000000000000 RSI: ffffc90000603d18 RDI: ffff888102bf0800
+RBP: 0000000000000000 R08: 0000000000000002 R09: 0000000000000101
+R10: 0000000000000000 R11: 0000000000000075 R12: ffffc90000603d18
+R13: ffff888102bf0800 R14: ffff888102bf0800 R15: 0000000000000000
+FS: 00007f6e38b8c4c0(0000) GS:ffff8881b877e000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 000055aa7bff1680 CR3: 0000000105cbe000 CR4: 00000000000006f0
+Call Trace:
+ <TASK>
+ mptcp_recvmsg+0x547/0x8c0 net/mptcp/protocol.c:2329
+ inet_recvmsg+0x11f/0x130 net/ipv4/af_inet.c:891
+ sock_recvmsg+0x94/0xc0 net/socket.c:1100
+ __sys_recvfrom+0xb2/0x130 net/socket.c:2256
+ __x64_sys_recvfrom+0x1f/0x30 net/socket.c:2267
+ do_syscall_64+0x59/0x2d0 arch/x86/entry/syscall_64.c:94
+ entry_SYSCALL_64_after_hwframe+0x76/0x7e arch/x86/entry/entry_64.S:131
+RIP: 0033:0x7f6e386a4a1d
+Code: 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8d 05 f1 de 2c 00 41 89 ca 8b 00 85 c0 75 20 45 31 c9 45 31 c0 b8 2d 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 6b f3 c3 66 0f 1f 84 00 00 00 00 00 41 56 41
+RSP: 002b:00007ffc3c4bb078 EFLAGS: 00000246 ORIG_RAX: 000000000000002d
+RAX: ffffffffffffffda RBX: 000000000000861e RCX: 00007f6e386a4a1d
+RDX: 00000000000003ff RSI: 00007ffc3c4bb150 RDI: 0000000000000004
+RBP: 00007ffc3c4bb570 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000103 R11: 0000000000000246 R12: 00005605dbc00be0
+R13: 00007ffc3c4bb650 R14: 0000000000000000 R15: 0000000000000000
+ </TASK>
+
+Fixes: 8e04ce45a8db ("mptcp: fix MSG_PEEK stream corruption")
+Signed-off-by: Li Xiasong <lixiasong1@huawei.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260330120335.659027-1-lixiasong1@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Conflicts in protocol.c, because commit bc68b0efa1bf ("mptcp: move the
+ whole rx path under msk socket lock protection") and commit
+ d88b2127b242 ("mptcp: add eat_recv_skb helper") (with some
+ dependences) are not in this version. These conflicts were in the
+ context, and not related to this fix. ]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -1960,7 +1960,7 @@ static int __mptcp_recvmsg_mskq(struct m
+ struct msghdr *msg,
+ size_t len, int flags, int copied_total,
+ struct scm_timestamping_internal *tss,
+- int *cmsg_flags)
++ int *cmsg_flags, struct sk_buff **last)
+ {
+ struct sk_buff *skb, *tmp;
+ int total_data_len = 0;
+@@ -1976,6 +1976,7 @@ static int __mptcp_recvmsg_mskq(struct m
+ /* skip already peeked skbs */
+ if (total_data_len + data_len <= copied_total) {
+ total_data_len += data_len;
++ *last = skb;
+ continue;
+ }
+
+@@ -2016,6 +2017,8 @@ static int __mptcp_recvmsg_mskq(struct m
+ WRITE_ONCE(msk->rmem_released, msk->rmem_released + skb->truesize);
+ __skb_unlink(skb, &msk->receive_queue);
+ __kfree_skb(skb);
++ } else {
++ *last = skb;
+ }
+
+ if (copied >= len)
+@@ -2237,10 +2240,12 @@ static int mptcp_recvmsg(struct sock *sk
+ cmsg_flags = MPTCP_CMSG_INQ;
+
+ while (copied < len) {
++ struct sk_buff *last = NULL;
+ int err, bytes_read;
+
+ bytes_read = __mptcp_recvmsg_mskq(msk, msg, len - copied, flags,
+- copied, &tss, &cmsg_flags);
++ copied, &tss, &cmsg_flags,
++ &last);
+ if (unlikely(bytes_read < 0)) {
+ if (!copied)
+ copied = bytes_read;
+@@ -2298,7 +2303,7 @@ static int mptcp_recvmsg(struct sock *sk
+
+ pr_debug("block timeout %ld\n", timeo);
+ mptcp_cleanup_rbuf(msk, copied);
+- err = sk_wait_data(sk, &timeo, NULL);
++ err = sk_wait_data(sk, &timeo, last);
+ if (err < 0) {
+ err = copied ? : err;
+ goto out_err;
--- /dev/null
+From stable+bounces-235903-greg=kroah.com@vger.kernel.org Mon Apr 13 06:40:43 2026
+From: Keerthana K <keerthana.kalyanasundaram@broadcom.com>
+Date: Mon, 13 Apr 2026 04:32:23 +0000
+Subject: netfilter: nft_set_pipapo: do not rely on ZERO_SIZE_PTR
+To: stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: pablo@netfilter.org, kadlec@netfilter.org, fw@strlen.de, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, ajay.kaher@broadcom.com, alexey.makhalov@broadcom.com, vamsi-krishna.brahmajosyula@broadcom.com, yin.ding@broadcom.com, tapas.kundu@broadcom.com, Stefano Brivio <sbrivio@redhat.com>, Mukul Sikka <mukul.sikka@broadcom.com>, Brennan Lamoreaux <brennan.lamoreaux@broadcom.com>, Keerthana K <keerthana.kalyanasundaram@broadcom.com>
+Message-ID: <20260413043223.3327827-1-keerthana.kalyanasundaram@broadcom.com>
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 07ace0bbe03b3d8e85869af1dec5e4087b1d57b8 upstream
+
+pipapo relies on kmalloc(0) returning ZERO_SIZE_PTR (i.e., not NULL
+but pointer is invalid).
+
+Rework this to not call slab allocator when we'd request a 0-byte
+allocation.
+
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Mukul Sikka <mukul.sikka@broadcom.com>
+Signed-off-by: Brennan Lamoreaux <brennan.lamoreaux@broadcom.com>
+[Keerthana: In older stable branches (v6.6 and earlier), the allocation logic in
+pipapo_clone() still relies on `src->rules` rather than `src->rules_alloc`
+(introduced in v6.9 via 9f439bd6ef4f). Consequently, the previously
+backported INT_MAX clamping check uses `src->rules`. This patch correctly
+moves that `src->rules > (INT_MAX / ...)` check inside the new
+`if (src->rules > 0)` block]
+Signed-off-by: Keerthana K <keerthana.kalyanasundaram@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/nft_set_pipapo.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -525,6 +525,8 @@ static struct nft_pipapo_elem *pipapo_ge
+ int i;
+
+ m = priv->clone;
++ if (m->bsize_max == 0)
++ return ret;
+
+ res_map = kmalloc_array(m->bsize_max, sizeof(*res_map), GFP_ATOMIC);
+ if (!res_map) {
+@@ -1394,14 +1396,20 @@ static struct nft_pipapo_match *pipapo_c
+ src->bsize * sizeof(*dst->lt) *
+ src->groups * NFT_PIPAPO_BUCKETS(src->bb));
+
+- if (src->rules > (INT_MAX / sizeof(*src->mt)))
+- goto out_mt;
++ if (src->rules > 0) {
++ if (src->rules > (INT_MAX / sizeof(*src->mt)))
++ goto out_mt;
++
++ dst->mt = kvmalloc_array(src->rules, sizeof(*src->mt),
++ GFP_KERNEL);
++ if (!dst->mt)
++ goto out_mt;
+
+- dst->mt = kvmalloc(src->rules * sizeof(*src->mt), GFP_KERNEL_ACCOUNT);
+- if (!dst->mt)
+- goto out_mt;
++ memcpy(dst->mt, src->mt, src->rules * sizeof(*src->mt));
++ } else {
++ dst->mt = NULL;
++ }
+
+- memcpy(dst->mt, src->mt, src->rules * sizeof(*src->mt));
+ src++;
+ dst++;
+ }
--- /dev/null
+From linux@leemhuis.info Mon Apr 13 10:06:33 2026
+From: Thorsten Leemhuis <linux@leemhuis.info>
+Date: Mon, 13 Apr 2026 10:03:33 +0200
+Subject: Revert "drm: Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug"
+To: regressions@leemhuis.info
+Cc: dri-devel@lists.freedesktop.org, gregkh@linuxfoundation.org, matt.fagnani@bell.net, regressions@lists.linux.dev, sashal@kernel.org, stable@vger.kernel.org, "Maarten Lankhorst" <dev@lankhorst.se>, "Thomas Hellström" <thomas.hellstrom@linux.intel.com>, "Guenter Roeck" <linux@roeck-us.net>, "Simona Vetter" <simona.vetter@ffwll.ch>, "Thorsten Leemhuis" <linux@leemhuis.info>
+Message-ID: <20260413080333.3079490-1-linux@leemhuis.info>
+
+From: Maarten Lankhorst <dev@lankhorst.se>
+
+commit 45ebe43ea00d6b9f5b3e0db9c35b8ca2a96b7e70 upstream.
+
+This reverts commit 6bee098b91417654703e17eb5c1822c6dfd0c01d.
+
+Den 2026-03-25 kl. 22:11, skrev Simona Vetter:
+> On Wed, Mar 25, 2026 at 10:26:40AM -0700, Guenter Roeck wrote:
+>> Hi,
+>>
+>> On Fri, Mar 13, 2026 at 04:17:27PM +0100, Maarten Lankhorst wrote:
+>>> When trying to do a rather aggressive test of igt's "xe_module_load
+>>> --r reload" with a full desktop environment and game running I noticed
+>>> a few OOPSes when dereferencing freed pointers, related to
+>>> framebuffers and property blobs after the compositor exits.
+>>>
+>>> Solve this by guarding the freeing in drm_file with drm_dev_enter/exit,
+>>> and immediately put the references from struct drm_file objects during
+>>> drm_dev_unplug().
+>>>
+>>
+>> With this patch in v6.18.20, I get the warning backtraces below.
+>> The backtraces are gone with the patch reverted.
+>
+> Yeah, this needs to be reverted, reasoning below. Maarten, can you please
+> take care of that and feed the revert through the usual channels? I don't
+> think it's critical enough that we need to fast-track this into drm.git
+> directly.
+>
+> Quoting the patch here again:
+>
+>> drivers/gpu/drm/drm_file.c| 5 ++++-
+>> drivers/gpu/drm/drm_mode_config.c | 9 ++++++---
+>> 2 files changed, 10 insertions(+), 4 deletions(-)
+>>
+>> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
+>> index ec820686b3021..f52141f842a1f 100644
+>> --- a/drivers/gpu/drm/drm_file.c
+>> +++ b/drivers/gpu/drm/drm_file.c
+>> @@ -233,6 +233,7 @@ static void drm_events_release(struct drm_file *file_priv)
+>> void drm_file_free(struct drm_file *file)
+>> {
+>> struct drm_device *dev;
+>> +int idx;
+>>
+>> if (!file)
+>> return;
+>> @@ -249,9 +250,11 @@ void drm_file_free(struct drm_file *file)
+>>
+>> drm_events_release(file);
+>>
+>> -if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+>> +if (drm_core_check_feature(dev, DRIVER_MODESET) &&
+>> +drm_dev_enter(dev, &idx)) {
+>
+> This is misplaced for two reasons:
+>
+> - Even if we'd want to guarantee that we hold a drm_dev_enter/exit
+> reference during framebuffer teardown, we'd need to do this
+> _consistently over all callsites. Not ad-hoc in just one place that a
+> testcase hits. This also means kerneldoc updates of the relevant hooks
+> and at least a bunch of acks from other driver people to document the
+> consensus.
+>
+> - More importantly, this is driver responsibilities in general unless we
+> have extremely good reasons to the contrary. Which means this must be
+> placed in xe.
+>
+>> drm_fb_release(file);
+>> drm_property_destroy_user_blobs(dev, file);
+>> +drm_dev_exit(idx);
+>> }
+>>
+>> if (drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+>> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
+>> index 84ae8a23a3678..e349418978f79 100644
+>> --- a/drivers/gpu/drm/drm_mode_config.c
+>> +++ b/drivers/gpu/drm/drm_mode_config.c
+>> @@ -583,10 +583,13 @@ void drm_mode_config_cleanup(struct drm_device *dev)
+>> */
+>> WARN_ON(!list_empty(&dev->mode_config.fb_list));
+>> list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
+>> -struct drm_printer p = drm_dbg_printer(dev, DRM_UT_KMS, "[leaked fb]");
+>> +if (list_empty(&fb->filp_head) || drm_framebuffer_read_refcount(fb) > 1) {
+>> +struct drm_printer p = drm_dbg_printer(dev, DRM_UT_KMS, "[leaked fb]");
+>
+> This is also wrong:
+>
+> - Firstly, it's a completely independent bug, we do not smash two bugfixes
+> into one patch.
+>
+> - Secondly, it's again a driver bug: drm_mode_cleanup must be called when
+> the last drm_device reference disappears (hence the existence of
+> drmm_mode_config_init), not when the driver gets unbound. The fact that
+> this shows up in a callchain from a devres cleanup means the intel
+> driver gets this wrong (like almost everyone else because historically
+> we didn't know better).
+>
+> If we don't follow this rule, then we get races with this code here
+> running concurrently with drm_file fb cleanups, which just does not
+> work. Review pointed that out, but then shrugged it off with a confused
+> explanation:
+>
+> https://lore.kernel.org/all/e61e64c796ccfb17ae673331a3df4b877bf42d82.camel@linux.intel.com/
+>
+> Yes this also means a lot of the other drm_device teardown that drivers
+> do happens way too early. There is a massive can of worms here of a
+> magnitude that most likely is much, much bigger than what you can
+> backport to stable kernels. Hotunplug is _hard_.
+
+Back to the drawing board, and fixing it in the intel display driver
+instead.
+
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Fixes: 6bee098b9141 ("drm: Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug")
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Acked-by: Simona Vetter <simona.vetter@ffwll.ch>
+Signed-off-by: Maarten Lankhorst <dev@lankhorst.se>
+Link: https://patch.msgid.link/20260326082217.39941-2-dev@lankhorst.se
+[ Thorsten: adjust to the v6.6.y/v6.6.y backports of 6bee098b9141 ]
+Signed-off-by: Thorsten Leemhuis <linux@leemhuis.info>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/drm_file.c | 5 +----
+ drivers/gpu/drm/drm_mode_config.c | 9 +++------
+ 2 files changed, 4 insertions(+), 10 deletions(-)
+
+--- a/drivers/gpu/drm/drm_file.c
++++ b/drivers/gpu/drm/drm_file.c
+@@ -243,7 +243,6 @@ static void drm_events_release(struct dr
+ void drm_file_free(struct drm_file *file)
+ {
+ struct drm_device *dev;
+- int idx;
+
+ if (!file)
+ return;
+@@ -269,11 +268,9 @@ void drm_file_free(struct drm_file *file
+
+ drm_events_release(file);
+
+- if (drm_core_check_feature(dev, DRIVER_MODESET) &&
+- drm_dev_enter(dev, &idx)) {
++ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ drm_fb_release(file);
+ drm_property_destroy_user_blobs(dev, file);
+- drm_dev_exit(idx);
+ }
+
+ if (drm_core_check_feature(dev, DRIVER_SYNCOBJ))
+--- a/drivers/gpu/drm/drm_mode_config.c
++++ b/drivers/gpu/drm/drm_mode_config.c
+@@ -546,13 +546,10 @@ void drm_mode_config_cleanup(struct drm_
+ */
+ WARN_ON(!list_empty(&dev->mode_config.fb_list));
+ list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) {
+- if (list_empty(&fb->filp_head) || drm_framebuffer_read_refcount(fb) > 1) {
+- struct drm_printer p = drm_debug_printer("[leaked fb]");
++ struct drm_printer p = drm_debug_printer("[leaked fb]");
+
+- drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
+- drm_framebuffer_print_info(&p, 1, fb);
+- }
+- list_del_init(&fb->filp_head);
++ drm_printf(&p, "framebuffer[%u]:\n", fb->base.id);
++ drm_framebuffer_print_info(&p, 1, fb);
+ drm_framebuffer_free(&fb->base.refcount);
+ }
+
--- /dev/null
+From stable+bounces-235832-greg=kroah.com@vger.kernel.org Sun Apr 12 18:58:10 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Apr 2026 12:58:02 -0400
+Subject: Revert "mptcp: add needs_id for netlink appending addr"
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Geliang Tang <geliang@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260412165802.2349149-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 8e2760eaab778494fc1fa257031e0e1799647f46 ]
+
+This commit was originally adding the ability to add MPTCP endpoints
+with ID 0 by accident. The in-kernel PM, handling MPTCP endpoints at the
+net namespace level, is not supposed to handle endpoints with such ID,
+because this ID 0 is reserved to the initial subflow, as mentioned in
+the MPTCPv1 protocol [1], a per-connection setting.
+
+Note that 'ip mptcp endpoint add id 0' stops early with an error, but
+other tools might still request the in-kernel PM to create MPTCP
+endpoints with this restricted ID 0.
+
+In other words, it was wrong to call the mptcp_pm_has_addr_attr_id
+helper to check whether the address ID attribute is set: if it was set
+to 0, a new MPTCP endpoint would be created with ID 0, which is not
+expected, and might cause various issues later.
+
+Fixes: 584f38942626 ("mptcp: add needs_id for netlink appending addr")
+Cc: stable@vger.kernel.org
+Link: https://datatracker.ietf.org/doc/html/rfc8684#section-3.2-9 [1]
+Reviewed-by: Geliang Tang <geliang@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260407-net-mptcp-revert-pm-needs-id-v2-1-7a25cbc324f8@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ applied changes to net/mptcp/pm_netlink.c instead of renamed net/mptcp/pm_kernel.c ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c | 24 +++++-------------------
+ 1 file changed, 5 insertions(+), 19 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -1079,7 +1079,7 @@ static void __mptcp_pm_release_addr_entr
+
+ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
+ struct mptcp_pm_addr_entry *entry,
+- bool needs_id, bool replace)
++ bool replace)
+ {
+ struct mptcp_pm_addr_entry *cur, *del_entry = NULL;
+ unsigned int addr_max;
+@@ -1138,7 +1138,7 @@ static int mptcp_pm_nl_append_new_local_
+ }
+ }
+
+- if (!entry->addr.id && needs_id) {
++ if (!entry->addr.id) {
+ find_next:
+ entry->addr.id = find_next_zero_bit(pernet->id_bitmap,
+ MPTCP_PM_MAX_ADDR_ID + 1,
+@@ -1149,7 +1149,7 @@ find_next:
+ }
+ }
+
+- if (!entry->addr.id && needs_id)
++ if (!entry->addr.id)
+ goto out;
+
+ __set_bit(entry->addr.id, pernet->id_bitmap);
+@@ -1282,7 +1282,7 @@ int mptcp_pm_nl_get_local_id(struct mptc
+ entry->ifindex = 0;
+ entry->flags = MPTCP_PM_ADDR_FLAG_IMPLICIT;
+ entry->lsk = NULL;
+- ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true, false);
++ ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, false);
+ if (ret < 0)
+ kfree(entry);
+
+@@ -1524,18 +1524,6 @@ next:
+ return 0;
+ }
+
+-static bool mptcp_pm_has_addr_attr_id(const struct nlattr *attr,
+- struct genl_info *info)
+-{
+- struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
+-
+- if (!nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr,
+- mptcp_pm_addr_policy, info->extack) &&
+- tb[MPTCP_PM_ADDR_ATTR_ID])
+- return true;
+- return false;
+-}
+-
+ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
+ {
+ struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
+@@ -1577,9 +1565,7 @@ static int mptcp_nl_cmd_add_addr(struct
+ goto out_free;
+ }
+ }
+- ret = mptcp_pm_nl_append_new_local_addr(pernet, entry,
+- !mptcp_pm_has_addr_attr_id(attr, info),
+- true);
++ ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true);
+ if (ret < 0) {
+ GENL_SET_ERR_MSG_FMT(info, "too many addresses or duplicate one: %d", ret);
+ goto out_free;
--- /dev/null
+From stable+bounces-235833-greg=kroah.com@vger.kernel.org Sun Apr 12 18:58:57 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 12 Apr 2026 12:58:30 -0400
+Subject: seg6: separate dst_cache for input and output paths in seg6 lwtunnel
+To: stable@vger.kernel.org
+Cc: Andrea Mayer <andrea.mayer@uniroma2.it>, Nicolas Dichtel <nicolas.dichtel@6wind.com>, Justin Iurman <justin.iurman@gmail.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260412165830.2349698-1-sashal@kernel.org>
+
+From: Andrea Mayer <andrea.mayer@uniroma2.it>
+
+[ Upstream commit c3812651b522fe8437ebb7063b75ddb95b571643 ]
+
+The seg6 lwtunnel uses a single dst_cache per encap route, shared
+between seg6_input_core() and seg6_output_core(). These two paths
+can perform the post-encap SID lookup in different routing contexts
+(e.g., ip rules matching on the ingress interface, or VRF table
+separation). Whichever path runs first populates the cache, and the
+other reuses it blindly, bypassing its own lookup.
+
+Fix this by splitting the cache into cache_input and cache_output,
+so each path maintains its own cached dst independently.
+
+Fixes: 6c8702c60b88 ("ipv6: sr: add support for SRH encapsulation and injection with lwtunnels")
+Cc: stable@vger.kernel.org
+Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
+Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Reviewed-by: Justin Iurman <justin.iurman@gmail.com>
+Link: https://patch.msgid.link/20260404004405.4057-2-andrea.mayer@uniroma2.it
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ added missing dst reference loop guard in seg6_output_core() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/seg6_iptunnel.c | 41 ++++++++++++++++++++++++++++-------------
+ 1 file changed, 28 insertions(+), 13 deletions(-)
+
+--- a/net/ipv6/seg6_iptunnel.c
++++ b/net/ipv6/seg6_iptunnel.c
+@@ -48,7 +48,8 @@ static size_t seg6_lwt_headroom(struct s
+ }
+
+ struct seg6_lwt {
+- struct dst_cache cache;
++ struct dst_cache cache_input;
++ struct dst_cache cache_output;
+ struct seg6_iptunnel_encap tuninfo[];
+ };
+
+@@ -486,7 +487,7 @@ static int seg6_input_core(struct net *n
+ slwt = seg6_lwt_lwtunnel(lwtst);
+
+ local_bh_disable();
+- dst = dst_cache_get(&slwt->cache);
++ dst = dst_cache_get(&slwt->cache_input);
+ local_bh_enable();
+
+ err = seg6_do_srh(skb, dst);
+@@ -500,7 +501,7 @@ static int seg6_input_core(struct net *n
+ /* cache only if we don't create a dst reference loop */
+ if (!dst->error && lwtst != dst->lwtstate) {
+ local_bh_disable();
+- dst_cache_set_ip6(&slwt->cache, dst,
++ dst_cache_set_ip6(&slwt->cache_input, dst,
+ &ipv6_hdr(skb)->saddr);
+ local_bh_enable();
+ }
+@@ -560,7 +561,7 @@ static int seg6_output_core(struct net *
+ slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);
+
+ local_bh_disable();
+- dst = dst_cache_get(&slwt->cache);
++ dst = dst_cache_get(&slwt->cache_output);
+ local_bh_enable();
+
+ err = seg6_do_srh(skb, dst);
+@@ -585,9 +586,12 @@ static int seg6_output_core(struct net *
+ goto drop;
+ }
+
+- local_bh_disable();
+- dst_cache_set_ip6(&slwt->cache, dst, &fl6.saddr);
+- local_bh_enable();
++ /* cache only if we don't create a dst reference loop */
++ if (orig_dst->lwtstate != dst->lwtstate) {
++ local_bh_disable();
++ dst_cache_set_ip6(&slwt->cache_output, dst, &fl6.saddr);
++ local_bh_enable();
++ }
+
+ err = skb_cow_head(skb, LL_RESERVED_SPACE(dst->dev));
+ if (unlikely(err))
+@@ -694,11 +698,13 @@ static int seg6_build_state(struct net *
+
+ slwt = seg6_lwt_lwtunnel(newts);
+
+- err = dst_cache_init(&slwt->cache, GFP_ATOMIC);
+- if (err) {
+- kfree(newts);
+- return err;
+- }
++ err = dst_cache_init(&slwt->cache_input, GFP_ATOMIC);
++ if (err)
++ goto err_free_newts;
++
++ err = dst_cache_init(&slwt->cache_output, GFP_ATOMIC);
++ if (err)
++ goto err_destroy_input;
+
+ memcpy(&slwt->tuninfo, tuninfo, tuninfo_len);
+
+@@ -713,11 +719,20 @@ static int seg6_build_state(struct net *
+ *ts = newts;
+
+ return 0;
++
++err_destroy_input:
++ dst_cache_destroy(&slwt->cache_input);
++err_free_newts:
++ kfree(newts);
++ return err;
+ }
+
+ static void seg6_destroy_state(struct lwtunnel_state *lwt)
+ {
+- dst_cache_destroy(&seg6_lwt_lwtunnel(lwt)->cache);
++ struct seg6_lwt *slwt = seg6_lwt_lwtunnel(lwt);
++
++ dst_cache_destroy(&slwt->cache_input);
++ dst_cache_destroy(&slwt->cache_output);
+ }
+
+ static int seg6_fill_encap_info(struct sk_buff *skb,
mips-mm-rewrite-tlb-uniquification-for-the-hidden-bi.patch
asoc-simple-card-utils-don-t-use-__free-device_node-.patch
scsi-ufs-core-fix-use-after-free-in-init-error-and-r.patch
+virtio_net-clamp-rss_max_key_size-to-netdev_rss_key_len.patch
+mptcp-fix-soft-lockup-in-mptcp_recvmsg.patch
+usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch
+revert-mptcp-add-needs_id-for-netlink-appending-addr.patch
+seg6-separate-dst_cache-for-input-and-output-paths-in-seg6-lwtunnel.patch
+netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch
+revert-drm-fix-use-after-free-on-framebuffers-and-property-blobs-when-calling-drm_dev_unplug.patch
--- /dev/null
+From stable+bounces-235777-greg=kroah.com@vger.kernel.org Sun Apr 12 03:02:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Apr 2026 21:02:47 -0400
+Subject: usb: gadget: f_hid: move list and spinlock inits from bind to alloc
+To: stable@vger.kernel.org
+Cc: Michael Zimmermann <sigmaepsilon92@gmail.com>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260412010247.1905349-1-sashal@kernel.org>
+
+From: Michael Zimmermann <sigmaepsilon92@gmail.com>
+
+[ Upstream commit 4e0a88254ad59f6c53a34bf5fa241884ec09e8b2 ]
+
+There was an issue when you did the following:
+- setup and bind an hid gadget
+- open /dev/hidg0
+- use the resulting fd in EPOLL_CTL_ADD
+- unbind the UDC
+- bind the UDC
+- use the fd in EPOLL_CTL_DEL
+
+When CONFIG_DEBUG_LIST was enabled, a list_del corruption was reported
+within remove_wait_queue (via ep_remove_wait_queue). After some
+debugging I found out that the queues, which f_hid registers via
+poll_wait were the problem. These were initialized using
+init_waitqueue_head inside hidg_bind. So effectively, the bind function
+re-initialized the queues while there were still items in them.
+
+The solution is to move the initialization from hidg_bind to hidg_alloc
+to extend their lifetimes to the lifetime of the function instance.
+
+Additionally, I found many other possibly problematic init calls in the
+bind function, which I moved as well.
+
+Signed-off-by: Michael Zimmermann <sigmaepsilon92@gmail.com>
+Cc: stable <stable@kernel.org>
+Link: https://patch.msgid.link/20260331184844.2388761-1-sigmaepsilon92@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_hid.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -1000,13 +1000,8 @@ static int hidg_bind(struct usb_configur
+ if (status)
+ goto fail;
+
+- spin_lock_init(&hidg->write_spinlock);
+ hidg->write_pending = 1;
+ hidg->req = NULL;
+- spin_lock_init(&hidg->read_spinlock);
+- init_waitqueue_head(&hidg->write_queue);
+- init_waitqueue_head(&hidg->read_queue);
+- INIT_LIST_HEAD(&hidg->completed_out_req);
+
+ /* create char device */
+ cdev_init(&hidg->cdev, &f_hidg_fops);
+@@ -1275,6 +1270,12 @@ static struct usb_function *hidg_alloc(s
+
+ mutex_lock(&opts->lock);
+
++ spin_lock_init(&hidg->write_spinlock);
++ spin_lock_init(&hidg->read_spinlock);
++ init_waitqueue_head(&hidg->write_queue);
++ init_waitqueue_head(&hidg->read_queue);
++ INIT_LIST_HEAD(&hidg->completed_out_req);
++
+ device_initialize(&hidg->dev);
+ hidg->dev.release = hidg_release;
+ hidg->dev.class = &hidg_class;
--- /dev/null
+From stable+bounces-233908-greg=kroah.com@vger.kernel.org Wed Apr 8 15:44:31 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Apr 2026 09:39:21 -0400
+Subject: virtio_net: clamp rss_max_key_size to NETDEV_RSS_KEY_LEN
+To: stable@vger.kernel.org
+Cc: Srujana Challa <schalla@marvell.com>, "Michael S. Tsirkin" <mst@redhat.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260408133921.1094528-1-sashal@kernel.org>
+
+From: Srujana Challa <schalla@marvell.com>
+
+[ Upstream commit b4e5f04c58a29c499faa85d12952ca9a4faf1cb9 ]
+
+rss_max_key_size in the virtio spec is the maximum key size supported by
+the device, not a mandatory size the driver must use. Also the value 40
+is a spec minimum, not a spec maximum.
+
+The current code rejects RSS and can fail probe when the device reports a
+larger rss_max_key_size than the driver buffer limit. Instead, clamp the
+effective key length to min(device rss_max_key_size, NETDEV_RSS_KEY_LEN)
+and keep RSS enabled.
+
+This keeps probe working on devices that advertise larger maximum key sizes
+while respecting the netdev RSS key buffer size limit.
+
+Fixes: 3f7d9c1964fc ("virtio_net: Add hash_key_length check")
+Cc: stable@vger.kernel.org
+Signed-off-by: Srujana Challa <schalla@marvell.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Link: https://patch.msgid.link/20260326142344.1171317-1-schalla@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ changed clamp target from NETDEV_RSS_KEY_LEN to VIRTIO_NET_RSS_MAX_KEY_SIZE ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/virtio_net.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -4465,6 +4465,7 @@ static int virtnet_probe(struct virtio_d
+ struct virtnet_info *vi;
+ u16 max_queue_pairs;
+ int mtu = 0;
++ u16 key_sz;
+
+ /* Find if host supports multiqueue/rss virtio_net device */
+ max_queue_pairs = 1;
+@@ -4589,14 +4590,13 @@ static int virtnet_probe(struct virtio_d
+ }
+
+ if (vi->has_rss || vi->has_rss_hash_report) {
+- vi->rss_key_size =
+- virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size));
+- if (vi->rss_key_size > VIRTIO_NET_RSS_MAX_KEY_SIZE) {
+- dev_err(&vdev->dev, "rss_max_key_size=%u exceeds the limit %u.\n",
+- vi->rss_key_size, VIRTIO_NET_RSS_MAX_KEY_SIZE);
+- err = -EINVAL;
+- goto free;
+- }
++ key_sz = virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size));
++
++ vi->rss_key_size = min_t(u16, key_sz, VIRTIO_NET_RSS_MAX_KEY_SIZE);
++ if (key_sz > vi->rss_key_size)
++ dev_warn(&vdev->dev,
++ "rss_max_key_size=%u exceeds driver limit %u, clamping\n",
++ key_sz, vi->rss_key_size);
+
+ vi->rss_hash_types_supported =
+ virtio_cread32(vdev, offsetof(struct virtio_net_config, supported_hash_types));