--- /dev/null
+From stable+bounces-230046-greg=kroah.com@vger.kernel.org Tue Mar 24 03:39:42 2026
+From: Robert Garcia <rob_garcia@163.com>
+Date: Tue, 24 Mar 2026 10:34:02 +0800
+Subject: Bluetooth: eir: Fix possible crashes on eir_create_adv_data
+To: stable@vger.kernel.org, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Cc: Marcel Holtmann <marcel@holtmann.org>, Robert Garcia <rob_garcia@163.com>, Johan Hedberg <johan.hedberg@gmail.com>, "David S . Miller" <davem@davemloft.net>, Eric Dumazet <edumazet@google.com>, Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>, linux-bluetooth@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org
+Message-ID: <20260324023402.2607704-1-rob_garcia@163.com>
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 47c03902269aff377f959dc3fd94a9733aa31d6e ]
+
+eir_create_adv_data may attempt to add EIR_FLAGS and EIR_TX_POWER
+without checking if that would fit.
+
+Link: https://github.com/bluez/bluez/issues/1117#issuecomment-2958244066
+Fixes: 01ce70b0a274 ("Bluetooth: eir: Move EIR/Adv Data functions to its own file")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+[ Use pdu.data instead of pdu->data in hci_set_ext_adv_data_sync()
+ to keep context consistency. ]
+Signed-off-by: Robert Garcia <rob_garcia@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/eir.c | 7 ++++---
+ net/bluetooth/eir.h | 2 +-
+ net/bluetooth/hci_sync.c | 5 +++--
+ 3 files changed, 8 insertions(+), 6 deletions(-)
+
+--- a/net/bluetooth/eir.c
++++ b/net/bluetooth/eir.c
+@@ -242,7 +242,7 @@ u8 eir_create_per_adv_data(struct hci_de
+ return ad_len;
+ }
+
+-u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
++u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr, u8 size)
+ {
+ struct adv_info *adv = NULL;
+ u8 ad_len = 0, flags = 0;
+@@ -286,7 +286,7 @@ u8 eir_create_adv_data(struct hci_dev *h
+ /* If flags would still be empty, then there is no need to
+ * include the "Flags" AD field".
+ */
+- if (flags) {
++ if (flags && (ad_len + eir_precalc_len(1) <= size)) {
+ ptr[0] = 0x02;
+ ptr[1] = EIR_FLAGS;
+ ptr[2] = flags;
+@@ -316,7 +316,8 @@ skip_flags:
+ }
+
+ /* Provide Tx Power only if we can provide a valid value for it */
+- if (adv_tx_power != HCI_TX_POWER_INVALID) {
++ if (adv_tx_power != HCI_TX_POWER_INVALID &&
++ (ad_len + eir_precalc_len(1) <= size)) {
+ ptr[0] = 0x02;
+ ptr[1] = EIR_TX_POWER;
+ ptr[2] = (u8)adv_tx_power;
+--- a/net/bluetooth/eir.h
++++ b/net/bluetooth/eir.h
+@@ -9,7 +9,7 @@
+
+ void eir_create(struct hci_dev *hdev, u8 *data);
+
+-u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
++u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr, u8 size);
+ u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr);
+ u8 eir_create_per_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
+
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -1248,7 +1248,8 @@ static int hci_set_ext_adv_data_sync(str
+ return 0;
+ }
+
+- len = eir_create_adv_data(hdev, instance, pdu.data);
++ len = eir_create_adv_data(hdev, instance, pdu.data,
++ HCI_MAX_EXT_AD_LENGTH);
+
+ pdu.cp.length = len;
+ pdu.cp.handle = instance;
+@@ -1279,7 +1280,7 @@ static int hci_set_adv_data_sync(struct
+
+ memset(&cp, 0, sizeof(cp));
+
+- len = eir_create_adv_data(hdev, instance, cp.data);
++ len = eir_create_adv_data(hdev, instance, cp.data, sizeof(cp.data));
+
+ /* There's nothing to do if the data hasn't changed */
+ if (hdev->adv_data_len == len &&
--- /dev/null
+From stable+bounces-230584-greg=kroah.com@vger.kernel.org Fri Mar 27 05:34:18 2026
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+Date: Fri, 27 Mar 2026 12:33:59 +0800
+Subject: erofs: fix PSI memstall accounting
+To: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: linux-erofs@lists.ozlabs.org, Gao Xiang <hsiangkao@linux.alibaba.com>, Max Kellermann <max.kellermann@ionos.com>, Chao Yu <chao@kernel.org>, Alexey Panov <apanov@astralinux.ru>
+Message-ID: <20260327043359.1121251-1-hsiangkao@linux.alibaba.com>
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+commit 1a2180f6859c73c674809f9f82e36c94084682ba upstream.
+
+Max Kellermann recently reported psi_group_cpu.tasks[NR_MEMSTALL] is
+incorrect in the 6.11.9 kernel.
+
+The root cause appears to be that, since the problematic commit, bio
+can be NULL, causing psi_memstall_leave() to be skipped in
+z_erofs_submit_queue().
+
+Reported-by: Max Kellermann <max.kellermann@ionos.com>
+Closes: https://lore.kernel.org/r/CAKPOu+8tvSowiJADW2RuKyofL_CSkm_SuyZA7ME5vMLWmL6pqw@mail.gmail.com
+Fixes: 9e2f9d34dd12 ("erofs: handle overlapped pclusters out of crafted images properly")
+Reviewed-by: Chao Yu <chao@kernel.org>
+Link: https://lore.kernel.org/r/20241127085236.3538334-1-hsiangkao@linux.alibaba.com
+Signed-off-by: Alexey Panov <apanov@astralinux.ru>
+Link: https://lore.kernel.org/r/20250304110558.8315-3-apanov@astralinux.ru
+Link: https://lore.kernel.org/r/20250304110558.8315-1-apanov@astralinux.ru
+[ Gao Xiang: re-address the previous Alexey's backport. ]
+CVE: CVE-2024-47736
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/erofs/zdata.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -1574,11 +1574,10 @@ drain_io:
+ move_to_bypass_jobqueue(pcl, qtail, owned_head);
+ } while (owned_head != Z_EROFS_PCLUSTER_TAIL);
+
+- if (bio) {
++ if (bio)
+ submit_bio(bio);
+- if (memstall)
+- psi_memstall_leave(&pflags);
+- }
++ if (memstall)
++ psi_memstall_leave(&pflags);
+
+ /*
+ * although background is preferred, no one is pending for submission.
--- /dev/null
+From arefev@swemel.ru Mon Mar 23 14:59:38 2026
+From: Denis Arefev <arefev@swemel.ru>
+Date: Mon, 23 Mar 2026 16:59:35 +0300
+Subject: erofs: Fix the slab-out-of-bounds in drop_buffers()
+To: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Gao Xiang <xiang@kernel.org>, Chao Yu <chao@kernel.org>, Jeffle Xu <jefflexu@linux.alibaba.com>, linux-erofs@lists.ozlabs.org, linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org, syzbot+5b886a2e03529dbcef81@syzkaller.appspotmail.com
+Message-ID: <20260323135936.15070-1-arefev@swemel.ru>
+
+From: Denis Arefev <arefev@swemel.ru>
+
+commit ce529cc25b184e93397b94a8a322128fc0095cbb upstream.
+
+This was accidentally fixed in commit ce529cc25b18, but it's not possible
+to accept all the changes, due to the lack of large folios support for
+Linux 6.1 kernels, so this is only the actual bug fix that's needed.
+
+[Background]
+
+Syzbot reported that a KASAN slab-out-of-bounds bug was discovered in
+the drop_buffers() function [1].
+
+The root cause is that erofs_raw_access_aops does not define .release_folio
+and .invalidate_folio. When using iomap-based operations, folio->private
+may contain iomap-specific data rather than buffer_heads. Without special
+handlers, the kernel may fall back to generic functions (such as
+drop_buffers), which incorrectly treat folio->private as a list of
+buffer_head structures, leading to incorrect memory interpretation and
+out-of-bounds access.
+
+Fix this by explicitly setting .release_folio and .invalidate_folio to the
+values of iomap_release_folio and iomap_invalidate_folio, respectively.
+
+[1] https://syzkaller.appspot.com/x/report.txt?x=12e5a142580000
+
+Fixes: 7479c505b4ab ("fs: Convert iomap_readpage to iomap_read_folio")
+Reported-by: syzbot+5b886a2e03529dbcef81@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?id=c6aeabd0c4ad2466f63a274faf2a123103f8fbf7
+Signed-off-by: Denis Arefev <arefev@swemel.ru>
+Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/erofs/data.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/erofs/data.c
++++ b/fs/erofs/data.c
+@@ -406,6 +406,8 @@ const struct address_space_operations er
+ .readahead = erofs_readahead,
+ .bmap = erofs_bmap,
+ .direct_IO = noop_direct_IO,
++ .release_folio = iomap_release_folio,
++ .invalidate_folio = iomap_invalidate_folio,
+ };
+
+ #ifdef CONFIG_FS_DAX
--- /dev/null
+From stable+bounces-230583-greg=kroah.com@vger.kernel.org Fri Mar 27 05:33:33 2026
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+Date: Fri, 27 Mar 2026 12:33:12 +0800
+Subject: erofs: handle overlapped pclusters out of crafted images properly
+To: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: linux-erofs@lists.ozlabs.org, Gao Xiang <hsiangkao@linux.alibaba.com>, syzbot+4fc98ed414ae63d1ada2@syzkaller.appspotmail.com, syzbot+de04e06b28cfecf2281c@syzkaller.appspotmail.com, syzbot+c8c8238b394be4a1087d@syzkaller.appspotmail.com, Alexey Panov <apanov@astralinux.ru>
+Message-ID: <20260327043312.1118901-1-hsiangkao@linux.alibaba.com>
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+commit 9e2f9d34dd12e6e5b244ec488bcebd0c2d566c50 upstream.
+
+syzbot reported a task hang issue due to a deadlock case where it is
+waiting for the folio lock of a cached folio that will be used for
+cache I/Os.
+
+After looking into the crafted fuzzed image, I found it's formed with
+several overlapped big pclusters as below:
+
+ Ext: logical offset | length : physical offset | length
+ 0: 0.. 16384 | 16384 : 151552.. 167936 | 16384
+ 1: 16384.. 32768 | 16384 : 155648.. 172032 | 16384
+ 2: 32768.. 49152 | 16384 : 537223168.. 537239552 | 16384
+...
+
+Here, extent 0/1 are physically overlapped although it's entirely
+_impossible_ for normal filesystem images generated by mkfs.
+
+First, managed folios containing compressed data will be marked as
+up-to-date and then unlocked immediately (unlike in-place folios) when
+compressed I/Os are complete. If physical blocks are not submitted in
+the incremental order, there should be separate BIOs to avoid dependency
+issues. However, the current code mis-arranges z_erofs_fill_bio_vec()
+and BIO submission which causes unexpected BIO waits.
+
+Second, managed folios will be connected to their own pclusters for
+efficient inter-queries. However, this is somewhat hard to implement
+easily if overlapped big pclusters exist. Again, these only appear in
+fuzzed images so let's simply fall back to temporary short-lived pages
+for correctness.
+
+Additionally, it justifies that referenced managed folios cannot be
+truncated for now and reverts part of commit 2080ca1ed3e4 ("erofs: tidy
+up `struct z_erofs_bvec`") for simplicity although it shouldn't be any
+difference.
+
+[Alexey: This patch follows linux 6.6.y conflict resolution changes of
+struct folio -> struct page]
+
+Reported-by: syzbot+4fc98ed414ae63d1ada2@syzkaller.appspotmail.com
+Reported-by: syzbot+de04e06b28cfecf2281c@syzkaller.appspotmail.com
+Reported-by: syzbot+c8c8238b394be4a1087d@syzkaller.appspotmail.com
+Tested-by: syzbot+4fc98ed414ae63d1ada2@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/r/0000000000002fda01061e334873@google.com
+Fixes: 8e6c8fa9f2e9 ("erofs: enable big pcluster feature")
+Link: https://lore.kernel.org/r/20240910070847.3356592-1-hsiangkao@linux.alibaba.com
+Signed-off-by: Alexey Panov <apanov@astralinux.ru>
+Link: https://lore.kernel.org/r/20250304110558.8315-2-apanov@astralinux.ru
+Link: https://lore.kernel.org/r/20250304110558.8315-1-apanov@astralinux.ru
+[ Gao Xiang: re-address the previous Alexey's backport. ]
+CVE: CVE-2024-47736
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/erofs/zdata.c | 60 +++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 32 insertions(+), 28 deletions(-)
+
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -1331,14 +1331,14 @@ repeat:
+ goto out;
+
+ lock_page(page);
+-
+- /* only true if page reclaim goes wrong, should never happen */
+- DBG_BUGON(justfound && PagePrivate(page));
+-
+- /* the page is still in manage cache */
+- if (page->mapping == mc) {
++ if (likely(page->mapping == mc)) {
+ WRITE_ONCE(pcl->compressed_bvecs[nr].page, page);
++ oldpage = page;
+
++ /*
++ * The cached folio is still in managed cache but without
++ * a valid `->private` pcluster hint. Let's reconnect them.
++ */
+ if (!PagePrivate(page)) {
+ /*
+ * impossible to be !PagePrivate(page) for
+@@ -1352,22 +1352,24 @@ repeat:
+ SetPagePrivate(page);
+ }
+
+- /* no need to submit io if it is already up-to-date */
+- if (PageUptodate(page)) {
+- unlock_page(page);
+- page = NULL;
++ if (likely(page->private == (unsigned long)pcl)) {
++ /* don't submit cache I/Os again if already uptodate */
++ if (PageUptodate(page)) {
++ unlock_page(page);
++ page = NULL;
++
++ }
++ goto out;
+ }
+- goto out;
++ /*
++ * Already linked with another pcluster, which only appears in
++ * crafted images by fuzzers for now. But handle this anyway.
++ */
++ tocache = false; /* use temporary short-lived pages */
++ } else {
++ DBG_BUGON(1); /* referenced managed folios can't be truncated */
++ tocache = true;
+ }
+-
+- /*
+- * the managed page has been truncated, it's unsafe to
+- * reuse this one, let's allocate a new cache-managed page.
+- */
+- DBG_BUGON(page->mapping);
+- DBG_BUGON(!justfound);
+-
+- tocache = true;
+ unlock_page(page);
+ put_page(page);
+ out_allocpage:
+@@ -1520,16 +1522,11 @@ static void z_erofs_submit_queue(struct
+ end = cur + pcl->pclusterpages;
+
+ do {
+- struct page *page;
+-
+- page = pickup_page_for_submission(pcl, i++,
+- &f->pagepool, mc);
+- if (!page)
+- continue;
++ struct page *page = NULL;
+
+ if (bio && (cur != last_index + 1 ||
+ last_bdev != mdev.m_bdev)) {
+-submit_bio_retry:
++drain_io:
+ submit_bio(bio);
+ if (memstall) {
+ psi_memstall_leave(&pflags);
+@@ -1538,6 +1535,13 @@ submit_bio_retry:
+ bio = NULL;
+ }
+
++ if (!page) {
++ page = pickup_page_for_submission(pcl, i++,
++ &f->pagepool, mc);
++ if (!page)
++ continue;
++ }
++
+ if (unlikely(PageWorkingset(page)) && !memstall) {
+ psi_memstall_enter(&pflags);
+ memstall = 1;
+@@ -1558,7 +1562,7 @@ submit_bio_retry:
+ }
+
+ if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE)
+- goto submit_bio_retry;
++ goto drain_io;
+
+ last_index = cur;
+ bypass = false;
--- /dev/null
+From stable+bounces-230425-greg=kroah.com@vger.kernel.org Thu Mar 26 07:40:52 2026
+From: Robert Garcia <rob_garcia@163.com>
+Date: Thu, 26 Mar 2026 14:34:27 +0800
+Subject: gfs2: Fix unlikely race in gdlm_put_lock
+To: stable@vger.kernel.org, Andreas Gruenbacher <agruenba@redhat.com>
+Cc: Andrew Price <anprice@redhat.com>, Robert Garcia <rob_garcia@163.com>, Bob Peterson <rpeterso@redhat.com>, cluster-devel@redhat.com, linux-kernel@vger.kernel.org
+Message-ID: <20260326063427.1771116-1-rob_garcia@163.com>
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit 28c4d9bc0708956c1a736a9e49fee71b65deee81 ]
+
+In gdlm_put_lock(), there is a small window of time in which the
+DFL_UNMOUNT flag has been set but the lockspace hasn't been released,
+yet. In that window, dlm may still call gdlm_ast() and gdlm_bast().
+To prevent it from dereferencing freed glock objects, only free the
+glock if the lockspace has actually been released.
+
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Reviewed-by: Andrew Price <anprice@redhat.com>
+[ Minor context change fixed. ]
+Signed-off-by: Robert Garcia <rob_garcia@163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/gfs2/lock_dlm.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/fs/gfs2/lock_dlm.c
++++ b/fs/gfs2/lock_dlm.c
+@@ -301,11 +301,6 @@ static void gdlm_put_lock(struct gfs2_gl
+ gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
+ gfs2_update_request_times(gl);
+
+- /* don't want to call dlm if we've unmounted the lock protocol */
+- if (test_bit(DFL_UNMOUNT, &ls->ls_recover_flags)) {
+- gfs2_glock_free(gl);
+- return;
+- }
+ /* don't want to skip dlm_unlock writing the lvb when lock has one */
+
+ if (test_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags) &&
+@@ -322,6 +317,11 @@ again:
+ goto again;
+ }
+
++ if (error == -ENODEV) {
++ gfs2_glock_free(gl);
++ return;
++ }
++
+ if (error) {
+ fs_err(sdp, "gdlm_unlock %x,%llx err=%d\n",
+ gl->gl_name.ln_type,
--- /dev/null
+From stable+bounces-230289-greg=kroah.com@vger.kernel.org Wed Mar 25 10:29:03 2026
+From: liyin.zhang.cn@windriver.com
+Date: Wed, 25 Mar 2026 17:23:14 +0800
+Subject: mtd: spi-nor: core: avoid odd length/address reads on 8D-8D-8D mode
+To: stable@vger.kernel.org
+Message-ID: <20260325092315.956451-2-liyin.zhang.cn@windriver.com>
+
+From: Pratyush Yadav <p.yadav@ti.com>
+
+[ Upstream commit f156b23df6a84efb2f6686156be94d4988568954 ]
+
+On Octal DTR capable flashes like Micron Xcella reads cannot start or
+end at an odd address in Octal DTR mode. Extra bytes need to be read at
+the start or end to make sure both the start address and length remain
+even.
+
+To avoid allocating too much extra memory, thereby putting unnecessary
+memory pressure on the system, the temporary buffer containing the extra
+padding bytes is capped at PAGE_SIZE bytes. The rest of the 2-byte
+aligned part should be read directly in the main buffer.
+
+Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
+Reviewed-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
+Signed-off-by: Pratyush Yadav <pratyush@kernel.org>
+Link: https://lore.kernel.org/r/20250708091646.292-1-ziniu.wang_1@nxp.com
+[ Resolve conflict in drivers/mtd/spi-nor/core.c.
+ In spi_nor_read(), 6.1.y contains a spi_nor_convert_addr() call
+ before spi_nor_read_data(), introduced by 364995962803 ("mtd:
+ spi-nor: Add a ->convert_addr() method"), which does not exist in
+ mainline. This call is specific to Xilinx S3AN flashes, which use a
+ non-standard address format. In mainline, S3AN flash support was
+ removed entirely, and the corresponding spi_nor_convert_addr() call
+ was dropped by 9539d12d9f52 ("mtd: spi-nor: get rid of non-power-of-2
+ page size handling"). Keep the existing spi_nor_convert_addr() call
+ and insert the new spi_nor_octal_dtr_read() branch after it. ]
+Signed-off-by: Liyin Zhang <liyin.zhang.cn@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/spi-nor/core.c | 76 ++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 75 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -1677,6 +1677,76 @@ static const struct flash_info *spi_nor_
+ return info;
+ }
+
++/*
++ * On Octal DTR capable flashes, reads cannot start or end at an odd
++ * address in Octal DTR mode. Extra bytes need to be read at the start
++ * or end to make sure both the start address and length remain even.
++ */
++static int spi_nor_octal_dtr_read(struct spi_nor *nor, loff_t from, size_t len,
++ u_char *buf)
++{
++ u_char *tmp_buf;
++ size_t tmp_len;
++ loff_t start, end;
++ int ret, bytes_read;
++
++ if (IS_ALIGNED(from, 2) && IS_ALIGNED(len, 2))
++ return spi_nor_read_data(nor, from, len, buf);
++ else if (IS_ALIGNED(from, 2) && len > PAGE_SIZE)
++ return spi_nor_read_data(nor, from, round_down(len, PAGE_SIZE),
++ buf);
++
++ tmp_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
++ if (!tmp_buf)
++ return -ENOMEM;
++
++ start = round_down(from, 2);
++ end = round_up(from + len, 2);
++
++ /*
++ * Avoid allocating too much memory. The requested read length might be
++ * quite large. Allocating a buffer just as large (slightly bigger, in
++ * fact) would put unnecessary memory pressure on the system.
++ *
++ * For example if the read is from 3 to 1M, then this will read from 2
++ * to 4098. The reads from 4098 to 1M will then not need a temporary
++ * buffer so they can proceed as normal.
++ */
++ tmp_len = min_t(size_t, end - start, PAGE_SIZE);
++
++ ret = spi_nor_read_data(nor, start, tmp_len, tmp_buf);
++ if (ret == 0) {
++ ret = -EIO;
++ goto out;
++ }
++ if (ret < 0)
++ goto out;
++
++ /*
++ * More bytes are read than actually requested, but that number can't be
++ * reported to the calling function or it will confuse its calculations.
++ * Calculate how many of the _requested_ bytes were read.
++ */
++ bytes_read = ret;
++
++ if (from != start)
++ ret -= from - start;
++
++ /*
++ * Only account for extra bytes at the end if they were actually read.
++ * For example, if the total length was truncated because of temporary
++ * buffer size limit then the adjustment for the extra bytes at the end
++ * is not needed.
++ */
++ if (start + bytes_read == end)
++ ret -= end - (from + len);
++
++ memcpy(buf, tmp_buf + (from - start), ret);
++out:
++ kfree(tmp_buf);
++ return ret;
++}
++
+ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+ {
+@@ -1694,7 +1764,11 @@ static int spi_nor_read(struct mtd_info
+
+ addr = spi_nor_convert_addr(nor, addr);
+
+- ret = spi_nor_read_data(nor, addr, len, buf);
++ if (nor->read_proto == SNOR_PROTO_8_8_8_DTR)
++ ret = spi_nor_octal_dtr_read(nor, addr, len, buf);
++ else
++ ret = spi_nor_read_data(nor, addr, len, buf);
++
+ if (ret == 0) {
+ /* We shouldn't see 0-length reads */
+ ret = -EIO;
--- /dev/null
+From stable+bounces-230291-greg=kroah.com@vger.kernel.org Wed Mar 25 10:31:34 2026
+From: liyin.zhang.cn@windriver.com
+Date: Wed, 25 Mar 2026 17:23:15 +0800
+Subject: mtd: spi-nor: core: avoid odd length/address writes in 8D-8D-8D mode
+To: stable@vger.kernel.org
+Message-ID: <20260325092315.956451-3-liyin.zhang.cn@windriver.com>
+
+From: Pratyush Yadav <p.yadav@ti.com>
+
+[ Upstream commit 17926cd770ec837ed27d9856cf07f2da8dda4131 ]
+
+On Octal DTR capable flashes like Micron Xcella the writes cannot start
+or end at an odd address in Octal DTR mode. Extra 0xff bytes need to be
+appended or prepended to make sure the start address and end address are
+even. 0xff is used because on NOR flashes a program operation can only
+flip bits from 1 to 0, not the other way round. 0 to 1 flip needs to
+happen via erases.
+
+Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
+Reviewed-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Luke Wang <ziniu.wang_1@nxp.com>
+Signed-off-by: Pratyush Yadav <pratyush@kernel.org>
+Link: https://lore.kernel.org/r/20250708091646.292-2-ziniu.wang_1@nxp.com
+[ Resolve conflict in drivers/mtd/spi-nor/core.c.
+ In spi_nor_write(), the spi_nor_lock_device() and
+ spi_nor_unlock_device() mechanism was not yet introduced in 6.1.y.
+ Drop the spi_nor_unlock_device() call from the patch. ]
+Signed-off-by: Liyin Zhang <liyin.zhang.cn@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/spi-nor/core.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 68 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -1791,6 +1791,68 @@ read_err:
+ }
+
+ /*
++ * On Octal DTR capable flashes, writes cannot start or end at an odd address
++ * in Octal DTR mode. Extra 0xff bytes need to be appended or prepended to
++ * make sure the start address and end address are even. 0xff is used because
++ * on NOR flashes a program operation can only flip bits from 1 to 0, not the
++ * other way round. 0 to 1 flip needs to happen via erases.
++ */
++static int spi_nor_octal_dtr_write(struct spi_nor *nor, loff_t to, size_t len,
++ const u8 *buf)
++{
++ u8 *tmp_buf;
++ size_t bytes_written;
++ loff_t start, end;
++ int ret;
++
++ if (IS_ALIGNED(to, 2) && IS_ALIGNED(len, 2))
++ return spi_nor_write_data(nor, to, len, buf);
++
++ tmp_buf = kmalloc(nor->params->page_size, GFP_KERNEL);
++ if (!tmp_buf)
++ return -ENOMEM;
++
++ memset(tmp_buf, 0xff, nor->params->page_size);
++
++ start = round_down(to, 2);
++ end = round_up(to + len, 2);
++
++ memcpy(tmp_buf + (to - start), buf, len);
++
++ ret = spi_nor_write_data(nor, start, end - start, tmp_buf);
++ if (ret == 0) {
++ ret = -EIO;
++ goto out;
++ }
++ if (ret < 0)
++ goto out;
++
++ /*
++ * More bytes are written than actually requested, but that number can't
++ * be reported to the calling function or it will confuse its
++ * calculations. Calculate how many of the _requested_ bytes were
++ * written.
++ */
++ bytes_written = ret;
++
++ if (to != start)
++ ret -= to - start;
++
++ /*
++ * Only account for extra bytes at the end if they were actually
++ * written. For example, if for some reason the controller could only
++ * complete a partial write then the adjustment for the extra bytes at
++ * the end is not needed.
++ */
++ if (start + bytes_written == end)
++ ret -= end - (to + len);
++
++out:
++ kfree(tmp_buf);
++ return ret;
++}
++
++/*
+ * Write an address range to the nor chip. Data must be written in
+ * FLASH_PAGESIZE chunks. The address range may be any size provided
+ * it is within the physical boundaries.
+@@ -1834,7 +1896,12 @@ static int spi_nor_write(struct mtd_info
+ if (ret)
+ goto write_err;
+
+- ret = spi_nor_write_data(nor, addr, page_remain, buf + i);
++ if (nor->write_proto == SNOR_PROTO_8_8_8_DTR)
++ ret = spi_nor_octal_dtr_write(nor, addr, page_remain,
++ buf + i);
++ else
++ ret = spi_nor_write_data(nor, addr, page_remain,
++ buf + i);
+ if (ret < 0)
+ goto write_err;
+ written = ret;
--- /dev/null
+From 681739313@139.com Fri Mar 27 02:52:59 2026
+From: Rajani Kantha <681739313@139.com>
+Date: Fri, 27 Mar 2026 09:52:37 +0800
+Subject: net: phy: allow MDIO bus PM ops to start/stop state machine for phylink-controlled PHY
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org, vladimir.oltean@nxp.com
+Cc: patches@lists.linux.dev, linux-kernel@vger.kernel.org, andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com, f.fainelli@gmail.com, netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, wei.fang@nxp.com
+Message-ID: <20260327015237.1713008-1-681739313@139.com>
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit fc75ea20ffb452652f0d4033f38fe88d7cfdae35 ]
+
+DSA has 2 kinds of drivers:
+
+1. Those who call dsa_switch_suspend() and dsa_switch_resume() from
+ their device PM ops: qca8k-8xxx, bcm_sf2, microchip ksz
+2. Those who don't: all others. The above methods should be optional.
+
+For type 1, dsa_switch_suspend() calls dsa_user_suspend() -> phylink_stop(),
+and dsa_switch_resume() calls dsa_user_resume() -> phylink_start().
+These seem good candidates for setting mac_managed_pm = true because
+that is essentially its definition [1], but that does not seem to be the
+biggest problem for now, and is not what this change focuses on.
+
+Talking strictly about the 2nd category of DSA drivers here (which
+do not have MAC managed PM, meaning that for their attached PHYs,
+mdio_bus_phy_suspend() and mdio_bus_phy_resume() should run in full),
+I have noticed that the following warning from mdio_bus_phy_resume() is
+triggered:
+
+ WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY &&
+ phydev->state != PHY_UP);
+
+because the PHY state machine is running.
+
+It's running as a result of a previous dsa_user_open() -> ... ->
+phylink_start() -> phy_start() having been initiated by the user.
+
+The previous mdio_bus_phy_suspend() was supposed to have called
+phy_stop_machine(), but it didn't. So this is why the PHY is in state
+PHY_NOLINK by the time mdio_bus_phy_resume() runs.
+
+mdio_bus_phy_suspend() did not call phy_stop_machine() because for
+phylink, the phydev->adjust_link function pointer is NULL. This seems a
+technicality introduced by commit fddd91016d16 ("phylib: fix PAL state
+machine restart on resume"). That commit was written before phylink
+existed, and was intended to avoid crashing with consumer drivers which
+don't use the PHY state machine - phylink always does, when using a PHY.
+But phylink itself has historically not been developed with
+suspend/resume in mind, and apparently not tested too much in that
+scenario, allowing this bug to exist unnoticed for so long. Plus, prior
+to the WARN_ON(), it would have likely been invisible.
+
+This issue is not in fact restricted to type 2 DSA drivers (according to
+the above ad-hoc classification), but can be extrapolated to any MAC
+driver with phylink and MDIO-bus-managed PHY PM ops. DSA is just where
+the issue was reported. Assuming mac_managed_pm is set correctly, a
+quick search indicates the following other drivers might be affected:
+
+$ grep -Zlr PHYLINK_NETDEV drivers/ | xargs -0 grep -L mac_managed_pm
+drivers/net/ethernet/atheros/ag71xx.c
+drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+drivers/net/ethernet/freescale/ucc_geth.c
+drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+drivers/net/ethernet/marvell/mvneta.c
+drivers/net/ethernet/marvell/prestera/prestera_main.c
+drivers/net/ethernet/mediatek/mtk_eth_soc.c
+drivers/net/ethernet/altera/altera_tse_main.c
+drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
+drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
+drivers/net/ethernet/tehuti/tn40_phy.c
+drivers/net/ethernet/mscc/ocelot_net.c
+
+Make the existing conditions dependent on the PHY device having a
+phydev->phy_link_change() implementation equal to the default
+phy_link_change() provided by phylib. Otherwise, we implicitly know that
+the phydev has the phylink-provided phylink_phy_change() callback, and
+when phylink is used, the PHY state machine always needs to be stopped/
+started on the suspend/resume path. The code is structured as such that
+if phydev->phy_link_change() is absent, it is a matter of time until the
+kernel will crash - no need to further complicate the test.
+
+Thus, for the situation where the PM is not managed by the MAC, we will
+make the MDIO bus PM ops treat identically the phylink-controlled PHYs
+with the phylib-controlled PHYs where an adjust_link() callback is
+supplied. In both cases, the MDIO bus PM ops should stop and restart the
+PHY state machine.
+
+[1] https://lore.kernel.org/netdev/Z-1tiW9zjcoFkhwc@shell.armlinux.org.uk/
+
+Fixes: 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() state")
+Reported-by: Wei Fang <wei.fang@nxp.com>
+Tested-by: Wei Fang <wei.fang@nxp.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250407094042.2155633-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Rajani Kantha <681739313@139.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/phy_device.c | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -247,6 +247,33 @@ static void phy_link_change(struct phy_d
+ phydev->mii_ts->link_state(phydev->mii_ts, phydev);
+ }
+
++/**
++ * phy_uses_state_machine - test whether consumer driver uses PAL state machine
++ * @phydev: the target PHY device structure
++ *
++ * Ultimately, this aims to indirectly determine whether the PHY is attached
++ * to a consumer which uses the state machine by calling phy_start() and
++ * phy_stop().
++ *
++ * When the PHY driver consumer uses phylib, it must have previously called
++ * phy_connect_direct() or one of its derivatives, so that phy_prepare_link()
++ * has set up a hook for monitoring state changes.
++ *
++ * When the PHY driver is used by the MAC driver consumer through phylink (the
++ * only other provider of a phy_link_change() method), using the PHY state
++ * machine is not optional.
++ *
++ * Return: true if consumer calls phy_start() and phy_stop(), false otherwise.
++ */
++static bool phy_uses_state_machine(struct phy_device *phydev)
++{
++ if (phydev->phy_link_change == phy_link_change)
++ return phydev->attached_dev && phydev->adjust_link;
++
++ /* phydev->phy_link_change is implicitly phylink_phy_change() */
++ return true;
++}
++
+ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
+ {
+ struct device_driver *drv = phydev->mdio.dev.driver;
+@@ -307,7 +334,7 @@ static __maybe_unused int mdio_bus_phy_s
+ * may call phy routines that try to grab the same lock, and that may
+ * lead to a deadlock.
+ */
+- if (phydev->attached_dev && phydev->adjust_link)
++ if (phy_uses_state_machine(phydev))
+ phy_stop_machine(phydev);
+
+ if (!mdio_bus_phy_may_suspend(phydev))
+@@ -361,7 +388,7 @@ no_resume:
+ }
+ }
+
+- if (phydev->attached_dev && phydev->adjust_link)
++ if (phy_uses_state_machine(phydev))
+ phy_start_machine(phydev);
+
+ return 0;
--- /dev/null
+From 681739313@139.com Fri Mar 27 02:53:35 2026
+From: Rajani Kantha <681739313@139.com>
+Date: Fri, 27 Mar 2026 09:53:16 +0800
+Subject: net: phy: fix phy_uses_state_machine()
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org, rmk+kernel@armlinux.org.uk
+Cc: patches@lists.linux.dev, linux-kernel@vger.kernel.org, andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, vladimir.oltean@nxp.com, netdev@vger.kernel.org, xu.yang_2@nxp.com
+Message-ID: <20260327015316.1713133-1-681739313@139.com>
+
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit e0d1c55501d377163eb57feed863777ed1c973ad ]
+
+The blamed commit changed the conditions which phylib uses to stop
+and start the state machine in the suspend and resume paths, and
+while improving it, has caused two issues.
+
+The original code used this test:
+
+ phydev->attached_dev && phydev->adjust_link
+
+and if true, the paths would handle the PHY state machine. This test
+evaluates true for normal drivers that are using phylib directly
+while the PHY is attached to the network device, but false in all
+other cases, which include the following cases:
+
+- when the PHY has never been attached to a network device.
+- when the PHY has been detached from a network device (as phy_detach()
+ sets phydev->attached_dev to NULL, phy_disconnect() calls
+ phy_detach() and additionally sets phydev->adjust_link NULL.)
+- when phylink is using the driver (as phydev->adjust_link is NULL.)
+
+Only the third case was incorrect, and the blamed commit attempted to
+fix this by changing this test to (simplified for brevity, see
+phy_uses_state_machine()):
+
+ phydev->phy_link_change == phy_link_change ?
+ phydev->attached_dev && phydev->adjust_link : true
+
+However, this also incorrectly evaluates true in the first two cases.
+
+Fix the first case by ensuring that phy_uses_state_machine() returns
+false when phydev->phy_link_change is NULL.
+
+Fix the second case by ensuring that phydev->phy_link_change is set to
+NULL when phy_detach() is called.
+
+Reported-by: Xu Yang <xu.yang_2@nxp.com>
+Link: https://lore.kernel.org/r/20250806082931.3289134-1-xu.yang_2@nxp.com
+Fixes: fc75ea20ffb4 ("net: phy: allow MDIO bus PM ops to start/stop state machine for phylink-controlled PHY")
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/E1uvMEz-00000003Aoe-3qWe@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Rajani Kantha <681739313@139.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/phy_device.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -270,8 +270,7 @@ static bool phy_uses_state_machine(struc
+ if (phydev->phy_link_change == phy_link_change)
+ return phydev->attached_dev && phydev->adjust_link;
+
+- /* phydev->phy_link_change is implicitly phylink_phy_change() */
+- return true;
++ return !!phydev->phy_link_change;
+ }
+
+ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
+@@ -1791,6 +1790,8 @@ void phy_detach(struct phy_device *phyde
+ phydev->attached_dev->phydev = NULL;
+ phydev->attached_dev = NULL;
+ }
++
++ phydev->phy_link_change = NULL;
+ phydev->phylink = NULL;
+
+ if (phydev->mdio.dev.driver)
--- /dev/null
+From 681739313@139.com Fri Mar 27 02:51:43 2026
+From: Rajani Kantha <681739313@139.com>
+Date: Fri, 27 Mar 2026 09:51:20 +0800
+Subject: net: phy: move phy_link_change() prior to mdio_bus_phy_may_suspend()
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org, vladimir.oltean@nxp.com
+Cc: patches@lists.linux.dev, linux-kernel@vger.kernel.org, andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, rmk+kernel@armlinux.org.uk
+Message-ID: <20260327015120.1712759-1-681739313@139.com>
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit f40a673d6b4a128fe95dd9b8c3ed02da50a6a862 ]
+
+In an upcoming change, mdio_bus_phy_may_suspend() will need to
+distinguish a phylib-based PHY client from a phylink PHY client.
+For that, it will need to compare the phydev->phy_link_change() function
+pointer with the eponymous phy_link_change() provided by phylib.
+
+To avoid forward function declarations, the default PHY link state
+change method should be moved upwards. There is no functional change
+associated with this patch, it is only to reduce the noise from a real
+bug fix.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/20250407093900.2155112-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Minor context change fixed ]
+Signed-off-by: Rajani Kantha <681739313@139.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/phy_device.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -234,6 +234,19 @@ static struct phy_driver genphy_driver;
+ static LIST_HEAD(phy_fixup_list);
+ static DEFINE_MUTEX(phy_fixup_lock);
+
++static void phy_link_change(struct phy_device *phydev, bool up)
++{
++ struct net_device *netdev = phydev->attached_dev;
++
++ if (up)
++ netif_carrier_on(netdev);
++ else
++ netif_carrier_off(netdev);
++ phydev->adjust_link(netdev);
++ if (phydev->mii_ts && phydev->mii_ts->link_state)
++ phydev->mii_ts->link_state(phydev->mii_ts, phydev);
++}
++
+ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
+ {
+ struct device_driver *drv = phydev->mdio.dev.driver;
+@@ -1036,19 +1049,6 @@ struct phy_device *phy_find_first(struct
+ }
+ EXPORT_SYMBOL(phy_find_first);
+
+-static void phy_link_change(struct phy_device *phydev, bool up)
+-{
+- struct net_device *netdev = phydev->attached_dev;
+-
+- if (up)
+- netif_carrier_on(netdev);
+- else
+- netif_carrier_off(netdev);
+- phydev->adjust_link(netdev);
+- if (phydev->mii_ts && phydev->mii_ts->link_state)
+- phydev->mii_ts->link_state(phydev->mii_ts, phydev);
+-}
+-
+ /**
+ * phy_prepare_link - prepares the PHY layer to monitor link status
+ * @phydev: target phy_device struct
--- /dev/null
+From matttbe@kernel.org Tue Mar 24 10:50:56 2026
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 24 Mar 2026 10:49:39 +0100
+Subject: selftests: mptcp: join: check removing signal+subflow endp
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, sashal@kernel.org, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20260324094936.1826804-6-matttbe@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+commit 1777f349ff41b62dfe27454b69c27b0bc99ffca5 upstream.
+
+This validates the previous commit: endpoints with both the signal and
+subflow flags should always be marked as used even if it was not
+possible to create new subflows due to the MPTCP PM limits.
+
+For this test, an extra endpoint is created with both the signal and the
+subflow flags, and limits are set not to create extra subflows. In this
+case, an ADD_ADDR is sent, but no subflows are created. Still, the local
+endpoint is marked as used, and no warning is fired when removing the
+endpoint, after having sent a RM_ADDR.
+
+The 'Fixes' tag here below is the same as the one from the previous
+commit: this patch here is not fixing anything wrong in the selftests,
+but it validates the previous fix for an issue introduced by this commit
+ID.
+
+Fixes: 85df533a787b ("mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260303-net-mptcp-misc-fixes-7-0-rc2-v1-5-4b5462b6f016@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ No conflicts, but in this kernel version 'run_tests' doesn't support
+ parameters set via env vars: positional parameters need to be used.
+ See commit 595ef566a2ef ("selftests: mptcp: drop addr_nr_ns1/2
+ parameters") and commit e571fb09c893 ("selftests: mptcp: add speed env
+ var") which are not in this kernel version. ]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/net/mptcp/mptcp_join.sh | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+@@ -2407,6 +2407,18 @@ remove_tests()
+ chk_rst_nr 0 0
+ fi
+
++ # signal+subflow with limits, remove
++ if reset "remove signal+subflow with limits"; then
++ pm_nl_set_limits $ns1 0 0
++ pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,subflow
++ pm_nl_set_limits $ns2 0 0
++ run_tests $ns1 $ns2 10.0.1.1 0 -1 0 slow
++ chk_join_nr 0 0 0
++ chk_add_nr 1 1
++ chk_rm_nr 1 0 invert
++ chk_rst_nr 0 0
++ fi
++
+ # addresses remove
+ if reset "remove addresses"; then
+ pm_nl_set_limits $ns1 3 3
--- /dev/null
+From matttbe@kernel.org Tue Mar 24 10:50:55 2026
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Tue, 24 Mar 2026 10:49:38 +0100
+Subject: selftests: mptcp: join: implicit: stop transfer after last check
+To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, sashal@kernel.org
+Message-ID: <20260324094936.1826804-5-matttbe@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+With this kernel version, the 'implicit EP' MPTCP Join selftest ended
+with an error message:
+
+ 115 implicit EP creation[ ok ]
+ ID change is prevented[ ok ]
+ modif is allowed[ ok ]
+ TcpPassiveOpens 2 0.0
+ TcpEstabResets 2 0.0
+ TcpInSegs 315 0.0
+ TcpOutSegs 617 0.0
+ TcpOutRsts 1 0.0
+ TcpExtDelayedACKs 289 0.0
+ TcpExtTCPPureAcks 6 0.0
+ TcpExtTCPOrigDataSent 306 0.0
+ TcpExtTCPDelivered 306 0.0
+ MPTcpExtMPCapableSYNRX 1 0.0
+ MPTcpExtMPCapableACKRX 1 0.0
+ MPTcpExtMPJoinSynRx 1 0.0
+ MPTcpExtMPJoinAckRx 1 0.0
+ MPTcpExtAddAddr 1 0.0
+ MPTcpExtEchoAdd 1 0.0
+ MPTcpExtMPFastcloseTx 1 0.0
+ MPTcpExtMPRstTx 1 0.0
+ MPTcpExtMPRstRx 1 0.0
+ TcpActiveOpens 2 0.0
+ TcpEstabResets 2 0.0
+ TcpInSegs 617 0.0
+ TcpOutSegs 315 0.0
+ TcpOutRsts 1 0.0
+ TcpExtTCPPureAcks 308 0.0
+ TcpExtTCPOrigDataSent 306 0.0
+ TcpExtTCPDelivered 307 0.0
+ MPTcpExtMPCapableSYNTX 1 0.0
+ MPTcpExtMPCapableSYNACKRX 1 0.0
+ MPTcpExtMPJoinSynAckRx 1 0.0
+ MPTcpExtAddAddr 1 0.0
+ MPTcpExtEchoAdd 1 0.0
+ MPTcpExtMPFastcloseRx 1 0.0
+ MPTcpExtMPRstTx 1 0.0
+ MPTcpExtMPRstRx 1 0.0
+ MPTcpExtRcvWndShared 1 0.0
+
+That's because the test was waiting for the end of the transfer for no
+reasons, which ended after a timeout with an error. In this case, the
+stats were displayed, but this error was ignored: the end of transfer is
+not validated in this test.
+
+To fix that, stop the transfer after the last check, similar to what is
+done in the other tests.
+
+Fixes: 699879d5f866 ("selftests: mptcp: join: endpoints: longer transfer")
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/net/mptcp/mptcp_join.sh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+@@ -3429,6 +3429,7 @@ endpoint_tests()
+ pm_nl_set_limits $ns2 2 2
+ pm_nl_add_endpoint $ns1 10.0.2.1 flags signal
+ run_tests $ns1 $ns2 10.0.1.1 128 0 0 slow 2>/dev/null &
++ local tests_pid=$!
+
+ wait_mpj $ns1
+ pm_nl_check_endpoint 1 "creation" \
+@@ -3441,6 +3442,7 @@ endpoint_tests()
+ pm_nl_add_endpoint $ns2 10.0.2.2 flags signal
+ pm_nl_check_endpoint 0 "modif is allowed" \
+ $ns2 10.0.2.2 id 1 flags signal
++ kill_wait "${tests_pid}"
+ kill_tests_wait
+ fi
+
ext4-handle-wraparound-when-searching-for-blocks-for-indirect-mapped-blocks.patch
cpufreq-governor-free-dbs_data-directly-when-gov-init-fails.patch
cpufreq-governor-fix-double-free-in-cpufreq_dbs_governor_init-error-path.patch
+mtd-spi-nor-core-avoid-odd-length-address-reads-on-8d-8d-8d-mode.patch
+mtd-spi-nor-core-avoid-odd-length-address-writes-in-8d-8d-8d-mode.patch
+erofs-handle-overlapped-pclusters-out-of-crafted-images-properly.patch
+erofs-fix-psi-memstall-accounting.patch
+erofs-fix-the-slab-out-of-bounds-in-drop_buffers.patch
+xfs-avoid-dereferencing-log-items-after-push-callbacks.patch
+xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch
+net-phy-move-phy_link_change-prior-to-mdio_bus_phy_may_suspend.patch
+net-phy-allow-mdio-bus-pm-ops-to-start-stop-state-machine-for-phylink-controlled-phy.patch
+net-phy-fix-phy_uses_state_machine.patch
+gfs2-fix-unlikely-race-in-gdlm_put_lock.patch
+selftests-mptcp-join-implicit-stop-transfer-after-last-check.patch
+selftests-mptcp-join-check-removing-signal-subflow-endp.patch
+bluetooth-eir-fix-possible-crashes-on-eir_create_adv_data.patch
--- /dev/null
+From 79ef34ec0554ec04bdbafafbc9836423734e1bd6 Mon Sep 17 00:00:00 2001
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+Date: Tue, 10 Mar 2026 18:38:38 +0000
+Subject: xfs: avoid dereferencing log items after push callbacks
+
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+
+commit 79ef34ec0554ec04bdbafafbc9836423734e1bd6 upstream.
+
+After xfsaild_push_item() calls iop_push(), the log item may have been
+freed if the AIL lock was dropped during the push. Background inode
+reclaim or the dquot shrinker can free the log item while the AIL lock
+is not held, and the tracepoints in the switch statement dereference
+the log item after iop_push() returns.
+
+Fix this by capturing the log item type, flags, and LSN before calling
+xfsaild_push_item(), and introducing a new xfs_ail_push_class trace
+event class that takes these pre-captured values and the ailp pointer
+instead of the log item pointer.
+
+Reported-by: syzbot+652af2b3c5569c4ab63c@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=652af2b3c5569c4ab63c
+Fixes: 90c60e164012 ("xfs: xfs_iflush() is no longer necessary")
+Cc: stable@vger.kernel.org # v5.9
+Signed-off-by: Yuto Ohnuki <ytohnuki@amazon.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_trace.c | 1 +
+ fs/xfs/xfs_trace.h | 36 ++++++++++++++++++++++++++++++++----
+ fs/xfs/xfs_trans_ail.c | 26 +++++++++++++++++++-------
+ 3 files changed, 52 insertions(+), 11 deletions(-)
+
+--- a/fs/xfs/xfs_trace.c
++++ b/fs/xfs/xfs_trace.c
+@@ -22,6 +22,7 @@
+ #include "xfs_trans.h"
+ #include "xfs_log.h"
+ #include "xfs_log_priv.h"
++#include "xfs_trans_priv.h"
+ #include "xfs_buf_item.h"
+ #include "xfs_quota.h"
+ #include "xfs_dquot_item.h"
+--- a/fs/xfs/xfs_trace.h
++++ b/fs/xfs/xfs_trace.h
+@@ -47,6 +47,7 @@
+ #include <linux/tracepoint.h>
+
+ struct xfs_agf;
++struct xfs_ail;
+ struct xfs_alloc_arg;
+ struct xfs_attr_list_context;
+ struct xfs_buf_log_item;
+@@ -1335,14 +1336,41 @@ TRACE_EVENT(xfs_log_force,
+ DEFINE_EVENT(xfs_log_item_class, name, \
+ TP_PROTO(struct xfs_log_item *lip), \
+ TP_ARGS(lip))
+-DEFINE_LOG_ITEM_EVENT(xfs_ail_push);
+-DEFINE_LOG_ITEM_EVENT(xfs_ail_pinned);
+-DEFINE_LOG_ITEM_EVENT(xfs_ail_locked);
+-DEFINE_LOG_ITEM_EVENT(xfs_ail_flushing);
+ DEFINE_LOG_ITEM_EVENT(xfs_cil_whiteout_mark);
+ DEFINE_LOG_ITEM_EVENT(xfs_cil_whiteout_skip);
+ DEFINE_LOG_ITEM_EVENT(xfs_cil_whiteout_unpin);
+
++DECLARE_EVENT_CLASS(xfs_ail_push_class,
++ TP_PROTO(struct xfs_ail *ailp, uint type, unsigned long flags, xfs_lsn_t lsn),
++ TP_ARGS(ailp, type, flags, lsn),
++ TP_STRUCT__entry(
++ __field(dev_t, dev)
++ __field(uint, type)
++ __field(unsigned long, flags)
++ __field(xfs_lsn_t, lsn)
++ ),
++ TP_fast_assign(
++ __entry->dev = ailp->ail_log->l_mp->m_super->s_dev;
++ __entry->type = type;
++ __entry->flags = flags;
++ __entry->lsn = lsn;
++ ),
++ TP_printk("dev %d:%d lsn %d/%d type %s flags %s",
++ MAJOR(__entry->dev), MINOR(__entry->dev),
++ CYCLE_LSN(__entry->lsn), BLOCK_LSN(__entry->lsn),
++ __print_symbolic(__entry->type, XFS_LI_TYPE_DESC),
++ __print_flags(__entry->flags, "|", XFS_LI_FLAGS))
++)
++
++#define DEFINE_AIL_PUSH_EVENT(name) \
++DEFINE_EVENT(xfs_ail_push_class, name, \
++ TP_PROTO(struct xfs_ail *ailp, uint type, unsigned long flags, xfs_lsn_t lsn), \
++ TP_ARGS(ailp, type, flags, lsn))
++DEFINE_AIL_PUSH_EVENT(xfs_ail_push);
++DEFINE_AIL_PUSH_EVENT(xfs_ail_pinned);
++DEFINE_AIL_PUSH_EVENT(xfs_ail_locked);
++DEFINE_AIL_PUSH_EVENT(xfs_ail_flushing);
++
+ DECLARE_EVENT_CLASS(xfs_ail_class,
+ TP_PROTO(struct xfs_log_item *lip, xfs_lsn_t old_lsn, xfs_lsn_t new_lsn),
+ TP_ARGS(lip, old_lsn, new_lsn),
+--- a/fs/xfs/xfs_trans_ail.c
++++ b/fs/xfs/xfs_trans_ail.c
+@@ -389,6 +389,12 @@ xfsaild_resubmit_item(
+ return XFS_ITEM_SUCCESS;
+ }
+
++/*
++ * Push a single log item from the AIL.
++ *
++ * @lip may have been released and freed by the time this function returns,
++ * so callers must not dereference the log item afterwards.
++ */
+ static inline uint
+ xfsaild_push_item(
+ struct xfs_ail *ailp,
+@@ -474,20 +480,26 @@ xfsaild_push(
+
+ lsn = lip->li_lsn;
+ while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) {
+- int lock_result;
++ int lock_result;
++ uint type = lip->li_type;
++ unsigned long flags = lip->li_flags;
++ xfs_lsn_t item_lsn = lip->li_lsn;
+
+ /*
+ * Note that iop_push may unlock and reacquire the AIL lock. We
+ * rely on the AIL cursor implementation to be able to deal with
+ * the dropped lock.
++ *
++ * The log item may have been freed by the push, so it must not
++ * be accessed or dereferenced below this line.
+ */
+ lock_result = xfsaild_push_item(ailp, lip);
+ switch (lock_result) {
+ case XFS_ITEM_SUCCESS:
+ XFS_STATS_INC(mp, xs_push_ail_success);
+- trace_xfs_ail_push(lip);
++ trace_xfs_ail_push(ailp, type, flags, item_lsn);
+
+- ailp->ail_last_pushed_lsn = lsn;
++ ailp->ail_last_pushed_lsn = item_lsn;
+ break;
+
+ case XFS_ITEM_FLUSHING:
+@@ -503,22 +515,22 @@ xfsaild_push(
+ * AIL is being flushed.
+ */
+ XFS_STATS_INC(mp, xs_push_ail_flushing);
+- trace_xfs_ail_flushing(lip);
++ trace_xfs_ail_flushing(ailp, type, flags, item_lsn);
+
+ flushing++;
+- ailp->ail_last_pushed_lsn = lsn;
++ ailp->ail_last_pushed_lsn = item_lsn;
+ break;
+
+ case XFS_ITEM_PINNED:
+ XFS_STATS_INC(mp, xs_push_ail_pinned);
+- trace_xfs_ail_pinned(lip);
++ trace_xfs_ail_pinned(ailp, type, flags, item_lsn);
+
+ stuck++;
+ ailp->ail_log_flush++;
+ break;
+ case XFS_ITEM_LOCKED:
+ XFS_STATS_INC(mp, xs_push_ail_locked);
+- trace_xfs_ail_locked(lip);
++ trace_xfs_ail_locked(ailp, type, flags, item_lsn);
+
+ stuck++;
+ break;
--- /dev/null
+From 394d70b86fae9fe865e7e6d9540b7696f73aa9b6 Mon Sep 17 00:00:00 2001
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+Date: Tue, 10 Mar 2026 18:38:39 +0000
+Subject: xfs: save ailp before dropping the AIL lock in push callbacks
+
+From: Yuto Ohnuki <ytohnuki@amazon.com>
+
+commit 394d70b86fae9fe865e7e6d9540b7696f73aa9b6 upstream.
+
+In xfs_inode_item_push() and xfs_qm_dquot_logitem_push(), the AIL lock
+is dropped to perform buffer IO. Once the cluster buffer no longer
+protects the log item from reclaim, the log item may be freed by
+background reclaim or the dquot shrinker. The subsequent spin_lock()
+call dereferences lip->li_ailp, which is a use-after-free.
+
+Fix this by saving the ailp pointer in a local variable while the AIL
+lock is held and the log item is guaranteed to be valid.
+
+Reported-by: syzbot+652af2b3c5569c4ab63c@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=652af2b3c5569c4ab63c
+Fixes: 90c60e164012 ("xfs: xfs_iflush() is no longer necessary")
+Cc: stable@vger.kernel.org # v5.9
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Yuto Ohnuki <ytohnuki@amazon.com>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_dquot_item.c | 9 +++++++--
+ fs/xfs/xfs_inode_item.c | 9 +++++++--
+ 2 files changed, 14 insertions(+), 4 deletions(-)
+
+--- a/fs/xfs/xfs_dquot_item.c
++++ b/fs/xfs/xfs_dquot_item.c
+@@ -125,6 +125,7 @@ xfs_qm_dquot_logitem_push(
+ {
+ struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
+ struct xfs_buf *bp = lip->li_buf;
++ struct xfs_ail *ailp = lip->li_ailp;
+ uint rval = XFS_ITEM_SUCCESS;
+ int error;
+
+@@ -153,7 +154,7 @@ xfs_qm_dquot_logitem_push(
+ goto out_unlock;
+ }
+
+- spin_unlock(&lip->li_ailp->ail_lock);
++ spin_unlock(&ailp->ail_lock);
+
+ error = xfs_qm_dqflush(dqp, &bp);
+ if (!error) {
+@@ -163,7 +164,11 @@ xfs_qm_dquot_logitem_push(
+ } else if (error == -EAGAIN)
+ rval = XFS_ITEM_LOCKED;
+
+- spin_lock(&lip->li_ailp->ail_lock);
++ /*
++ * The buffer no longer protects the log item from reclaim, so
++ * do not reference lip after this point.
++ */
++ spin_lock(&ailp->ail_lock);
+ out_unlock:
+ xfs_dqunlock(dqp);
+ return rval;
+--- a/fs/xfs/xfs_inode_item.c
++++ b/fs/xfs/xfs_inode_item.c
+@@ -727,6 +727,7 @@ xfs_inode_item_push(
+ struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+ struct xfs_inode *ip = iip->ili_inode;
+ struct xfs_buf *bp = lip->li_buf;
++ struct xfs_ail *ailp = lip->li_ailp;
+ uint rval = XFS_ITEM_SUCCESS;
+ int error;
+
+@@ -749,7 +750,7 @@ xfs_inode_item_push(
+ if (!xfs_buf_trylock(bp))
+ return XFS_ITEM_LOCKED;
+
+- spin_unlock(&lip->li_ailp->ail_lock);
++ spin_unlock(&ailp->ail_lock);
+
+ /*
+ * We need to hold a reference for flushing the cluster buffer as it may
+@@ -773,7 +774,11 @@ xfs_inode_item_push(
+ rval = XFS_ITEM_LOCKED;
+ }
+
+- spin_lock(&lip->li_ailp->ail_lock);
++ /*
++ * The buffer no longer protects the log item from reclaim, so
++ * do not reference lip after this point.
++ */
++ spin_lock(&ailp->ail_lock);
+ return rval;
+ }
+