]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 Apr 2026 13:30:51 +0000 (15:30 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 Apr 2026 13:30:51 +0000 (15:30 +0200)
added patches:
bluetooth-eir-fix-possible-crashes-on-eir_create_adv_data.patch
erofs-fix-psi-memstall-accounting.patch
erofs-fix-the-slab-out-of-bounds-in-drop_buffers.patch
erofs-handle-overlapped-pclusters-out-of-crafted-images-properly.patch
gfs2-fix-unlikely-race-in-gdlm_put_lock.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
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
net-phy-move-phy_link_change-prior-to-mdio_bus_phy_may_suspend.patch
selftests-mptcp-join-check-removing-signal-subflow-endp.patch
selftests-mptcp-join-implicit-stop-transfer-after-last-check.patch
xfs-avoid-dereferencing-log-items-after-push-callbacks.patch
xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch

15 files changed:
queue-6.1/bluetooth-eir-fix-possible-crashes-on-eir_create_adv_data.patch [new file with mode: 0644]
queue-6.1/erofs-fix-psi-memstall-accounting.patch [new file with mode: 0644]
queue-6.1/erofs-fix-the-slab-out-of-bounds-in-drop_buffers.patch [new file with mode: 0644]
queue-6.1/erofs-handle-overlapped-pclusters-out-of-crafted-images-properly.patch [new file with mode: 0644]
queue-6.1/gfs2-fix-unlikely-race-in-gdlm_put_lock.patch [new file with mode: 0644]
queue-6.1/mtd-spi-nor-core-avoid-odd-length-address-reads-on-8d-8d-8d-mode.patch [new file with mode: 0644]
queue-6.1/mtd-spi-nor-core-avoid-odd-length-address-writes-in-8d-8d-8d-mode.patch [new file with mode: 0644]
queue-6.1/net-phy-allow-mdio-bus-pm-ops-to-start-stop-state-machine-for-phylink-controlled-phy.patch [new file with mode: 0644]
queue-6.1/net-phy-fix-phy_uses_state_machine.patch [new file with mode: 0644]
queue-6.1/net-phy-move-phy_link_change-prior-to-mdio_bus_phy_may_suspend.patch [new file with mode: 0644]
queue-6.1/selftests-mptcp-join-check-removing-signal-subflow-endp.patch [new file with mode: 0644]
queue-6.1/selftests-mptcp-join-implicit-stop-transfer-after-last-check.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/xfs-avoid-dereferencing-log-items-after-push-callbacks.patch [new file with mode: 0644]
queue-6.1/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch [new file with mode: 0644]

diff --git a/queue-6.1/bluetooth-eir-fix-possible-crashes-on-eir_create_adv_data.patch b/queue-6.1/bluetooth-eir-fix-possible-crashes-on-eir_create_adv_data.patch
new file mode 100644 (file)
index 0000000..7f5cd06
--- /dev/null
@@ -0,0 +1,90 @@
+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 &&
diff --git a/queue-6.1/erofs-fix-psi-memstall-accounting.patch b/queue-6.1/erofs-fix-psi-memstall-accounting.patch
new file mode 100644 (file)
index 0000000..af17801
--- /dev/null
@@ -0,0 +1,52 @@
+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.
diff --git a/queue-6.1/erofs-fix-the-slab-out-of-bounds-in-drop_buffers.patch b/queue-6.1/erofs-fix-the-slab-out-of-bounds-in-drop_buffers.patch
new file mode 100644 (file)
index 0000000..3531a9a
--- /dev/null
@@ -0,0 +1,55 @@
+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
diff --git a/queue-6.1/erofs-handle-overlapped-pclusters-out-of-crafted-images-properly.patch b/queue-6.1/erofs-handle-overlapped-pclusters-out-of-crafted-images-properly.patch
new file mode 100644 (file)
index 0000000..e83984c
--- /dev/null
@@ -0,0 +1,171 @@
+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;
diff --git a/queue-6.1/gfs2-fix-unlikely-race-in-gdlm_put_lock.patch b/queue-6.1/gfs2-fix-unlikely-race-in-gdlm_put_lock.patch
new file mode 100644 (file)
index 0000000..55e71d4
--- /dev/null
@@ -0,0 +1,53 @@
+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,
diff --git a/queue-6.1/mtd-spi-nor-core-avoid-odd-length-address-reads-on-8d-8d-8d-mode.patch b/queue-6.1/mtd-spi-nor-core-avoid-odd-length-address-reads-on-8d-8d-8d-mode.patch
new file mode 100644 (file)
index 0000000..976f981
--- /dev/null
@@ -0,0 +1,134 @@
+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;
diff --git a/queue-6.1/mtd-spi-nor-core-avoid-odd-length-address-writes-in-8d-8d-8d-mode.patch b/queue-6.1/mtd-spi-nor-core-avoid-odd-length-address-writes-in-8d-8d-8d-mode.patch
new file mode 100644 (file)
index 0000000..1bc8435
--- /dev/null
@@ -0,0 +1,118 @@
+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;
diff --git a/queue-6.1/net-phy-allow-mdio-bus-pm-ops-to-start-stop-state-machine-for-phylink-controlled-phy.patch b/queue-6.1/net-phy-allow-mdio-bus-pm-ops-to-start-stop-state-machine-for-phylink-controlled-phy.patch
new file mode 100644 (file)
index 0000000..66905c3
--- /dev/null
@@ -0,0 +1,161 @@
+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;
diff --git a/queue-6.1/net-phy-fix-phy_uses_state_machine.patch b/queue-6.1/net-phy-fix-phy_uses_state_machine.patch
new file mode 100644 (file)
index 0000000..af4f6c1
--- /dev/null
@@ -0,0 +1,80 @@
+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)
diff --git a/queue-6.1/net-phy-move-phy_link_change-prior-to-mdio_bus_phy_may_suspend.patch b/queue-6.1/net-phy-move-phy_link_change-prior-to-mdio_bus_phy_may_suspend.patch
new file mode 100644 (file)
index 0000000..e807fba
--- /dev/null
@@ -0,0 +1,75 @@
+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
diff --git a/queue-6.1/selftests-mptcp-join-check-removing-signal-subflow-endp.patch b/queue-6.1/selftests-mptcp-join-check-removing-signal-subflow-endp.patch
new file mode 100644 (file)
index 0000000..ef6904d
--- /dev/null
@@ -0,0 +1,65 @@
+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
diff --git a/queue-6.1/selftests-mptcp-join-implicit-stop-transfer-after-last-check.patch b/queue-6.1/selftests-mptcp-join-implicit-stop-transfer-after-last-check.patch
new file mode 100644 (file)
index 0000000..3a1f239
--- /dev/null
@@ -0,0 +1,85 @@
+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
index 7d958b960b8a935edb8f82745b542b840f88f645..75690a3383866aacf88ec96e9e477c49cbccbaa6 100644 (file)
@@ -292,3 +292,17 @@ mptcp-fix-lock-class-name-family-in-pm_nl_create_listen_socket.patch
 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
diff --git a/queue-6.1/xfs-avoid-dereferencing-log-items-after-push-callbacks.patch b/queue-6.1/xfs-avoid-dereferencing-log-items-after-push-callbacks.patch
new file mode 100644 (file)
index 0000000..50bea5f
--- /dev/null
@@ -0,0 +1,172 @@
+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;
diff --git a/queue-6.1/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch b/queue-6.1/xfs-save-ailp-before-dropping-the-ail-lock-in-push-callbacks.patch
new file mode 100644 (file)
index 0000000..b2f8569
--- /dev/null
@@ -0,0 +1,96 @@
+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;
+ }