--- /dev/null
+From ad2208a35a011c1eaa43f80a1e70e9ea0dc5799a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 15:13:38 +0300
+Subject: clk: imx: Add check for kcalloc
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+commit ed713e2bc093239ccd380c2ce8ae9e4162f5c037 upstream.
+
+As the potential failure of the kcalloc(),
+it should be better to check it in order to
+avoid the dereference of the NULL pointer.
+
+Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
+Link: https://lore.kernel.org/r/20220310080257.1988412-1-jiasheng@iscas.ac.cn
+Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
+Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
+index d4cf0c7045ab27..be0493e5b494e6 100644
+--- a/drivers/clk/imx/clk.c
++++ b/drivers/clk/imx/clk.c
+@@ -173,6 +173,8 @@ void imx_register_uart_clocks(unsigned int clk_count)
+ int i;
+
+ imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
++ if (!imx_uart_clocks)
++ return;
+
+ if (!of_stdout)
+ return;
+--
+2.53.0
+
--- /dev/null
+From 122574ca65b1fdbcf6cc08385e970fb6e6114496 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 23:39:54 -0400
+Subject: nfsd: release layout stid on setlease failure
+
+From: Chris Mason <clm@meta.com>
+
+commit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream.
+
+nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via
+idr_alloc_cyclic() under cl_lock before returning to
+nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then
+fails, the error path frees the layout stateid directly with
+kmem_cache_free() without ever calling idr_remove(), leaving the
+IDR slot pointing at freed slab memory. Any subsequent IDR walker
+(states_show, client teardown) dereferences the dangling pointer.
+
+The correct teardown for an IDR-published stid is nfs4_put_stid(),
+which removes the IDR slot under cl_lock, dispatches sc_free
+(nfsd4_free_layout_stateid) to release ls->ls_file via
+nfsd4_close_layout(), and drops the nfs4_file reference in its
+tail.
+
+A second issue blocks that switch: nfsd4_free_layout_stateid()
+unconditionally inspects ls->ls_fence_work via
+delayed_work_pending() under ls_lock, but
+INIT_DELAYED_WORK(&ls->ls_fence_work, ...) currently runs only
+after the setlease call. On the setlease-failure path the
+destructor would touch an uninitialized delayed_work.
+
+ nfsd4_alloc_layout_stateid()
+ nfs4_alloc_stid() /* idr_alloc_cyclic under cl_lock */
+ nfsd4_layout_setlease() /* fails */
+ nfs4_put_stid()
+ nfsd4_free_layout_stateid()
+ delayed_work_pending(&ls->ls_fence_work) /* needs INIT */
+ nfsd4_close_layout() /* nfsd_file_put(ls->ls_file) */
+ put_nfs4_file()
+
+Fix by hoisting the ls_fenced / ls_fence_delay / INIT_DELAYED_WORK
+initialization above the nfsd4_layout_setlease() call, and replace
+the manual nfsd_file_put + put_nfs4_file + kmem_cache_free cleanup
+with a single nfs4_put_stid(stp).
+
+Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
+Cc: stable@vger.kernel.org
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: no ls_fence_work in 5.10.y; dropped INIT_DELAYED_WORK hunk ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4layouts.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
+index d0fbbd34db689c..bcf16dd07d4883 100644
+--- a/fs/nfsd/nfs4layouts.c
++++ b/fs/nfsd/nfs4layouts.c
+@@ -241,9 +241,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
+ BUG_ON(!ls->ls_file);
+
+ if (nfsd4_layout_setlease(ls)) {
+- nfsd_file_put(ls->ls_file);
+- put_nfs4_file(fp);
+- kmem_cache_free(nfs4_layout_stateid_cache, ls);
++ nfs4_put_stid(stp);
+ return NULL;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From e2150551b46f9c37bef29685380d8e35a6dba1e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 23:40:48 -0400
+Subject: nfsd: reset write verifier on deferred writeback errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit 2090b05803faab8a9fa62fbff871007862cac1b7 upstream.
+
+nfsd_vfs_write() and nfsd_commit() both call filemap_check_wb_err() to
+detect deferred writeback errors, but neither rotates the server's write
+verifier (nn->writeverf) when this check fails. Every other
+durable-storage-failure path in these functions calls
+commit_reset_write_verifier() before returning an error.
+
+The missing rotation means clients holding UNSTABLE write data under the
+current verifier will COMMIT, receive the unchanged verifier back, and
+conclude their data is durable — silently dropping data that failed
+writeback. This violates the UNSTABLE+COMMIT durability contract
+(RFC 1813 §3.3.7, RFC 8881 §18.32).
+
+Add commit_reset_write_verifier() calls at both filemap_check_wb_err()
+error sites, matching the pattern used by adjacent error paths in the
+same functions. The helper already filters -EAGAIN and -ESTALE
+internally, so the calls are unconditionally safe.
+
+Reported-by: Chris Mason <clm@meta.com>
+Fixes: 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t")
+Cc: stable@vger.kernel.org
+Assisted-by: kres:claude-opus-4-6
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: open-code the reset; commit_reset_write_verifier() is v6.7 ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/vfs.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index 19468142486671..c8eebd03784a21 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -1149,8 +1149,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
+ nfsd_stats_io_write_add(nn, exp, *cnt);
+ fsnotify_modify(file);
+ host_err = filemap_check_wb_err(file->f_mapping, since);
+- if (host_err < 0)
++ if (host_err < 0) {
++ nfsd_reset_write_verifier(nn);
++ trace_nfsd_writeverf_reset(nn, rqstp, host_err);
+ goto out_nfserr;
++ }
+
+ if (stable && use_wgather) {
+ host_err = wait_for_concurrent_writes(file);
+@@ -1286,6 +1289,10 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
+ nfsd_copy_write_verifier(verf, nn);
+ err2 = filemap_check_wb_err(nf->nf_file->f_mapping,
+ since);
++ if (err2 < 0) {
++ nfsd_reset_write_verifier(nn);
++ trace_nfsd_writeverf_reset(nn, rqstp, err2);
++ }
+ err = nfserrno(err2);
+ break;
+ case -EINVAL:
+--
+2.53.0
+
nvmet-tcp-fix-race-between-icreq-handling-and-queue-.patch
+nfsd-release-layout-stid-on-setlease-failure.patch
+nfsd-reset-write-verifier-on-deferred-writeback-erro.patch
+userfaultfd-gate-must_wait-writability-check-on-pte_.patch
+clk-imx-add-check-for-kcalloc.patch
--- /dev/null
+From 0238b29475513ccd662ba52895b839e4ecff68d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:48:59 +0100
+Subject: userfaultfd: gate must_wait writability check on pte_present()
+
+From: Kiryl Shutsemau <kas@kernel.org>
+
+[ Upstream commit 8e80af52db652fbc41320eee45a4f73bc029faf2 ]
+
+userfaultfd_must_wait() and userfaultfd_huge_must_wait() read the PTE
+without taking the page table lock and then apply pte_write() /
+huge_pte_write() to it. Those accessors decode bits from the present
+encoding only; on a swap or migration entry they read the offset bits that
+happen to share the same position and return an undefined result.
+
+The intent of the check is "is this fault still WP-blocked?". A
+non-marker swap entry means the page is in transit -- the userfault
+context the original fault delivered against is no longer the same, and
+the swap-in or migration completion path will re-deliver a fresh fault if
+userspace still needs to handle it. Worst case under the current code the
+garbage write bit says "wait", and the thread stays asleep until a
+UFFDIO_WAKE that may never arrive.
+
+Gate the writability check on pte_present() so the lockless re-check only
+inspects present-PTE bits when the entry is actually present. The
+non-present, non-marker case returns "don't wait" and lets the fault path
+retry.
+
+Link: https://lore.kernel.org/20260529172331.356655-6-kas@kernel.org
+Fixes: 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges")
+Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+
+[ kas: apply to fs/userfaultfd.c and fold the pte_present()/
+ huge_pte_present() gate into the existing writability checks; this tree
+ predates the marker/return-style refactor of these functions ]
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/userfaultfd.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index 0d6c00e9b49316..6773227fbe889e 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -251,7 +251,12 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
+ */
+ if (huge_pte_none(pte))
+ ret = true;
+- if (!huge_pte_write(pte) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): huge_pte_write() on a
++ * non-present migration entry decodes random offset bits. The
++ * migration completion path re-delivers the fault if still needed.
++ */
++ if (pte_present(pte) && !huge_pte_write(pte) && (reason & VM_UFFD_WP))
+ ret = true;
+ out:
+ return ret;
+@@ -332,7 +337,12 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
+ */
+ if (pte_none(*pte))
+ ret = true;
+- if (!pte_write(*pte) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): pte_write() on a
++ * non-present swap/migration entry decodes random offset bits. The
++ * page-in path re-delivers the fault if it still needs userspace.
++ */
++ if (pte_present(*pte) && !pte_write(*pte) && (reason & VM_UFFD_WP))
+ ret = true;
+ pte_unmap(pte);
+
+--
+2.53.0
+
--- /dev/null
+From d222ad955ddcccfb80986e8d247cfa7bc20e3553 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 15:13:38 +0300
+Subject: clk: imx: Add check for kcalloc
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+commit ed713e2bc093239ccd380c2ce8ae9e4162f5c037 upstream.
+
+As the potential failure of the kcalloc(),
+it should be better to check it in order to
+avoid the dereference of the NULL pointer.
+
+Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Reviewed-by: Abel Vesa <abel.vesa@nxp.com>
+Link: https://lore.kernel.org/r/20220310080257.1988412-1-jiasheng@iscas.ac.cn
+Signed-off-by: Abel Vesa <abel.vesa@nxp.com>
+Signed-off-by: Alexandra Diupina <adiupina@astralinux.ru>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/imx/clk.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
+index d4cf0c7045ab27..be0493e5b494e6 100644
+--- a/drivers/clk/imx/clk.c
++++ b/drivers/clk/imx/clk.c
+@@ -173,6 +173,8 @@ void imx_register_uart_clocks(unsigned int clk_count)
+ int i;
+
+ imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
++ if (!imx_uart_clocks)
++ return;
+
+ if (!of_stdout)
+ return;
+--
+2.53.0
+
--- /dev/null
+From 75f355d4d6cc11f927ba7294db5d5a21f7c68b70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 20:25:22 +0100
+Subject: nfc: llcp: protect nfc_llcp_sock_unlink() calls
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+
+[ Upstream commit a06b8044169f6d5c3eb34772c13d2c0c1b205352 ]
+
+nfc_llcp_sock_link() is called in all paths (bind/connect) as a last
+action, still protected with lock_sock(). When cleaning up in
+llcp_sock_release(), call nfc_llcp_sock_unlink() in a mirrored way:
+earlier and still under the lock_sock().
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/llcp_sock.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
+index 54af85d939c6b9..57dea580c02912 100644
+--- a/net/nfc/llcp_sock.c
++++ b/net/nfc/llcp_sock.c
+@@ -626,6 +626,13 @@ static int llcp_sock_release(struct socket *sock)
+ }
+ }
+
++ if (sock->type == SOCK_RAW)
++ nfc_llcp_sock_unlink(&local->raw_sockets, sk);
++ else if (sk->sk_state == LLCP_CONNECTING)
++ nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
++ else
++ nfc_llcp_sock_unlink(&local->sockets, sk);
++
+ if (llcp_sock->reserved_ssap < LLCP_SAP_MAX)
+ nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap);
+
+@@ -638,13 +645,6 @@ static int llcp_sock_release(struct socket *sock)
+ if (sk->sk_state == LLCP_DISCONNECTING)
+ return err;
+
+- if (sock->type == SOCK_RAW)
+- nfc_llcp_sock_unlink(&local->raw_sockets, sk);
+- else if (sk->sk_state == LLCP_CONNECTING)
+- nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+- else
+- nfc_llcp_sock_unlink(&local->sockets, sk);
+-
+ out:
+ sock_orphan(sk);
+ sock_put(sk);
+--
+2.53.0
+
--- /dev/null
+From 01729f0bdb4c64bb22ea8a36287859b05258fa57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 23:38:15 -0400
+Subject: nfsd: release layout stid on setlease failure
+
+From: Chris Mason <clm@meta.com>
+
+commit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream.
+
+nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via
+idr_alloc_cyclic() under cl_lock before returning to
+nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then
+fails, the error path frees the layout stateid directly with
+kmem_cache_free() without ever calling idr_remove(), leaving the
+IDR slot pointing at freed slab memory. Any subsequent IDR walker
+(states_show, client teardown) dereferences the dangling pointer.
+
+The correct teardown for an IDR-published stid is nfs4_put_stid(),
+which removes the IDR slot under cl_lock, dispatches sc_free
+(nfsd4_free_layout_stateid) to release ls->ls_file via
+nfsd4_close_layout(), and drops the nfs4_file reference in its
+tail.
+
+A second issue blocks that switch: nfsd4_free_layout_stateid()
+unconditionally inspects ls->ls_fence_work via
+delayed_work_pending() under ls_lock, but
+INIT_DELAYED_WORK(&ls->ls_fence_work, ...) currently runs only
+after the setlease call. On the setlease-failure path the
+destructor would touch an uninitialized delayed_work.
+
+ nfsd4_alloc_layout_stateid()
+ nfs4_alloc_stid() /* idr_alloc_cyclic under cl_lock */
+ nfsd4_layout_setlease() /* fails */
+ nfs4_put_stid()
+ nfsd4_free_layout_stateid()
+ delayed_work_pending(&ls->ls_fence_work) /* needs INIT */
+ nfsd4_close_layout() /* nfsd_file_put(ls->ls_file) */
+ put_nfs4_file()
+
+Fix by hoisting the ls_fenced / ls_fence_delay / INIT_DELAYED_WORK
+initialization above the nfsd4_layout_setlease() call, and replace
+the manual nfsd_file_put + put_nfs4_file + kmem_cache_free cleanup
+with a single nfs4_put_stid(stp).
+
+Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
+Cc: stable@vger.kernel.org
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: no ls_fence_work in 5.15.y; dropped INIT_DELAYED_WORK hunk ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4layouts.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
+index d0fbbd34db689c..bcf16dd07d4883 100644
+--- a/fs/nfsd/nfs4layouts.c
++++ b/fs/nfsd/nfs4layouts.c
+@@ -241,9 +241,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
+ BUG_ON(!ls->ls_file);
+
+ if (nfsd4_layout_setlease(ls)) {
+- nfsd_file_put(ls->ls_file);
+- put_nfs4_file(fp);
+- kmem_cache_free(nfs4_layout_stateid_cache, ls);
++ nfs4_put_stid(stp);
+ return NULL;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From f299c908152878a01db1687ae9b7f6974f1d779b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 23:37:05 -0400
+Subject: nfsd: reset write verifier on deferred writeback errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit 2090b05803faab8a9fa62fbff871007862cac1b7 upstream.
+
+nfsd_vfs_write() and nfsd_commit() both call filemap_check_wb_err() to
+detect deferred writeback errors, but neither rotates the server's write
+verifier (nn->writeverf) when this check fails. Every other
+durable-storage-failure path in these functions calls
+commit_reset_write_verifier() before returning an error.
+
+The missing rotation means clients holding UNSTABLE write data under the
+current verifier will COMMIT, receive the unchanged verifier back, and
+conclude their data is durable — silently dropping data that failed
+writeback. This violates the UNSTABLE+COMMIT durability contract
+(RFC 1813 §3.3.7, RFC 8881 §18.32).
+
+Add commit_reset_write_verifier() calls at both filemap_check_wb_err()
+error sites, matching the pattern used by adjacent error paths in the
+same functions. The helper already filters -EAGAIN and -ESTALE
+internally, so the calls are unconditionally safe.
+
+Reported-by: Chris Mason <clm@meta.com>
+Fixes: 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t")
+Cc: stable@vger.kernel.org
+Assisted-by: kres:claude-opus-4-6
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: open-code the reset; commit_reset_write_verifier() is v6.7 ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/vfs.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index e1737984e0ca11..7b0bc4507ad047 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -1133,8 +1133,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
+ nfsd_stats_io_write_add(nn, exp, *cnt);
+ fsnotify_modify(file);
+ host_err = filemap_check_wb_err(file->f_mapping, since);
+- if (host_err < 0)
++ if (host_err < 0) {
++ nfsd_reset_write_verifier(nn);
++ trace_nfsd_writeverf_reset(nn, rqstp, host_err);
+ goto out_nfserr;
++ }
+
+ if (stable && use_wgather) {
+ host_err = wait_for_concurrent_writes(file);
+@@ -1270,6 +1273,10 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
+ nfsd_copy_write_verifier(verf, nn);
+ err2 = filemap_check_wb_err(nf->nf_file->f_mapping,
+ since);
++ if (err2 < 0) {
++ nfsd_reset_write_verifier(nn);
++ trace_nfsd_writeverf_reset(nn, rqstp, err2);
++ }
+ err = nfserrno(err2);
+ break;
+ case -EINVAL:
+--
+2.53.0
+
nvmet-tcp-fix-race-between-icreq-handling-and-queue-.patch
+nfc-llcp-protect-nfc_llcp_sock_unlink-calls.patch
+nfsd-release-layout-stid-on-setlease-failure.patch
+nfsd-reset-write-verifier-on-deferred-writeback-erro.patch
+userfaultfd-gate-must_wait-writability-check-on-pte_.patch
+clk-imx-add-check-for-kcalloc.patch
--- /dev/null
+From 6818363111ac85da61e796958bab5d953ad04d96 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:49:00 +0100
+Subject: userfaultfd: gate must_wait writability check on pte_present()
+
+From: Kiryl Shutsemau <kas@kernel.org>
+
+[ Upstream commit 8e80af52db652fbc41320eee45a4f73bc029faf2 ]
+
+userfaultfd_must_wait() and userfaultfd_huge_must_wait() read the PTE
+without taking the page table lock and then apply pte_write() /
+huge_pte_write() to it. Those accessors decode bits from the present
+encoding only; on a swap or migration entry they read the offset bits that
+happen to share the same position and return an undefined result.
+
+The intent of the check is "is this fault still WP-blocked?". A
+non-marker swap entry means the page is in transit -- the userfault
+context the original fault delivered against is no longer the same, and
+the swap-in or migration completion path will re-deliver a fresh fault if
+userspace still needs to handle it. Worst case under the current code the
+garbage write bit says "wait", and the thread stays asleep until a
+UFFDIO_WAKE that may never arrive.
+
+Gate the writability check on pte_present() so the lockless re-check only
+inspects present-PTE bits when the entry is actually present. The
+non-present, non-marker case returns "don't wait" and lets the fault path
+retry.
+
+Link: https://lore.kernel.org/20260529172331.356655-6-kas@kernel.org
+Fixes: 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges")
+Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+
+[ kas: apply to fs/userfaultfd.c and fold the pte_present()/
+ huge_pte_present() gate into the existing writability checks; this tree
+ predates the marker/return-style refactor of these functions ]
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/userfaultfd.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index 868405f3cfa0c4..271ce399f6b6fd 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -249,7 +249,12 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
+ */
+ if (huge_pte_none(pte))
+ ret = true;
+- if (!huge_pte_write(pte) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): huge_pte_write() on a
++ * non-present migration entry decodes random offset bits. The
++ * migration completion path re-delivers the fault if still needed.
++ */
++ if (pte_present(pte) && !huge_pte_write(pte) && (reason & VM_UFFD_WP))
+ ret = true;
+ out:
+ return ret;
+@@ -330,7 +335,12 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
+ */
+ if (pte_none(*pte))
+ ret = true;
+- if (!pte_write(*pte) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): pte_write() on a
++ * non-present swap/migration entry decodes random offset bits. The
++ * page-in path re-delivers the fault if it still needs userspace.
++ */
++ if (pte_present(*pte) && !pte_write(*pte) && (reason & VM_UFFD_WP))
+ ret = true;
+ pte_unmap(pte);
+
+--
+2.53.0
+
--- /dev/null
+From 95196fa5ddb921ba5e98e461cb508beb95e1e305 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 11:24:00 +0800
+Subject: LoongArch: Report dying CPU to RCU in stop_this_cpu()
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+commit f2539c56c74691e7a88af6372ba2b48c06ed2fe4 upstream.
+
+This is a port of MIPS commit 9f3f3bdc6d9dac1 ("MIPS: smp: report dying
+CPU to RCU in stop_this_cpu()"). smp_send_stop() parks all secondary
+CPUs in stop_this_cpu(). And the function marks the CPU offline for the
+scheduler via set_cpu_online(false) but never informs RCU, so RCU keeps
+expecting a quiescent state from CPUs that are now spinning forever with
+interrupts disabled.
+
+As long as nothing waits for an RCU grace period after smp_send_stop()
+this is harmless, which is why it went unnoticed. However, since commit
+91840be8f710370 ("irq_work: Fix use-after-free in irq_work_single() on
+PREEMPT_RT"), irq_work_sync() calls synchronize_rcu() on architectures
+without an irq_work self-IPI, i.e. where arch_irq_work_has_interrupt()
+returns false. Any irq_work_sync() issued in the reboot/shutdown/halt
+path after smp_send_stop() then blocks on a grace period that can never
+complete, hanging the reboot:
+
+ WARNING: CPU: 0 PID: 15 at kernel/irq_work.c:144 irq_work_queue_on
+ ...
+ rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
+ rcu: Offline CPU 1 blocking current GP.
+ rcu: Offline CPU 2 blocking current GP.
+ rcu: Offline CPU 3 blocking current GP.
+
+This issue needs some hacks to reproduce, and it was not noticed on
+LoongArch because arch_irq_work_has_interrupt() usually returns true.
+
+Call rcutree_report_cpu_dead() once interrupts are disabled, mirroring
+the generic CPU-hotplug offline path, so RCU stops waiting on the parked
+CPUs and grace periods can still complete. LoongArch shuts down all CPUs
+here without going through the CPU-hotplug mechanism, so this report is
+not otherwise issued.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 91840be8f710 ("irq_work: Fix use-after-free in irq_work_single() on PREEMPT_RT")
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/kernel/smp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
+index 18a2b37f4aea37..356918d5aa28f1 100644
+--- a/arch/loongarch/kernel/smp.c
++++ b/arch/loongarch/kernel/smp.c
+@@ -517,6 +517,7 @@ static void stop_this_cpu(void *dummy)
+ set_cpu_online(smp_processor_id(), false);
+ calculate_cpu_foreign_map();
+ local_irq_disable();
++ rcu_report_dead(smp_processor_id());
+ while (true);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From c621b5be1c3140f4f9eddc00beb50fb10b1ff6f8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 23:32:42 -0400
+Subject: nfsd: release layout stid on setlease failure
+
+From: Chris Mason <clm@meta.com>
+
+commit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream.
+
+nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via
+idr_alloc_cyclic() under cl_lock before returning to
+nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then
+fails, the error path frees the layout stateid directly with
+kmem_cache_free() without ever calling idr_remove(), leaving the
+IDR slot pointing at freed slab memory. Any subsequent IDR walker
+(states_show, client teardown) dereferences the dangling pointer.
+
+The correct teardown for an IDR-published stid is nfs4_put_stid(),
+which removes the IDR slot under cl_lock, dispatches sc_free
+(nfsd4_free_layout_stateid) to release ls->ls_file via
+nfsd4_close_layout(), and drops the nfs4_file reference in its
+tail.
+
+A second issue blocks that switch: nfsd4_free_layout_stateid()
+unconditionally inspects ls->ls_fence_work via
+delayed_work_pending() under ls_lock, but
+INIT_DELAYED_WORK(&ls->ls_fence_work, ...) currently runs only
+after the setlease call. On the setlease-failure path the
+destructor would touch an uninitialized delayed_work.
+
+ nfsd4_alloc_layout_stateid()
+ nfs4_alloc_stid() /* idr_alloc_cyclic under cl_lock */
+ nfsd4_layout_setlease() /* fails */
+ nfs4_put_stid()
+ nfsd4_free_layout_stateid()
+ delayed_work_pending(&ls->ls_fence_work) /* needs INIT */
+ nfsd4_close_layout() /* nfsd_file_put(ls->ls_file) */
+ put_nfs4_file()
+
+Fix by hoisting the ls_fenced / ls_fence_delay / INIT_DELAYED_WORK
+initialization above the nfsd4_layout_setlease() call, and replace
+the manual nfsd_file_put + put_nfs4_file + kmem_cache_free cleanup
+with a single nfs4_put_stid(stp).
+
+Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
+Cc: stable@vger.kernel.org
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: no ls_fence_work in 6.1.y; dropped INIT_DELAYED_WORK hunk ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4layouts.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
+index 308214378fd352..84bb200e24adea 100644
+--- a/fs/nfsd/nfs4layouts.c
++++ b/fs/nfsd/nfs4layouts.c
+@@ -242,9 +242,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
+ BUG_ON(!ls->ls_file);
+
+ if (nfsd4_layout_setlease(ls)) {
+- nfsd_file_put(ls->ls_file);
+- put_nfs4_file(fp);
+- kmem_cache_free(nfs4_layout_stateid_cache, ls);
++ nfs4_put_stid(stp);
+ return NULL;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From e389b2a9d556c5a60f483c1ffc2fa09e9f43e9ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 23:32:43 -0400
+Subject: nfsd: reset write verifier on deferred writeback errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit 2090b05803faab8a9fa62fbff871007862cac1b7 upstream.
+
+nfsd_vfs_write() and nfsd_commit() both call filemap_check_wb_err() to
+detect deferred writeback errors, but neither rotates the server's write
+verifier (nn->writeverf) when this check fails. Every other
+durable-storage-failure path in these functions calls
+commit_reset_write_verifier() before returning an error.
+
+The missing rotation means clients holding UNSTABLE write data under the
+current verifier will COMMIT, receive the unchanged verifier back, and
+conclude their data is durable — silently dropping data that failed
+writeback. This violates the UNSTABLE+COMMIT durability contract
+(RFC 1813 §3.3.7, RFC 8881 §18.32).
+
+Add commit_reset_write_verifier() calls at both filemap_check_wb_err()
+error sites, matching the pattern used by adjacent error paths in the
+same functions. The helper already filters -EAGAIN and -ESTALE
+internally, so the calls are unconditionally safe.
+
+Reported-by: Chris Mason <clm@meta.com>
+Fixes: 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t")
+Cc: stable@vger.kernel.org
+Assisted-by: kres:claude-opus-4-6
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: open-code the reset; commit_reset_write_verifier() is v6.7 ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/vfs.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index 87a596fc6654dd..c40b2a706691c5 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -1134,8 +1134,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
+ nfsd_stats_io_write_add(nn, exp, *cnt);
+ fsnotify_modify(file);
+ host_err = filemap_check_wb_err(file->f_mapping, since);
+- if (host_err < 0)
++ if (host_err < 0) {
++ nfsd_reset_write_verifier(nn);
++ trace_nfsd_writeverf_reset(nn, rqstp, host_err);
+ goto out_nfserr;
++ }
+
+ if (stable && use_wgather) {
+ host_err = wait_for_concurrent_writes(file);
+@@ -1271,6 +1274,10 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
+ nfsd_copy_write_verifier(verf, nn);
+ err2 = filemap_check_wb_err(nf->nf_file->f_mapping,
+ since);
++ if (err2 < 0) {
++ nfsd_reset_write_verifier(nn);
++ trace_nfsd_writeverf_reset(nn, rqstp, err2);
++ }
+ err = nfserrno(err2);
+ break;
+ case -EINVAL:
+--
+2.53.0
+
nvmet-tcp-fix-race-between-icreq-handling-and-queue-.patch
bpf-arm64-reject-out-of-range-b.cond-targets.patch
+nfsd-release-layout-stid-on-setlease-failure.patch
+nfsd-reset-write-verifier-on-deferred-writeback-erro.patch
+loongarch-report-dying-cpu-to-rcu-in-stop_this_cpu.patch
+userfaultfd-gate-must_wait-writability-check-on-pte_.patch
--- /dev/null
+From f72740d8aa7b34d3c54f08ffe217fe59ca94e55f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:49:02 +0100
+Subject: userfaultfd: gate must_wait writability check on pte_present()
+
+From: Kiryl Shutsemau <kas@kernel.org>
+
+[ Upstream commit 8e80af52db652fbc41320eee45a4f73bc029faf2 ]
+
+userfaultfd_must_wait() and userfaultfd_huge_must_wait() read the PTE
+without taking the page table lock and then apply pte_write() /
+huge_pte_write() to it. Those accessors decode bits from the present
+encoding only; on a swap or migration entry they read the offset bits that
+happen to share the same position and return an undefined result.
+
+The intent of the check is "is this fault still WP-blocked?". A
+non-marker swap entry means the page is in transit -- the userfault
+context the original fault delivered against is no longer the same, and
+the swap-in or migration completion path will re-deliver a fresh fault if
+userspace still needs to handle it. Worst case under the current code the
+garbage write bit says "wait", and the thread stays asleep until a
+UFFDIO_WAKE that may never arrive.
+
+Gate the writability check on pte_present() so the lockless re-check only
+inspects present-PTE bits when the entry is actually present. The
+non-present, non-marker case returns "don't wait" and lets the fault path
+retry.
+
+Link: https://lore.kernel.org/20260529172331.356655-6-kas@kernel.org
+Fixes: 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges")
+Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+
+[ kas: apply to fs/userfaultfd.c and fold the pte_present()/
+ huge_pte_present() gate into the existing writability checks; this tree
+ predates the marker/return-style refactor of these functions ]
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/userfaultfd.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index 7f8b397597b0d1..6ebee2b3a5a83e 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -273,7 +273,12 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
+ */
+ if (huge_pte_none_mostly(pte))
+ ret = true;
+- if (!huge_pte_write(pte) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): huge_pte_write() on a
++ * non-present migration entry decodes random offset bits. The
++ * migration completion path re-delivers the fault if still needed.
++ */
++ if (pte_present(pte) && !huge_pte_write(pte) && (reason & VM_UFFD_WP))
+ ret = true;
+ out:
+ return ret;
+@@ -355,7 +360,12 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
+ */
+ if (pte_none_mostly(*pte))
+ ret = true;
+- if (!pte_write(*pte) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): pte_write() on a
++ * non-present swap/migration entry decodes random offset bits. The
++ * page-in path re-delivers the fault if it still needs userspace.
++ */
++ if (pte_present(*pte) && !pte_write(*pte) && (reason & VM_UFFD_WP))
+ ret = true;
+ pte_unmap(pte);
+
+--
+2.53.0
+
--- /dev/null
+From 753a6b0ee88ec528751193273d6f92bc00431cf6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Jun 2026 07:15:17 -0700
+Subject: kernel/fork: clear PF_BLOCK_TS in copy_process()
+
+From: Usama Arif <usama.arif@linux.dev>
+
+[ Upstream commit fd38b75c4b43295b10d69772a46d1c74dbd6fc81 ]
+
+PF_BLOCK_TS is only set in blk_time_get_ns() when current->plug is
+non-NULL, and blk_finish_plug() clears it via __blk_flush_plug()
+before NULLing the plug pointer. copy_process() breaks the
+invariant by inheriting PF_BLOCK_TS from the parent while resetting
+the child's plug to NULL.
+
+Clear PF_BLOCK_TS alongside that assignment so callers can rely on
+"PF_BLOCK_TS set implies current->plug != NULL" and dereference
+current->plug unguarded.
+
+Fixes: 06b23f92af87 ("block: update cached timestamp post schedule/preemption")
+Cc: stable@vger.kernel.org
+Signed-off-by: Usama Arif <usama.arif@linux.dev>
+Link: https://patch.msgid.link/20260616141604.328820-2-usama.arif@linux.dev
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fork.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index c4955cffcb6f4e..c81b45509e8ab1 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2450,6 +2450,7 @@ __latent_entropy struct task_struct *copy_process(
+
+ #ifdef CONFIG_BLOCK
+ p->plug = NULL;
++ p->flags &= ~PF_BLOCK_TS;
+ #endif
+ futex_init_task(p);
+
+--
+2.53.0
+
--- /dev/null
+From 08a5b7cba8363c749ec96f7d3b4ed3b39635385d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:27:48 -0400
+Subject: nfsd: fix file change detection in CB_GETATTR
+
+From: Scott Mayhew <smayhew@redhat.com>
+
+commit 304d81a2fbf2b454def4debcb38ea173911b72cd upstream.
+
+RFC 8881, section 10.4.3 doesn't say anything about caching the file
+size in the delegation record, nor does it say anything about comparing
+a cached file size with the size reported by the client in the
+CB_GETATTR reply for the purpose of determining if the client holds
+modified data for the file.
+
+What section 10.4.3 of RFC 8881 does say is that the server should
+compare the *current* file size with the size reported by the client
+holding the delegation in the CB_GETATTR reply, and if they differ to
+treat it as a modification regardless of the change attribute retrieved
+via the CB_GETATTR.
+
+Doing otherwise would cause the server to believe the client holding the
+delegation has a modified version of the file, even if the client
+flushed the modifications to the server prior to the CB_GETATTR. This
+would have the added side effect of subsequent CB_GETATTRs causing
+updates to the mtime, ctime, and change attribute even if the client
+holding the delegation makes no further updates to the file.
+
+Modify nfsd4_deleg_getattr_conflict() to obtain the current file size
+via i_size_read(). Retain the ncf_cur_fsize field, since it's a
+convenient way to return the file size back to nfsd4_encode_fattr4(),
+but don't use it for the purpose of detecting file changes. Remove the
+unnecessary initialization of ncf_cur_fsize in nfs4_open_delegation().
+
+Also, if we recall the delegation (because the client didn't respond to
+the CB_GETATTR), then skip the logic that checks the nfs4_cb_fattr
+fields.
+
+Fixes: c5967721e106 ("NFSD: handle GETATTR conflict with write delegation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Scott Mayhew <smayhew@redhat.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: no deleg_ts in 6.12.y; dropped the now-dead ncf_cur_fsize init ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4state.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index 1ce66acc9b6ba0..e18d70adcdb903 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -6086,7 +6086,6 @@ nfs4_open_delegation(struct nfsd4_open *open, struct nfs4_ol_stateid *stp,
+ goto out_no_deleg;
+ }
+ open->op_delegate_type = NFS4_OPEN_DELEGATE_WRITE;
+- dp->dl_cb_fattr.ncf_cur_fsize = stat.size;
+ dp->dl_cb_fattr.ncf_initial_cinfo = nfsd4_change_attribute(&stat);
+ trace_nfsd_deleg_write(&dp->dl_stid.sc_stateid);
+ } else {
+@@ -9040,11 +9039,15 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
+ if (status != nfserr_jukebox ||
+ !nfsd_wait_for_delegreturn(rqstp, inode))
+ goto out_status;
++ status = nfs_ok;
++ goto out_status;
++ }
++ if (!ncf->ncf_file_modified) {
++ if (ncf->ncf_initial_cinfo != ncf->ncf_cb_change)
++ ncf->ncf_file_modified = true;
++ else if (i_size_read(inode) != ncf->ncf_cb_fsize)
++ ncf->ncf_file_modified = true;
+ }
+- if (!ncf->ncf_file_modified &&
+- (ncf->ncf_initial_cinfo != ncf->ncf_cb_change ||
+- ncf->ncf_cur_fsize != ncf->ncf_cb_fsize))
+- ncf->ncf_file_modified = true;
+ if (ncf->ncf_file_modified) {
+ int err;
+
+--
+2.53.0
+
--- /dev/null
+From 6479dc14c89ee830e35d6f8157b5ac5fc2583c19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:27:49 -0400
+Subject: nfsd: release layout stid on setlease failure
+
+From: Chris Mason <clm@meta.com>
+
+commit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream.
+
+nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via
+idr_alloc_cyclic() under cl_lock before returning to
+nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then
+fails, the error path frees the layout stateid directly with
+kmem_cache_free() without ever calling idr_remove(), leaving the
+IDR slot pointing at freed slab memory. Any subsequent IDR walker
+(states_show, client teardown) dereferences the dangling pointer.
+
+The correct teardown for an IDR-published stid is nfs4_put_stid(),
+which removes the IDR slot under cl_lock, dispatches sc_free
+(nfsd4_free_layout_stateid) to release ls->ls_file via
+nfsd4_close_layout(), and drops the nfs4_file reference in its
+tail.
+
+Replace the manual nfsd_file_put + put_nfs4_file + kmem_cache_free
+cleanup with a single nfs4_put_stid(stp).
+
+Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
+Cc: stable@vger.kernel.org
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Chuck Lever <cel@kernel.org>
+[ cel: no ls_fence_work in 6.12.y; dropped INIT_DELAYED_WORK hunk ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4layouts.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
+index fc5e82eddaa1af..c08bc2d0d37796 100644
+--- a/fs/nfsd/nfs4layouts.c
++++ b/fs/nfsd/nfs4layouts.c
+@@ -256,9 +256,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
+ BUG_ON(!ls->ls_file);
+
+ if (nfsd4_layout_setlease(ls)) {
+- nfsd_file_put(ls->ls_file);
+- put_nfs4_file(fp);
+- kmem_cache_free(nfs4_layout_stateid_cache, ls);
++ nfs4_put_stid(stp);
+ return NULL;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From cbc9ac710af188b0ccafec80f422c7385da4ead7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 00:48:25 +0800
+Subject: perf: Fix dangling cgroup pointer in cpuctx backport
+
+From: Wentao Guan <guanwentao@uniontech.com>
+
+recently backport of ("perf: Fix dangling cgroup pointer in cpuctx")
+use a middle version, so aligned with the upstream commit:
+commit 3b7a34aebbdf ("perf: Fix dangling cgroup pointer in cpuctx")
+
+This is a fix for stable v6.12.94 backport commit, so no upstream commit.
+
+Link: https://lore.kernel.org/all/2026070200-uneaten-smock-4130@gregkh/
+Fixes: 46f5623f9b0e ("perf: Fix dangling cgroup pointer in cpuctx")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 9099c0cc933be2..8fa3ee209a5be6 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -2440,10 +2440,9 @@ __perf_remove_from_context(struct perf_event *event,
+ */
+ if (flags & DETACH_EXIT)
+ state = PERF_EVENT_STATE_EXIT;
+- if (flags & DETACH_DEAD) {
+- event->pending_disable = 1;
++ if (flags & DETACH_DEAD)
+ state = PERF_EVENT_STATE_DEAD;
+- }
++
+ event_sched_out(event, ctx);
+
+ if (event->state > PERF_EVENT_STATE_OFF)
+--
+2.53.0
+
bpf-arm64-reject-out-of-range-b.cond-targets.patch
+nfsd-fix-file-change-detection-in-cb_getattr.patch
+nfsd-release-layout-stid-on-setlease-failure.patch
+kernel-fork-clear-pf_block_ts-in-copy_process.patch
+userfaultfd-gate-must_wait-writability-check-on-pte_.patch
+perf-fix-dangling-cgroup-pointer-in-cpuctx-backport.patch
--- /dev/null
+From 53e60536810e916ce20d10ac84ccf4c679884fa0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:49:05 +0100
+Subject: userfaultfd: gate must_wait writability check on pte_present()
+
+From: Kiryl Shutsemau <kas@kernel.org>
+
+[ Upstream commit 8e80af52db652fbc41320eee45a4f73bc029faf2 ]
+
+userfaultfd_must_wait() and userfaultfd_huge_must_wait() read the PTE
+without taking the page table lock and then apply pte_write() /
+huge_pte_write() to it. Those accessors decode bits from the present
+encoding only; on a swap or migration entry they read the offset bits that
+happen to share the same position and return an undefined result.
+
+The intent of the check is "is this fault still WP-blocked?". A
+non-marker swap entry means the page is in transit -- the userfault
+context the original fault delivered against is no longer the same, and
+the swap-in or migration completion path will re-deliver a fresh fault if
+userspace still needs to handle it. Worst case under the current code the
+garbage write bit says "wait", and the thread stays asleep until a
+UFFDIO_WAKE that may never arrive.
+
+Gate the writability check on pte_present() so the lockless re-check only
+inspects present-PTE bits when the entry is actually present. The
+non-present, non-marker case returns "don't wait" and lets the fault path
+retry.
+
+Link: https://lore.kernel.org/20260529172331.356655-6-kas@kernel.org
+Fixes: 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges")
+Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+
+[ kas: apply to fs/userfaultfd.c and fold the pte_present()/
+ huge_pte_present() gate into the existing writability checks; this tree
+ predates the marker/return-style refactor of these functions ]
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/userfaultfd.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index 29c9941e5ea79f..cbd9d610c54bf0 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -251,7 +251,12 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
+ */
+ if (huge_pte_none_mostly(pte))
+ ret = true;
+- if (!huge_pte_write(pte) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): huge_pte_write() on a
++ * non-present migration entry decodes random offset bits. The
++ * migration completion path re-delivers the fault if still needed.
++ */
++ if (pte_present(pte) && !huge_pte_write(pte) && (reason & VM_UFFD_WP))
+ ret = true;
+ out:
+ return ret;
+@@ -326,7 +331,12 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
+ ptent = ptep_get(pte);
+ if (pte_none_mostly(ptent))
+ ret = true;
+- if (!pte_write(ptent) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): pte_write() on a
++ * non-present swap/migration entry decodes random offset bits. The
++ * page-in path re-delivers the fault if it still needs userspace.
++ */
++ if (pte_present(ptent) && !pte_write(ptent) && (reason & VM_UFFD_WP))
+ ret = true;
+ pte_unmap(pte);
+
+--
+2.53.0
+
--- /dev/null
+From 77ca1ddf431d2da2c0a0f90448a6a286cfb3f90e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Jun 2026 07:15:17 -0700
+Subject: kernel/fork: clear PF_BLOCK_TS in copy_process()
+
+From: Usama Arif <usama.arif@linux.dev>
+
+[ Upstream commit fd38b75c4b43295b10d69772a46d1c74dbd6fc81 ]
+
+PF_BLOCK_TS is only set in blk_time_get_ns() when current->plug is
+non-NULL, and blk_finish_plug() clears it via __blk_flush_plug()
+before NULLing the plug pointer. copy_process() breaks the
+invariant by inheriting PF_BLOCK_TS from the parent while resetting
+the child's plug to NULL.
+
+Clear PF_BLOCK_TS alongside that assignment so callers can rely on
+"PF_BLOCK_TS set implies current->plug != NULL" and dereference
+current->plug unguarded.
+
+Fixes: 06b23f92af87 ("block: update cached timestamp post schedule/preemption")
+Cc: stable@vger.kernel.org
+Signed-off-by: Usama Arif <usama.arif@linux.dev>
+Link: https://patch.msgid.link/20260616141604.328820-2-usama.arif@linux.dev
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fork.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 1215d3f52c6d21..8b1238d692916c 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2230,6 +2230,7 @@ __latent_entropy struct task_struct *copy_process(
+
+ #ifdef CONFIG_BLOCK
+ p->plug = NULL;
++ p->flags &= ~PF_BLOCK_TS;
+ #endif
+ futex_init_task(p);
+
+--
+2.53.0
+
--- /dev/null
+From cfeac762936a8a9061631f99271029941fe760b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:24:09 -0400
+Subject: nfsd: release layout stid on setlease failure
+
+From: Chris Mason <clm@meta.com>
+
+commit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream.
+
+nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via
+idr_alloc_cyclic() under cl_lock before returning to
+nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then
+fails, the error path frees the layout stateid directly with
+kmem_cache_free() without ever calling idr_remove(), leaving the
+IDR slot pointing at freed slab memory. Any subsequent IDR walker
+(states_show, client teardown) dereferences the dangling pointer.
+
+The correct teardown for an IDR-published stid is nfs4_put_stid(),
+which removes the IDR slot under cl_lock, dispatches sc_free
+(nfsd4_free_layout_stateid) to release ls->ls_file via
+nfsd4_close_layout(), and drops the nfs4_file reference in its
+tail.
+
+A second issue blocks that switch: nfsd4_free_layout_stateid()
+unconditionally inspects ls->ls_fence_work via
+delayed_work_pending() under ls_lock, but
+INIT_DELAYED_WORK(&ls->ls_fence_work, ...) currently runs only
+after the setlease call. On the setlease-failure path the
+destructor would touch an uninitialized delayed_work.
+
+ nfsd4_alloc_layout_stateid()
+ nfs4_alloc_stid() /* idr_alloc_cyclic under cl_lock */
+ nfsd4_layout_setlease() /* fails */
+ nfs4_put_stid()
+ nfsd4_free_layout_stateid()
+ delayed_work_pending(&ls->ls_fence_work) /* needs INIT */
+ nfsd4_close_layout() /* nfsd_file_put(ls->ls_file) */
+ put_nfs4_file()
+
+Fix by hoisting the ls_fenced / ls_fence_delay / INIT_DELAYED_WORK
+initialization above the nfsd4_layout_setlease() call, and replace
+the manual nfsd_file_put + put_nfs4_file + kmem_cache_free cleanup
+with a single nfs4_put_stid(stp).
+
+Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
+Cc: stable@vger.kernel.org
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: drop fence_work init hoist absent from 6.18.y ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4layouts.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
+index 683bd1130afe29..62762e43f810b3 100644
+--- a/fs/nfsd/nfs4layouts.c
++++ b/fs/nfsd/nfs4layouts.c
+@@ -256,9 +256,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
+ BUG_ON(!ls->ls_file);
+
+ if (nfsd4_layout_setlease(ls)) {
+- nfsd_file_put(ls->ls_file);
+- put_nfs4_file(fp);
+- kmem_cache_free(nfs4_layout_stateid_cache, ls);
++ nfs4_put_stid(stp);
+ return NULL;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 8f5c131aec0d4bd9d28f822e8bddd3f73662d252 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:24:07 -0400
+Subject: nfsd: update mtime/ctime on CLONE in presense of delegated attributes
+
+From: Olga Kornievskaia <okorniev@redhat.com>
+
+commit 2863bac7f49c4acd80a048ce52506a2b9c8db015 upstream.
+
+When delegated attributes are given on open, the file is opened with
+NOCMTIME and modifying operations do not update mtime/ctime as to not get
+out-of-sync with the client's delegated view. However, for CLONE operation,
+the server should update its view of mtime/ctime and reflect that in any
+GETATTR queries.
+
+Fixes: e5e9b24ab8fa ("nfsd: freeze c/mtime updates with outstanding WRITE_ATTRS delegation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Olga Kornievskaia <okorniev@redhat.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: 9be4b7e74eb7 and 3daab3112f03 are missing from linux-6.18.y ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4proc.c | 3 +++
+ fs/nfsd/nfs4state.c | 44 +++++++++++++++++++++++++++++---------------
+ fs/nfsd/state.h | 1 +
+ 3 files changed, 33 insertions(+), 15 deletions(-)
+
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index 9d876f9d98be20..5bfe49502a06f4 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1350,6 +1350,9 @@ nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ dst, clone->cl_dst_pos, clone->cl_count,
+ EX_ISSYNC(cstate->current_fh.fh_export));
+
++ if (!status && (READ_ONCE(dst->nf_file->f_mode) & FMODE_NOCMTIME) != 0)
++ nfsd_update_cmtime_attr(dst->nf_file, 0);
++
+ nfsd_file_put(dst);
+ nfsd_file_put(src);
+ out:
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index b02fe9926b093c..a063a4a83ec22d 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -1226,10 +1226,6 @@ static void put_deleg_file(struct nfs4_file *fp)
+
+ static void nfsd4_finalize_deleg_timestamps(struct nfs4_delegation *dp, struct file *f)
+ {
+- struct iattr ia = { .ia_valid = ATTR_ATIME | ATTR_CTIME | ATTR_MTIME | ATTR_DELEG };
+- struct inode *inode = file_inode(f);
+- int ret;
+-
+ /* don't do anything if FMODE_NOCMTIME isn't set */
+ if ((READ_ONCE(f->f_mode) & FMODE_NOCMTIME) == 0)
+ return;
+@@ -1247,17 +1243,7 @@ static void nfsd4_finalize_deleg_timestamps(struct nfs4_delegation *dp, struct f
+ return;
+
+ /* Stamp everything to "now" */
+- inode_lock(inode);
+- ret = notify_change(&nop_mnt_idmap, f->f_path.dentry, &ia, NULL);
+- inode_unlock(inode);
+- if (ret) {
+- struct inode *inode = file_inode(f);
+-
+- pr_notice_ratelimited("Unable to update timestamps on inode %02x:%02x:%lu: %d\n",
+- MAJOR(inode->i_sb->s_dev),
+- MINOR(inode->i_sb->s_dev),
+- inode->i_ino, ret);
+- }
++ nfsd_update_cmtime_attr(f, ATTR_ATIME);
+ }
+
+ static void nfs4_unlock_deleg_lease(struct nfs4_delegation *dp)
+@@ -9434,3 +9420,31 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry,
+ nfs4_put_stid(&dp->dl_stid);
+ return status;
+ }
++
++/**
++ * nfsd_update_cmtime_attr - update file's delegated ctime/mtime,
++ * and optionally other attributes (ie ATTR_ATIME).
++ * @f: pointer to an opened file
++ * @flags: any additional flags that should be updated
++ *
++ * Given upon opening a file delegated attributes were issues, update
++ * @f attributes to current times.
++ */
++void nfsd_update_cmtime_attr(struct file *f, unsigned int flags)
++{
++ int ret;
++ struct inode *inode = file_inode(f);
++ struct iattr attr = {
++ .ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_DELEG | flags,
++ };
++
++ inode_lock(inode);
++ ret = notify_change(&nop_mnt_idmap, f->f_path.dentry, &attr, NULL);
++ inode_unlock(inode);
++ if (ret)
++ pr_notice_ratelimited("nfsd: Unable to update timestamps on "
++ "inode %02x:%02x:%lu: %d\n",
++ MAJOR(inode->i_sb->s_dev),
++ MINOR(inode->i_sb->s_dev),
++ inode->i_ino, ret);
++}
+diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
+index aaf513ed910459..2eed2c5b3cd0c2 100644
+--- a/fs/nfsd/state.h
++++ b/fs/nfsd/state.h
+@@ -831,6 +831,7 @@ extern void nfsd4_shutdown_callback(struct nfs4_client *);
+ extern void nfsd4_shutdown_copy(struct nfs4_client *clp);
+ void nfsd4_async_copy_reaper(struct nfsd_net *nn);
+ bool nfsd4_has_active_async_copies(struct nfs4_client *clp);
++void nfsd_update_cmtime_attr(struct file *f, unsigned int flags);
+ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name,
+ struct xdr_netobj princhash, struct nfsd_net *nn);
+ extern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_net *nn);
+--
+2.53.0
+
--- /dev/null
+From 5baa12ecda3d86229dcc96934f06da46ce01632c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:24:08 -0400
+Subject: nfsd: update mtime/ctime on COPY in presence of delegated attributes
+
+From: Olga Kornievskaia <okorniev@redhat.com>
+
+commit 4183cf383b6faec17a0882b84cd2d901dba62b16 upstream.
+
+When delegated attributes are given on open, the file is opened with
+NOCMTIME and modifying operations do not update mtime/ctime as to not get
+out-of-sync with the client's delegated view. However, for COPY operation,
+the server should update its view of mtime/ctime and reflect that in any
+GETATTR queries.
+
+Fixes: e5e9b24ab8fa ("nfsd: freeze c/mtime updates with outstanding WRITE_ATTRS delegation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Olga Kornievskaia <okorniev@redhat.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4proc.c | 11 ++++++++++-
+ fs/nfsd/xdr4.h | 1 +
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index 5bfe49502a06f4..98086d217aa220 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1956,8 +1956,10 @@ static int nfsd4_do_async_copy(void *data)
+
+ set_bit(NFSD4_COPY_F_COMPLETED, ©->cp_flags);
+ trace_nfsd_copy_async_done(copy);
+- nfsd4_send_cb_offload(copy);
+ atomic_dec(©->cp_nn->pending_async_copies);
++ if (copy->cp_res.wr_bytes_written > 0 && copy->attr_update)
++ nfsd_update_cmtime_attr(copy->nf_dst->nf_file, 0);
++ nfsd4_send_cb_offload(copy);
+ return 0;
+ }
+
+@@ -2017,6 +2019,9 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ memcpy(&result->cb_stateid, ©->cp_stateid.cs_stid,
+ sizeof(result->cb_stateid));
+ dup_copy_fields(copy, async_copy);
++ if ((READ_ONCE(copy->nf_dst->nf_file->f_mode) &
++ FMODE_NOCMTIME) != 0)
++ async_copy->attr_update = true;
+ memcpy(async_copy->cp_cb_offload.co_referring_sessionid.data,
+ cstate->session->se_sessionid.data,
+ NFS4_MAX_SESSIONID_LEN);
+@@ -2035,6 +2040,10 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ } else {
+ status = nfsd4_do_copy(copy, copy->nf_src->nf_file,
+ copy->nf_dst->nf_file, true);
++ if ((READ_ONCE(copy->nf_dst->nf_file->f_mode) &
++ FMODE_NOCMTIME) != 0 &&
++ copy->cp_res.wr_bytes_written > 0)
++ nfsd_update_cmtime_attr(copy->nf_dst->nf_file, 0);
+ }
+ out:
+ trace_nfsd_copy_done(copy, status);
+diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
+index 1ce8e12ae3354c..d0ef5e7f10778f 100644
+--- a/fs/nfsd/xdr4.h
++++ b/fs/nfsd/xdr4.h
+@@ -745,6 +745,7 @@ struct nfsd4_copy {
+
+ struct nfsd_file *nf_src;
+ struct nfsd_file *nf_dst;
++ bool attr_update;
+
+ copy_stateid_t cp_stateid;
+
+--
+2.53.0
+
--- /dev/null
+From b6bf453231a442e2704299420b50d548709d8f15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 12:41:52 +0200
+Subject: rust: str: clean unused import for Rust >= 1.98
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit 3fff4271809b57182c4011811e96556bdd4cb2f9 ]
+
+Starting with Rust 1.98.0 (expected 2026-08-20), the compiler has changed
+how the resolution algorithm works [1] in upstream commit c4d84db5f184
+("Resolver: Batched import resolution."), and it now spots:
+
+ error: unused import: `flags::*`
+ --> rust/kernel/str.rs:7:9
+ |
+ 7 | flags::*,
+ | ^^^^^^^^
+ |
+ = note: `-D unused-imports` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(unused_imports)]`
+
+It happens to not be needed because the `prelude::*` already provides
+the flags.
+
+Thus clean it up.
+
+Cc: stable@vger.kernel.org # Needed in 6.18.y and later (prelude added to `str`).
+Link: https://github.com/rust-lang/rust/pull/145108 [1]
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Link: https://patch.msgid.link/20260609104152.261145-2-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/str.rs | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
+index 3a276bc32962d9..22cefbc9852360 100644
+--- a/rust/kernel/str.rs
++++ b/rust/kernel/str.rs
+@@ -4,7 +4,6 @@
+
+ use crate::{
+ alloc::{
+- flags::*,
+ AllocError,
+ KVec, //
+ },
+--
+2.53.0
+
--- /dev/null
+From a0fff564c0eccea685be81101d7c2a50cb71ff9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 12:41:51 +0200
+Subject: rust: str: use the "kernel vertical" imports style
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit 724a93a9f6033800b02a3530dbcb464638448e7f ]
+
+Convert the imports to use the "kernel vertical" imports style [1].
+
+No functional changes intended.
+
+Link: https://docs.kernel.org/rust/coding-guidelines.html#imports [1]
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://patch.msgid.link/20260609104152.261145-1-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Stable-dep-of: 3fff4271809b ("rust: str: clean unused import for Rust >= 1.98")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/str.rs | 25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
+index 8992fedabaf0f7..3a276bc32962d9 100644
+--- a/rust/kernel/str.rs
++++ b/rust/kernel/str.rs
+@@ -3,14 +3,29 @@
+ //! String representations.
+
+ use crate::{
+- alloc::{flags::*, AllocError, KVec},
+- error::{to_result, Result},
+- fmt::{self, Write},
+- prelude::*,
++ alloc::{
++ flags::*,
++ AllocError,
++ KVec, //
++ },
++ error::{
++ to_result,
++ Result, //
++ },
++ fmt::{
++ self,
++ Write, //
++ },
++ prelude::*, //
+ };
+ use core::{
+ marker::PhantomData,
+- ops::{self, Deref, DerefMut, Index},
++ ops::{
++ self,
++ Deref,
++ DerefMut,
++ Index, //
++ }, //
+ };
+
+ /// Byte string without UTF-8 validity guarantee.
+--
+2.53.0
+
bpf-arm64-reject-out-of-range-b.cond-targets.patch
+nfsd-update-mtime-ctime-on-clone-in-presense-of-dele.patch
+nfsd-update-mtime-ctime-on-copy-in-presence-of-deleg.patch
+nfsd-release-layout-stid-on-setlease-failure.patch
+kernel-fork-clear-pf_block_ts-in-copy_process.patch
+rust-str-use-the-kernel-vertical-imports-style.patch
+rust-str-clean-unused-import-for-rust-1.98.patch
+userfaultfd-gate-must_wait-writability-check-on-pte_.patch
--- /dev/null
+From 8e8e4086e0a1117a188b3f83a2b84aa2112de741 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:49:07 +0100
+Subject: userfaultfd: gate must_wait writability check on pte_present()
+
+From: Kiryl Shutsemau <kas@kernel.org>
+
+[ Upstream commit 8e80af52db652fbc41320eee45a4f73bc029faf2 ]
+
+userfaultfd_must_wait() and userfaultfd_huge_must_wait() read the PTE
+without taking the page table lock and then apply pte_write() /
+huge_pte_write() to it. Those accessors decode bits from the present
+encoding only; on a swap or migration entry they read the offset bits that
+happen to share the same position and return an undefined result.
+
+The intent of the check is "is this fault still WP-blocked?". A
+non-marker swap entry means the page is in transit -- the userfault
+context the original fault delivered against is no longer the same, and
+the swap-in or migration completion path will re-deliver a fresh fault if
+userspace still needs to handle it. Worst case under the current code the
+garbage write bit says "wait", and the thread stays asleep until a
+UFFDIO_WAKE that may never arrive.
+
+Gate the writability check on pte_present() so the lockless re-check only
+inspects present-PTE bits when the entry is actually present. The
+non-present, non-marker case returns "don't wait" and lets the fault path
+retry.
+
+Link: https://lore.kernel.org/20260529172331.356655-6-kas@kernel.org
+Fixes: 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges")
+Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+
+[ kas: apply to fs/userfaultfd.c and fold the pte_present()/
+ huge_pte_present() gate into the existing writability checks; this tree
+ predates the marker/return-style refactor of these functions ]
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/userfaultfd.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index a67afdbbf77af1..7e40eb9131bd70 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -251,7 +251,12 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
+ */
+ if (huge_pte_none_mostly(pte))
+ ret = true;
+- if (!huge_pte_write(pte) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): huge_pte_write() on a
++ * non-present migration entry decodes random offset bits. The
++ * migration completion path re-delivers the fault if still needed.
++ */
++ if (pte_present(pte) && !huge_pte_write(pte) && (reason & VM_UFFD_WP))
+ ret = true;
+ out:
+ return ret;
+@@ -326,7 +331,12 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
+ ptent = ptep_get(pte);
+ if (pte_none_mostly(ptent))
+ ret = true;
+- if (!pte_write(ptent) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): pte_write() on a
++ * non-present swap/migration entry decodes random offset bits. The
++ * page-in path re-delivers the fault if it still needs userspace.
++ */
++ if (pte_present(ptent) && !pte_write(ptent) && (reason & VM_UFFD_WP))
+ ret = true;
+ pte_unmap(pte);
+
+--
+2.53.0
+
--- /dev/null
+From cd09de42640fbefa66acb845eaf68bc2af47162c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 May 2024 16:15:18 -0700
+Subject: Bluetooth: btmtk: apply the common btmtk_fw_get_filename
+
+From: Sean Wang <sean.wang@mediatek.com>
+
+[ Upstream commit 7f935b21bee4d8a9f26b57ae6c3682161b247809 ]
+
+Apply the common btmtk_fw_get_filename to avoid the similar coding in each
+driver.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 5c5e8c52e3ca ("Bluetooth: btmtk: move btusb_mtk_[setup, shutdown] to btmtk.c")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btmtksdio.c | 3 +++
+ drivers/bluetooth/btusb.c | 10 ++--------
+ 2 files changed, 5 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
+index e249aa7587833b..2be38c8e353efb 100644
+--- a/drivers/bluetooth/btmtksdio.c
++++ b/drivers/bluetooth/btmtksdio.c
+@@ -1111,6 +1111,9 @@ static int btmtksdio_setup(struct hci_dev *hdev)
+ return err;
+ }
+
++ btmtk_fw_get_filename(fwname, sizeof(fwname), dev_id,
++ fw_version, 0);
++
+ snprintf(fwname, sizeof(fwname),
+ "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
+ dev_id & 0xffff, (fw_version & 0xff) + 1);
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 9b2857a8e7ac1f..048929e336cf64 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2940,14 +2940,8 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
+ case 0x7922:
+ case 0x7961:
+ case 0x7925:
+- if (dev_id == 0x7925)
+- snprintf(fw_bin_name, sizeof(fw_bin_name),
+- "mediatek/mt%04x/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
+- dev_id & 0xffff, dev_id & 0xffff, (fw_version & 0xff) + 1);
+- else
+- snprintf(fw_bin_name, sizeof(fw_bin_name),
+- "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
+- dev_id & 0xffff, (fw_version & 0xff) + 1);
++ btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id,
++ fw_version, 0);
+
+ err = btmtk_setup_firmware_79xx(hdev, fw_bin_name,
+ btmtk_usb_hci_wmt_sync);
+--
+2.53.0
+
--- /dev/null
+From 42fbc2763ae4bf267900aa1fa7c048837ec2ce4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jul 2024 11:30:19 +0800
+Subject: Bluetooth: btmtk: Fix btmtk.c undefined reference build error
+
+From: Chris Lu <chris.lu@mediatek.com>
+
+[ Upstream commit f0c83a23fcbb424fdff5b38fbcdda3c04003a210 ]
+
+MediaTek moved some usb interface related function to btmtk.c which
+may cause build failed if BT USB Kconfig wasn't enabled.
+Fix undefined reference by adding config check.
+
+btmtk.c:(.text+0x89c): undefined reference to `usb_alloc_urb'
+btmtk.c:(.text+0x8e3): undefined reference to `usb_free_urb'
+btmtk.c:(.text+0x956): undefined reference to `usb_free_urb'
+btmtk.c:(.text+0xa0e): undefined reference to `usb_anchor_urb'
+btmtk.c:(.text+0xb43): undefined reference to `usb_autopm_get_interface'
+btmtk.c:(.text+0xb7e): undefined reference to `usb_autopm_put_interface'
+btmtk.c:(.text+0xf70): undefined reference to `usb_disable_autosuspend'
+btmtk.c:(.text+0x133a): undefined reference to `usb_control_msg'
+
+Fixes: d019930b0049 ("Bluetooth: btmtk: move btusb_mtk_hci_wmt_sync to btmtk.c")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202407091928.AH0aGZnx-lkp@intel.com/
+Signed-off-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btmtk.c | 2 ++
+ drivers/bluetooth/btmtk.h | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
+index bd28a2d52af169..ab68c2cbd79e5e 100644
+--- a/drivers/bluetooth/btmtk.c
++++ b/drivers/bluetooth/btmtk.c
+@@ -438,6 +438,7 @@ int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb)
+ }
+ EXPORT_SYMBOL_GPL(btmtk_process_coredump);
+
++#if IS_ENABLED(CONFIG_BT_HCIBTUSB_MTK)
+ static void btmtk_usb_wmt_recv(struct urb *urb)
+ {
+ struct hci_dev *hdev = urb->context;
+@@ -1162,6 +1163,7 @@ int btmtk_usb_shutdown(struct hci_dev *hdev)
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(btmtk_usb_shutdown);
++#endif
+
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+ MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>");
+diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
+index fe41528ae509bf..0acf8bd57c56e5 100644
+--- a/drivers/bluetooth/btmtk.h
++++ b/drivers/bluetooth/btmtk.h
+@@ -189,11 +189,13 @@ int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb);
+ void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id, u32 fw_ver,
+ u32 fw_flavor);
+
++#if IS_ENABLED(CONFIG_BT_HCIBTUSB_MTK)
+ int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id);
+
+ int btmtk_usb_setup(struct hci_dev *hdev);
+
+ int btmtk_usb_shutdown(struct hci_dev *hdev);
++#endif
+ #else
+
+ static inline int btmtk_set_bdaddr(struct hci_dev *hdev,
+--
+2.53.0
+
--- /dev/null
+From 7e5aab02d869df92ae054b61665579c65707b250 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jan 2025 17:50:28 +0800
+Subject: Bluetooth: btmtk: Fix failed to send func ctrl for MediaTek devices.
+
+From: Chris Lu <chris.lu@mediatek.com>
+
+[ Upstream commit 67dba2c28fe0af7e25ea1aeade677162ed05310a ]
+
+Use usb_autopm_get_interface() and usb_autopm_put_interface()
+in btmtk_usb_shutdown(), it could send func ctrl after enabling
+autosuspend.
+
+Bluetooth: btmtk_usb_hci_wmt_sync() hci0: Execution of wmt command
+ timed out
+Bluetooth: btmtk_usb_shutdown() hci0: Failed to send wmt func ctrl
+ (-110)
+
+Fixes: 5c5e8c52e3ca ("Bluetooth: btmtk: move btusb_mtk_[setup, shutdown] to btmtk.c")
+Signed-off-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btmtk.c | 7 +++++++
+ net/bluetooth/rfcomm/tty.c | 4 ++--
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
+index 8fd923de47c1f3..29d4a04ea0d46a 100644
+--- a/drivers/bluetooth/btmtk.c
++++ b/drivers/bluetooth/btmtk.c
+@@ -1140,10 +1140,15 @@ EXPORT_SYMBOL_GPL(btmtk_usb_setup);
+
+ int btmtk_usb_shutdown(struct hci_dev *hdev)
+ {
++ struct btmtk_data *data = hci_get_priv(hdev);
+ struct btmtk_hci_wmt_params wmt_params;
+ u8 param = 0;
+ int err;
+
++ err = usb_autopm_get_interface(data->intf);
++ if (err < 0)
++ return err;
++
+ /* Disable the device */
+ wmt_params.op = BTMTK_WMT_FUNC_CTRL;
+ wmt_params.flag = 0;
+@@ -1154,9 +1159,11 @@ int btmtk_usb_shutdown(struct hci_dev *hdev)
+ err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
++ usb_autopm_put_interface(data->intf);
+ return err;
+ }
+
++ usb_autopm_put_interface(data->intf);
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(btmtk_usb_shutdown);
+diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
+index 912e37cb8310c6..389d7b47ad6132 100644
+--- a/net/bluetooth/rfcomm/tty.c
++++ b/net/bluetooth/rfcomm/tty.c
+@@ -201,14 +201,14 @@ static ssize_t address_show(struct device *tty_dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
+- return sprintf(buf, "%pMR\n", &dev->dst);
++ return sysfs_emit(buf, "%pMR\n", &dev->dst);
+ }
+
+ static ssize_t channel_show(struct device *tty_dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
+- return sprintf(buf, "%d\n", dev->channel);
++ return sysfs_emit(buf, "%d\n", dev->channel);
+ }
+
+ static DEVICE_ATTR_RO(address);
+--
+2.53.0
+
--- /dev/null
+From 56bc657c16594a632cfb6c958c084ff1a34888e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Jul 2025 16:51:17 +0800
+Subject: Bluetooth: btmtk: Fix wait_on_bit_timeout interruption during
+ shutdown
+
+From: Jiande Lu <jiande.lu@mediatek.com>
+
+[ Upstream commit 099799fa9b76c5c02b49e07005a85117a25b01ea ]
+
+During the shutdown process, an interrupt occurs that
+prematurely terminates the wait for the expected event.
+This change replaces TASK_INTERRUPTIBLE with
+TASK_UNINTERRUPTIBLE in the wait_on_bit_timeout call to ensure
+the shutdown process completes as intended without being
+interrupted by signals.
+
+Fixes: d019930b0049 ("Bluetooth: btmtk: move btusb_mtk_hci_wmt_sync to btmtk.c")
+Signed-off-by: Jiande Lu <jiande.lu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btmtk.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
+index 29d4a04ea0d46a..bd28a2d52af169 100644
+--- a/drivers/bluetooth/btmtk.c
++++ b/drivers/bluetooth/btmtk.c
+@@ -640,12 +640,7 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
+ * WMT command.
+ */
+ err = wait_on_bit_timeout(&data->flags, BTMTK_TX_WAIT_VND_EVT,
+- TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT);
+- if (err == -EINTR) {
+- bt_dev_err(hdev, "Execution of wmt command interrupted");
+- clear_bit(BTMTK_TX_WAIT_VND_EVT, &data->flags);
+- goto err_free_wc;
+- }
++ TASK_UNINTERRUPTIBLE, HCI_INIT_TIMEOUT);
+
+ if (err) {
+ bt_dev_err(hdev, "Execution of wmt command timed out");
+--
+2.53.0
+
--- /dev/null
+From aaf2333ff22b4422b4762e3098abcfd1697e7102 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jul 2024 14:01:14 +0800
+Subject: Bluetooth: btmtk: move btusb_mtk_[setup, shutdown] to btmtk.c
+
+From: Chris Lu <chris.lu@mediatek.com>
+
+[ Upstream commit 5c5e8c52e3cafaa6f71efd44a42a674271e5b3ad ]
+
+Move btusb_mtk_[setup, shutdown] and related function from
+btusb.c to btmtk.c which holds vendor specific stuff and
+would make btusb.c clean.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btmtk.c | 454 +++++++++++++++++++++++++++++++++++++-
+ drivers/bluetooth/btmtk.h | 23 +-
+ drivers/bluetooth/btusb.c | 446 ++-----------------------------------
+ 3 files changed, 484 insertions(+), 439 deletions(-)
+
+diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
+index 582915f9a8d700..8fd923de47c1f3 100644
+--- a/drivers/bluetooth/btmtk.c
++++ b/drivers/bluetooth/btmtk.c
+@@ -5,6 +5,8 @@
+ #include <linux/module.h>
+ #include <linux/firmware.h>
+ #include <linux/usb.h>
++#include <linux/iopoll.h>
++#include <asm/unaligned.h>
+
+ #include <net/bluetooth/bluetooth.h>
+ #include <net/bluetooth/hci_core.h>
+@@ -573,8 +575,8 @@ static int btmtk_usb_submit_wmt_recv_urb(struct hci_dev *hdev)
+ return err;
+ }
+
+-int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
+- struct btmtk_hci_wmt_params *wmt_params)
++static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
++ struct btmtk_hci_wmt_params *wmt_params)
+ {
+ struct btmtk_data *data = hci_get_priv(hdev);
+ struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
+@@ -711,7 +713,453 @@ int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
+ kfree(wc);
+ return err;
+ }
+-EXPORT_SYMBOL_GPL(btmtk_usb_hci_wmt_sync);
++
++static int btmtk_usb_func_query(struct hci_dev *hdev)
++{
++ struct btmtk_hci_wmt_params wmt_params;
++ int status, err;
++ u8 param = 0;
++
++ /* Query whether the function is enabled */
++ wmt_params.op = BTMTK_WMT_FUNC_CTRL;
++ wmt_params.flag = 4;
++ wmt_params.dlen = sizeof(param);
++ wmt_params.data = ¶m;
++ wmt_params.status = &status;
++
++ err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to query function status (%d)", err);
++ return err;
++ }
++
++ return status;
++}
++
++static int btmtk_usb_uhw_reg_write(struct hci_dev *hdev, u32 reg, u32 val)
++{
++ struct btmtk_data *data = hci_get_priv(hdev);
++ int pipe, err;
++ void *buf;
++
++ buf = kzalloc(4, GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++
++ put_unaligned_le32(val, buf);
++
++ pipe = usb_sndctrlpipe(data->udev, 0);
++ err = usb_control_msg(data->udev, pipe, 0x02,
++ 0x5E,
++ reg >> 16, reg & 0xffff,
++ buf, 4, USB_CTRL_SET_TIMEOUT);
++ if (err < 0)
++ bt_dev_err(hdev, "Failed to write uhw reg(%d)", err);
++
++ kfree(buf);
++
++ return err;
++}
++
++static int btmtk_usb_uhw_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
++{
++ struct btmtk_data *data = hci_get_priv(hdev);
++ int pipe, err;
++ void *buf;
++
++ buf = kzalloc(4, GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++
++ pipe = usb_rcvctrlpipe(data->udev, 0);
++ err = usb_control_msg(data->udev, pipe, 0x01,
++ 0xDE,
++ reg >> 16, reg & 0xffff,
++ buf, 4, USB_CTRL_GET_TIMEOUT);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to read uhw reg(%d)", err);
++ goto err_free_buf;
++ }
++
++ *val = get_unaligned_le32(buf);
++ bt_dev_dbg(hdev, "reg=%x, value=0x%08x", reg, *val);
++
++err_free_buf:
++ kfree(buf);
++
++ return err;
++}
++
++static int btmtk_usb_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
++{
++ struct btmtk_data *data = hci_get_priv(hdev);
++ int pipe, err, size = sizeof(u32);
++ void *buf;
++
++ buf = kzalloc(size, GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++
++ pipe = usb_rcvctrlpipe(data->udev, 0);
++ err = usb_control_msg(data->udev, pipe, 0x63,
++ USB_TYPE_VENDOR | USB_DIR_IN,
++ reg >> 16, reg & 0xffff,
++ buf, size, USB_CTRL_GET_TIMEOUT);
++ if (err < 0)
++ goto err_free_buf;
++
++ *val = get_unaligned_le32(buf);
++
++err_free_buf:
++ kfree(buf);
++
++ return err;
++}
++
++static int btmtk_usb_id_get(struct hci_dev *hdev, u32 reg, u32 *id)
++{
++ return btmtk_usb_reg_read(hdev, reg, id);
++}
++
++static u32 btmtk_usb_reset_done(struct hci_dev *hdev)
++{
++ u32 val = 0;
++
++ btmtk_usb_uhw_reg_read(hdev, MTK_BT_MISC, &val);
++
++ return val & MTK_BT_RST_DONE;
++}
++
++int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id)
++{
++ u32 val;
++ int err;
++
++ if (dev_id == 0x7922) {
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_BT_SUBSYS_RST, &val);
++ if (err < 0)
++ return err;
++ val |= 0x00002020;
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_BT_SUBSYS_RST, val);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_EP_RST_OPT, 0x00010001);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_BT_SUBSYS_RST, &val);
++ if (err < 0)
++ return err;
++ val |= BIT(0);
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_BT_SUBSYS_RST, val);
++ if (err < 0)
++ return err;
++ msleep(100);
++ } else if (dev_id == 0x7925) {
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_BT_RESET_REG_CONNV3, &val);
++ if (err < 0)
++ return err;
++ val |= (1 << 5);
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_BT_RESET_REG_CONNV3, val);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_BT_RESET_REG_CONNV3, &val);
++ if (err < 0)
++ return err;
++ val &= 0xFFFF00FF;
++ val |= (1 << 13);
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_BT_RESET_REG_CONNV3, val);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_EP_RST_OPT, 0x00010001);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_BT_RESET_REG_CONNV3, &val);
++ if (err < 0)
++ return err;
++ val |= (1 << 0);
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_BT_RESET_REG_CONNV3, val);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_UDMA_INT_STA_BT, 0x000000FF);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_UDMA_INT_STA_BT, &val);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_UDMA_INT_STA_BT1, 0x000000FF);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_UDMA_INT_STA_BT1, &val);
++ if (err < 0)
++ return err;
++ msleep(100);
++ } else {
++ /* It's Device EndPoint Reset Option Register */
++ bt_dev_dbg(hdev, "Initiating reset mechanism via uhw");
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_BT_WDT_STATUS, &val);
++ if (err < 0)
++ return err;
++ /* Reset the bluetooth chip via USB interface. */
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_BT_SUBSYS_RST, 1);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_UDMA_INT_STA_BT, 0x000000FF);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_UDMA_INT_STA_BT, &val);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_UDMA_INT_STA_BT1, 0x000000FF);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_UDMA_INT_STA_BT1, &val);
++ if (err < 0)
++ return err;
++ /* MT7921 need to delay 20ms between toggle reset bit */
++ msleep(20);
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_BT_SUBSYS_RST, 0);
++ if (err < 0)
++ return err;
++ err = btmtk_usb_uhw_reg_read(hdev, MTK_BT_SUBSYS_RST, &val);
++ if (err < 0)
++ return err;
++ }
++
++ err = readx_poll_timeout(btmtk_usb_reset_done, hdev, val,
++ val & MTK_BT_RST_DONE, 20000, 1000000);
++ if (err < 0)
++ bt_dev_err(hdev, "Reset timeout");
++
++ if (dev_id == 0x7922) {
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_UDMA_INT_STA_BT, 0x000000FF);
++ if (err < 0)
++ return err;
++ }
++
++ err = btmtk_usb_id_get(hdev, 0x70010200, &val);
++ if (err < 0 || !val)
++ bt_dev_err(hdev, "Can't get device id, subsys reset fail.");
++
++ return err;
++}
++EXPORT_SYMBOL_GPL(btmtk_usb_subsys_reset);
++
++int btmtk_usb_setup(struct hci_dev *hdev)
++{
++ struct btmtk_data *btmtk_data = hci_get_priv(hdev);
++ struct btmtk_hci_wmt_params wmt_params;
++ ktime_t calltime, delta, rettime;
++ struct btmtk_tci_sleep tci_sleep;
++ unsigned long long duration;
++ struct sk_buff *skb;
++ const char *fwname;
++ int err, status;
++ u32 dev_id = 0;
++ char fw_bin_name[64];
++ u32 fw_version = 0, fw_flavor = 0;
++ u8 param;
++
++ calltime = ktime_get();
++
++ err = btmtk_usb_id_get(hdev, 0x80000008, &dev_id);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to get device id (%d)", err);
++ return err;
++ }
++
++ if (!dev_id || dev_id != 0x7663) {
++ err = btmtk_usb_id_get(hdev, 0x70010200, &dev_id);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to get device id (%d)", err);
++ return err;
++ }
++ err = btmtk_usb_id_get(hdev, 0x80021004, &fw_version);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to get fw version (%d)", err);
++ return err;
++ }
++ err = btmtk_usb_id_get(hdev, 0x70010020, &fw_flavor);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to get fw flavor (%d)", err);
++ return err;
++ }
++ fw_flavor = (fw_flavor & 0x00000080) >> 7;
++ }
++
++ btmtk_data->dev_id = dev_id;
++
++ err = btmtk_register_coredump(hdev, btmtk_data->drv_name, fw_version);
++ if (err < 0)
++ bt_dev_err(hdev, "Failed to register coredump (%d)", err);
++
++ switch (dev_id) {
++ case 0x7663:
++ fwname = FIRMWARE_MT7663;
++ break;
++ case 0x7668:
++ fwname = FIRMWARE_MT7668;
++ break;
++ case 0x7922:
++ case 0x7961:
++ case 0x7925:
++ /* Reset the device to ensure it's in the initial state before
++ * downloading the firmware to ensure.
++ */
++
++ if (!test_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags))
++ btmtk_usb_subsys_reset(hdev, dev_id);
++
++ btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id,
++ fw_version, fw_flavor);
++
++ err = btmtk_setup_firmware_79xx(hdev, fw_bin_name,
++ btmtk_usb_hci_wmt_sync);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to set up firmware (%d)", err);
++ clear_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags);
++ return err;
++ }
++
++ set_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags);
++
++ /* It's Device EndPoint Reset Option Register */
++ err = btmtk_usb_uhw_reg_write(hdev, MTK_EP_RST_OPT,
++ MTK_EP_RST_IN_OUT_OPT);
++ if (err < 0)
++ return err;
++
++ /* Enable Bluetooth protocol */
++ param = 1;
++ wmt_params.op = BTMTK_WMT_FUNC_CTRL;
++ wmt_params.flag = 0;
++ wmt_params.dlen = sizeof(param);
++ wmt_params.data = ¶m;
++ wmt_params.status = NULL;
++
++ err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
++ return err;
++ }
++
++ hci_set_msft_opcode(hdev, 0xFD30);
++ hci_set_aosp_capable(hdev);
++
++ goto done;
++ default:
++ bt_dev_err(hdev, "Unsupported hardware variant (%08x)",
++ dev_id);
++ return -ENODEV;
++ }
++
++ /* Query whether the firmware is already download */
++ wmt_params.op = BTMTK_WMT_SEMAPHORE;
++ wmt_params.flag = 1;
++ wmt_params.dlen = 0;
++ wmt_params.data = NULL;
++ wmt_params.status = &status;
++
++ err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to query firmware status (%d)", err);
++ return err;
++ }
++
++ if (status == BTMTK_WMT_PATCH_DONE) {
++ bt_dev_info(hdev, "firmware already downloaded");
++ goto ignore_setup_fw;
++ }
++
++ /* Setup a firmware which the device definitely requires */
++ err = btmtk_setup_firmware(hdev, fwname,
++ btmtk_usb_hci_wmt_sync);
++ if (err < 0)
++ return err;
++
++ignore_setup_fw:
++ err = readx_poll_timeout(btmtk_usb_func_query, hdev, status,
++ status < 0 || status != BTMTK_WMT_ON_PROGRESS,
++ 2000, 5000000);
++ /* -ETIMEDOUT happens */
++ if (err < 0)
++ return err;
++
++ /* The other errors happen in btmtk_usb_func_query */
++ if (status < 0)
++ return status;
++
++ if (status == BTMTK_WMT_ON_DONE) {
++ bt_dev_info(hdev, "function already on");
++ goto ignore_func_on;
++ }
++
++ /* Enable Bluetooth protocol */
++ param = 1;
++ wmt_params.op = BTMTK_WMT_FUNC_CTRL;
++ wmt_params.flag = 0;
++ wmt_params.dlen = sizeof(param);
++ wmt_params.data = ¶m;
++ wmt_params.status = NULL;
++
++ err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
++ return err;
++ }
++
++ignore_func_on:
++ /* Apply the low power environment setup */
++ tci_sleep.mode = 0x5;
++ tci_sleep.duration = cpu_to_le16(0x640);
++ tci_sleep.host_duration = cpu_to_le16(0x640);
++ tci_sleep.host_wakeup_pin = 0;
++ tci_sleep.time_compensation = 0;
++
++ skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
++ HCI_INIT_TIMEOUT);
++ if (IS_ERR(skb)) {
++ err = PTR_ERR(skb);
++ bt_dev_err(hdev, "Failed to apply low power setting (%d)", err);
++ return err;
++ }
++ kfree_skb(skb);
++
++done:
++ rettime = ktime_get();
++ delta = ktime_sub(rettime, calltime);
++ duration = (unsigned long long)ktime_to_ns(delta) >> 10;
++
++ bt_dev_info(hdev, "Device setup in %llu usecs", duration);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(btmtk_usb_setup);
++
++int btmtk_usb_shutdown(struct hci_dev *hdev)
++{
++ struct btmtk_hci_wmt_params wmt_params;
++ u8 param = 0;
++ int err;
++
++ /* Disable the device */
++ wmt_params.op = BTMTK_WMT_FUNC_CTRL;
++ wmt_params.flag = 0;
++ wmt_params.dlen = sizeof(param);
++ wmt_params.data = ¶m;
++ wmt_params.status = NULL;
++
++ err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
++ if (err < 0) {
++ bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
++ return err;
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(btmtk_usb_shutdown);
+
+ MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+ MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>");
+diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
+index 3055b9728ae250..fe41528ae509bf 100644
+--- a/drivers/bluetooth/btmtk.h
++++ b/drivers/bluetooth/btmtk.h
+@@ -140,6 +140,8 @@ struct btmtk_hci_wmt_params {
+
+ enum {
+ BTMTK_TX_WAIT_VND_EVT,
++ BTMTK_FIRMWARE_LOADED,
++ BTMTK_HW_RESET_ACTIVE,
+ };
+
+ typedef int (*btmtk_reset_sync_func_t)(struct hci_dev *, void *);
+@@ -152,6 +154,7 @@ struct btmtk_coredump_info {
+ };
+
+ struct btmtk_data {
++ const char *drv_name;
+ unsigned long flags;
+ u32 dev_id;
+ btmtk_reset_sync_func_t reset_sync;
+@@ -186,8 +189,11 @@ int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb);
+ void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id, u32 fw_ver,
+ u32 fw_flavor);
+
+-int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
+- struct btmtk_hci_wmt_params *wmt_params);
++int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id);
++
++int btmtk_usb_setup(struct hci_dev *hdev);
++
++int btmtk_usb_shutdown(struct hci_dev *hdev);
+ #else
+
+ static inline int btmtk_set_bdaddr(struct hci_dev *hdev,
+@@ -228,8 +234,17 @@ static void btmtk_fw_get_filename(char *buf, size_t size, u32 dev_id,
+ {
+ }
+
+-static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
+- struct btmtk_hci_wmt_params *wmt_params)
++static int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id)
++{
++ return -EOPNOTSUPP;
++}
++
++static int btmtk_usb_setup(struct hci_dev *hdev)
++{
++ return -EOPNOTSUPP;
++}
++
++static int btmtk_usb_shutdown(struct hci_dev *hdev)
+ {
+ return -EOPNOTSUPP;
+ }
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index a7aa4c1dacb295..86c2aac507d673 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2686,241 +2686,6 @@ static int btusb_recv_event_realtek(struct hci_dev *hdev, struct sk_buff *skb)
+ return hci_recv_frame(hdev, skb);
+ }
+
+-static int btusb_mtk_func_query(struct hci_dev *hdev)
+-{
+- struct btmtk_hci_wmt_params wmt_params;
+- int status, err;
+- u8 param = 0;
+-
+- /* Query whether the function is enabled */
+- wmt_params.op = BTMTK_WMT_FUNC_CTRL;
+- wmt_params.flag = 4;
+- wmt_params.dlen = sizeof(param);
+- wmt_params.data = ¶m;
+- wmt_params.status = &status;
+-
+- err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
+- if (err < 0) {
+- bt_dev_err(hdev, "Failed to query function status (%d)", err);
+- return err;
+- }
+-
+- return status;
+-}
+-
+-static int btusb_mtk_uhw_reg_write(struct btusb_data *data, u32 reg, u32 val)
+-{
+- struct hci_dev *hdev = data->hdev;
+- int pipe, err;
+- void *buf;
+-
+- buf = kzalloc(4, GFP_KERNEL);
+- if (!buf)
+- return -ENOMEM;
+-
+- put_unaligned_le32(val, buf);
+-
+- pipe = usb_sndctrlpipe(data->udev, 0);
+- err = usb_control_msg(data->udev, pipe, 0x02,
+- 0x5E,
+- reg >> 16, reg & 0xffff,
+- buf, 4, USB_CTRL_SET_TIMEOUT);
+- if (err < 0)
+- bt_dev_err(hdev, "Failed to write uhw reg(%d)", err);
+-
+- kfree(buf);
+-
+- return err;
+-}
+-
+-static int btusb_mtk_uhw_reg_read(struct btusb_data *data, u32 reg, u32 *val)
+-{
+- struct hci_dev *hdev = data->hdev;
+- int pipe, err;
+- void *buf;
+-
+- buf = kzalloc(4, GFP_KERNEL);
+- if (!buf)
+- return -ENOMEM;
+-
+- pipe = usb_rcvctrlpipe(data->udev, 0);
+- err = usb_control_msg(data->udev, pipe, 0x01,
+- 0xDE,
+- reg >> 16, reg & 0xffff,
+- buf, 4, USB_CTRL_SET_TIMEOUT);
+- if (err < 0) {
+- bt_dev_err(hdev, "Failed to read uhw reg(%d)", err);
+- goto err_free_buf;
+- }
+-
+- *val = get_unaligned_le32(buf);
+- bt_dev_dbg(hdev, "reg=%x, value=0x%08x", reg, *val);
+-
+-err_free_buf:
+- kfree(buf);
+-
+- return err;
+-}
+-
+-static int btusb_mtk_reg_read(struct btusb_data *data, u32 reg, u32 *val)
+-{
+- int pipe, err, size = sizeof(u32);
+- void *buf;
+-
+- buf = kzalloc(size, GFP_KERNEL);
+- if (!buf)
+- return -ENOMEM;
+-
+- pipe = usb_rcvctrlpipe(data->udev, 0);
+- err = usb_control_msg(data->udev, pipe, 0x63,
+- USB_TYPE_VENDOR | USB_DIR_IN,
+- reg >> 16, reg & 0xffff,
+- buf, size, USB_CTRL_SET_TIMEOUT);
+- if (err < 0)
+- goto err_free_buf;
+-
+- *val = get_unaligned_le32(buf);
+-
+-err_free_buf:
+- kfree(buf);
+-
+- return err;
+-}
+-
+-static int btusb_mtk_id_get(struct btusb_data *data, u32 reg, u32 *id)
+-{
+- return btusb_mtk_reg_read(data, reg, id);
+-}
+-
+-static u32 btusb_mtk_reset_done(struct hci_dev *hdev)
+-{
+- struct btusb_data *data = hci_get_drvdata(hdev);
+- u32 val = 0;
+-
+- btusb_mtk_uhw_reg_read(data, MTK_BT_MISC, &val);
+-
+- return val & MTK_BT_RST_DONE;
+-}
+-
+-static int btusb_mtk_subsys_reset(struct hci_dev *hdev, u32 dev_id)
+-{
+- struct btusb_data *data = hci_get_drvdata(hdev);
+- u32 val;
+- int err;
+-
+- if (dev_id == 0x7922) {
+- err = btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
+- if (err < 0)
+- return err;
+- val |= 0x00002020;
+- err = btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, val);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, 0x00010001);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
+- if (err < 0)
+- return err;
+- val |= BIT(0);
+- err = btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, val);
+- if (err < 0)
+- return err;
+- msleep(100);
+- } else if (dev_id == 0x7925) {
+- err = btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
+- if (err < 0)
+- return err;
+- val |= (1 << 5);
+- err = btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
+- if (err < 0)
+- return err;
+- val &= 0xFFFF00FF;
+- if (err < 0)
+- return err;
+- val |= (1 << 13);
+- err = btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, 0x00010001);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
+- if (err < 0)
+- return err;
+- val |= (1 << 0);
+- err = btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val);
+- if (err < 0)
+- return err;
+- msleep(100);
+- } else {
+- /* It's Device EndPoint Reset Option Register */
+- bt_dev_dbg(hdev, "Initiating reset mechanism via uhw");
+- err = btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_read(data, MTK_BT_WDT_STATUS, &val);
+- if (err < 0)
+- return err;
+- /* Reset the bluetooth chip via USB interface. */
+- err = btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 1);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val);
+- if (err < 0)
+- return err;
+- /* MT7921 need to delay 20ms between toggle reset bit */
+- msleep(20);
+- err = btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0);
+- if (err < 0)
+- return err;
+- err = btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
+- if (err < 0)
+- return err;
+- }
+-
+- err = readx_poll_timeout(btusb_mtk_reset_done, hdev, val,
+- val & MTK_BT_RST_DONE, 20000, 1000000);
+- if (err < 0)
+- bt_dev_err(hdev, "Reset timeout");
+-
+- if (dev_id == 0x7922) {
+- err = btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
+- if (err < 0)
+- return err;
+- }
+-
+- err = btusb_mtk_id_get(data, 0x70010200, &val);
+- if (err < 0 || !val)
+- bt_dev_err(hdev, "Can't get device id, subsys reset fail.");
+-
+- return err;
+-}
+-
+ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
+ {
+ struct btusb_data *data = hci_get_drvdata(hdev);
+@@ -2928,7 +2693,7 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
+ int err;
+
+ /* It's MediaTek specific bluetooth reset mechanism via USB */
+- if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) {
++ if (test_and_set_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags)) {
+ bt_dev_err(hdev, "last reset failed? Not resetting again");
+ return -EBUSY;
+ }
+@@ -2940,10 +2705,10 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
+ btusb_stop_traffic(data);
+ usb_kill_anchored_urbs(&data->tx_anchor);
+
+- err = btusb_mtk_subsys_reset(hdev, btmtk_data->dev_id);
++ err = btmtk_usb_subsys_reset(hdev, btmtk_data->dev_id);
+
+ usb_queue_reset_device(data->intf);
+- clear_bit(BTUSB_HW_RESET_ACTIVE, &data->flags);
++ clear_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags);
+
+ return err;
+ }
+@@ -2951,206 +2716,23 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
+ static int btusb_mtk_setup(struct hci_dev *hdev)
+ {
+ struct btusb_data *data = hci_get_drvdata(hdev);
+- struct btmtk_hci_wmt_params wmt_params;
+- ktime_t calltime, delta, rettime;
+- struct btmtk_tci_sleep tci_sleep;
+- unsigned long long duration;
+- struct sk_buff *skb;
+- const char *fwname;
+- int err, status;
+- u32 dev_id = 0;
+- char fw_bin_name[64];
+- u32 fw_version = 0;
+- u8 param;
+- struct btmtk_data *mediatek;
+-
+- calltime = ktime_get();
+-
+- err = btusb_mtk_id_get(data, 0x80000008, &dev_id);
+- if (err < 0) {
+- bt_dev_err(hdev, "Failed to get device id (%d)", err);
+- return err;
+- }
+-
+- if (!dev_id || dev_id != 0x7663) {
+- err = btusb_mtk_id_get(data, 0x70010200, &dev_id);
+- if (err < 0) {
+- bt_dev_err(hdev, "Failed to get device id (%d)", err);
+- return err;
+- }
+- err = btusb_mtk_id_get(data, 0x80021004, &fw_version);
+- if (err < 0) {
+- bt_dev_err(hdev, "Failed to get fw version (%d)", err);
+- return err;
+- }
+- }
+-
+- mediatek = hci_get_priv(hdev);
+- mediatek->dev_id = dev_id;
+- mediatek->reset_sync = btusb_mtk_reset;
+-
+- err = btmtk_register_coredump(hdev, btusb_driver.name, fw_version);
+- if (err < 0)
+- bt_dev_err(hdev, "Failed to register coredump (%d)", err);
+-
+- switch (dev_id) {
+- case 0x7663:
+- fwname = FIRMWARE_MT7663;
+- break;
+- case 0x7668:
+- fwname = FIRMWARE_MT7668;
+- break;
+- case 0x7922:
+- case 0x7961:
+- case 0x7925:
+- /* Reset the device to ensure it's in the initial state before
+- * downloading the firmware to ensure.
+- */
+-
+- if (!test_bit(BTUSB_FIRMWARE_LOADED, &data->flags))
+- btusb_mtk_subsys_reset(hdev, dev_id);
+-
+- btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id,
+- fw_version, 0);
+-
+- err = btmtk_setup_firmware_79xx(hdev, fw_bin_name,
+- btmtk_usb_hci_wmt_sync);
+- if (err < 0) {
+- bt_dev_err(hdev, "Failed to set up firmware (%d)", err);
+- clear_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
+- return err;
+- }
+-
+- set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
+-
+- /* It's Device EndPoint Reset Option Register */
+- btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT);
+-
+- /* Enable Bluetooth protocol */
+- param = 1;
+- wmt_params.op = BTMTK_WMT_FUNC_CTRL;
+- wmt_params.flag = 0;
+- wmt_params.dlen = sizeof(param);
+- wmt_params.data = ¶m;
+- wmt_params.status = NULL;
+-
+- err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
+- if (err < 0) {
+- bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
+- return err;
+- }
+-
+- hci_set_msft_opcode(hdev, 0xFD30);
+- hci_set_aosp_capable(hdev);
+- goto done;
+- default:
+- bt_dev_err(hdev, "Unsupported hardware variant (%08x)",
+- dev_id);
+- return -ENODEV;
+- }
+-
+- /* Query whether the firmware is already download */
+- wmt_params.op = BTMTK_WMT_SEMAPHORE;
+- wmt_params.flag = 1;
+- wmt_params.dlen = 0;
+- wmt_params.data = NULL;
+- wmt_params.status = &status;
+-
+- err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
+- if (err < 0) {
+- bt_dev_err(hdev, "Failed to query firmware status (%d)", err);
+- return err;
+- }
+-
+- if (status == BTMTK_WMT_PATCH_DONE) {
+- bt_dev_info(hdev, "firmware already downloaded");
+- goto ignore_setup_fw;
+- }
+-
+- /* Setup a firmware which the device definitely requires */
+- err = btmtk_setup_firmware(hdev, fwname,
+- btmtk_usb_hci_wmt_sync);
+- if (err < 0)
+- return err;
+-
+-ignore_setup_fw:
+- err = readx_poll_timeout(btusb_mtk_func_query, hdev, status,
+- status < 0 || status != BTMTK_WMT_ON_PROGRESS,
+- 2000, 5000000);
+- /* -ETIMEDOUT happens */
+- if (err < 0)
+- return err;
+-
+- /* The other errors happen in btusb_mtk_func_query */
+- if (status < 0)
+- return status;
+-
+- if (status == BTMTK_WMT_ON_DONE) {
+- bt_dev_info(hdev, "function already on");
+- goto ignore_func_on;
+- }
+-
+- /* Enable Bluetooth protocol */
+- param = 1;
+- wmt_params.op = BTMTK_WMT_FUNC_CTRL;
+- wmt_params.flag = 0;
+- wmt_params.dlen = sizeof(param);
+- wmt_params.data = ¶m;
+- wmt_params.status = NULL;
+-
+- err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
+- if (err < 0) {
+- bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
+- return err;
+- }
+-
+-ignore_func_on:
+- /* Apply the low power environment setup */
+- tci_sleep.mode = 0x5;
+- tci_sleep.duration = cpu_to_le16(0x640);
+- tci_sleep.host_duration = cpu_to_le16(0x640);
+- tci_sleep.host_wakeup_pin = 0;
+- tci_sleep.time_compensation = 0;
+-
+- skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
+- HCI_INIT_TIMEOUT);
+- if (IS_ERR(skb)) {
+- err = PTR_ERR(skb);
+- bt_dev_err(hdev, "Failed to apply low power setting (%d)", err);
+- return err;
+- }
+- kfree_skb(skb);
+-
+-done:
+- rettime = ktime_get();
+- delta = ktime_sub(rettime, calltime);
+- duration = (unsigned long long)ktime_to_ns(delta) >> 10;
++ struct btmtk_data *btmtk_data = hci_get_priv(hdev);
+
+- bt_dev_info(hdev, "Device setup in %llu usecs", duration);
++ /* MediaTek WMT vendor cmd requiring below USB resources to
++ * complete the handshake.
++ */
++ btmtk_data->drv_name = btusb_driver.name;
++ btmtk_data->intf = data->intf;
++ btmtk_data->udev = data->udev;
++ btmtk_data->ctrl_anchor = &data->ctrl_anchor;
++ btmtk_data->reset_sync = btusb_mtk_reset;
+
+- return 0;
++ return btmtk_usb_setup(hdev);
+ }
+
+ static int btusb_mtk_shutdown(struct hci_dev *hdev)
+ {
+- struct btmtk_hci_wmt_params wmt_params;
+- u8 param = 0;
+- int err;
+-
+- /* Disable the device */
+- wmt_params.op = BTMTK_WMT_FUNC_CTRL;
+- wmt_params.flag = 0;
+- wmt_params.dlen = sizeof(param);
+- wmt_params.data = ¶m;
+- wmt_params.status = NULL;
+-
+- err = btmtk_usb_hci_wmt_sync(hdev, &wmt_params);
+- if (err < 0) {
+- bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
+- return err;
+- }
+-
+- return 0;
++ return btmtk_usb_shutdown(hdev);
+ }
+
+ static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb)
+--
+2.53.0
+
--- /dev/null
+From 982f08ceb2462f927e8d41e7ec225b0788da2197 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 May 2024 16:15:21 -0700
+Subject: Bluetooth: btusb: mediatek: add MT7922 subsystem reset
+
+From: Hao Qin <hao.qin@mediatek.com>
+
+[ Upstream commit 064aee501012eaeeeb40a2acb991598e0a89fac9 ]
+
+Add the support of MT7922 bluetooth subsystem reset that was called the
+auto revert to self-recover from the fatal error in the controller like
+the host encounters HCI cmd timeout or the controller crashes.
+
+Co-developed-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Hao Qin <hao.qin@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 5c5e8c52e3ca ("Bluetooth: btmtk: move btusb_mtk_[setup, shutdown] to btmtk.c")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index c6b62437be2d5a..536b013ff7aedc 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2811,7 +2811,16 @@ static int btusb_mtk_subsys_reset(struct hci_dev *hdev, u32 dev_id)
+ u32 val;
+ int err;
+
+- if (dev_id == 0x7925) {
++ if (dev_id == 0x7922) {
++ btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
++ val |= 0x00002020;
++ btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, val);
++ btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, 0x00010001);
++ btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
++ val |= BIT(0);
++ btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, val);
++ msleep(100);
++ } else if (dev_id == 0x7925) {
+ btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
+ val |= (1 << 5);
+ btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
+@@ -2851,6 +2860,9 @@ static int btusb_mtk_subsys_reset(struct hci_dev *hdev, u32 dev_id)
+ if (err < 0)
+ bt_dev_err(hdev, "Reset timeout");
+
++ if (dev_id == 0x7922)
++ btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
++
+ btusb_mtk_id_get(data, 0x70010200, &val);
+ if (!val)
+ bt_dev_err(hdev, "Can't get device id, subsys reset fail.");
+--
+2.53.0
+
--- /dev/null
+From f1b28e823a220da7cedadd038c345550d208bc31 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jul 2024 14:01:09 +0800
+Subject: Bluetooth: btusb: mediatek: remove the unnecessary goto tag
+
+From: Chris Lu <chris.lu@mediatek.com>
+
+[ Upstream commit be71dfb9ad2042bba713975ef50c3a5b0429f1d2 ]
+
+Remove the unnecessary goto tag whether there is an error or not, we have
+to free the buffer at the end of the function.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 5c5e8c52e3ca ("Bluetooth: btmtk: move btusb_mtk_[setup, shutdown] to btmtk.c")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 536b013ff7aedc..926ca7ecaf0cc2 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2725,12 +2725,9 @@ static int btusb_mtk_uhw_reg_write(struct btusb_data *data, u32 reg, u32 val)
+ 0x5E,
+ reg >> 16, reg & 0xffff,
+ buf, 4, USB_CTRL_SET_TIMEOUT);
+- if (err < 0) {
++ if (err < 0)
+ bt_dev_err(hdev, "Failed to write uhw reg(%d)", err);
+- goto err_free_buf;
+- }
+
+-err_free_buf:
+ kfree(buf);
+
+ return err;
+--
+2.53.0
+
--- /dev/null
+From fcba7a18c7e71c97132a18b6c1c00b92478b9f2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 15 May 2024 16:15:20 -0700
+Subject: Bluetooth: btusb: mediatek: reset the controller before downloading
+ the fw
+
+From: Hao Qin <hao.qin@mediatek.com>
+
+[ Upstream commit ccfc8948d7e4d93cab341a99774b24586717d89a ]
+
+Reset the controller before downloading the firmware to improve its
+reliability. This includes situations like cold or warm reboots, ensuring
+the controller is in its initial state before starting the firmware
+download.
+
+Co-developed-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Co-developed-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Hao Qin <hao.qin@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 5c5e8c52e3ca ("Bluetooth: btmtk: move btusb_mtk_[setup, shutdown] to btmtk.c")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 048929e336cf64..c6b62437be2d5a 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2940,6 +2940,13 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
+ case 0x7922:
+ case 0x7961:
+ case 0x7925:
++ /* Reset the device to ensure it's in the initial state before
++ * downloading the firmware to ensure.
++ */
++
++ if (!test_bit(BTUSB_FIRMWARE_LOADED, &data->flags))
++ btusb_mtk_subsys_reset(hdev, dev_id);
++
+ btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id,
+ fw_version, 0);
+
+@@ -2947,9 +2954,12 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
+ btmtk_usb_hci_wmt_sync);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to set up firmware (%d)", err);
++ clear_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
+ return err;
+ }
+
++ set_bit(BTUSB_FIRMWARE_LOADED, &data->flags);
++
+ /* It's Device EndPoint Reset Option Register */
+ btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT);
+
+--
+2.53.0
+
--- /dev/null
+From fb216845a1f75902455659c299e00c15cf027783 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jul 2024 14:01:10 +0800
+Subject: Bluetooth: btusb: mediatek: return error for failed reg access
+
+From: Chris Lu <chris.lu@mediatek.com>
+
+[ Upstream commit 3dcb122b30643444352ff4b9aa16367dd24d7571 ]
+
+Update the code to immediately return an error code if accessing a
+related register fails. This ensures that our desired logic for
+subsequent register operations is maintained and allows us to promptly
+catch any unexpected errors.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Chris Lu <chris.lu@mediatek.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: 5c5e8c52e3ca ("Bluetooth: btmtk: move btusb_mtk_[setup, shutdown] to btmtk.c")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 114 ++++++++++++++++++++++++++++----------
+ 1 file changed, 84 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 926ca7ecaf0cc2..a7aa4c1dacb295 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2809,47 +2809,98 @@ static int btusb_mtk_subsys_reset(struct hci_dev *hdev, u32 dev_id)
+ int err;
+
+ if (dev_id == 0x7922) {
+- btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
++ err = btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
++ if (err < 0)
++ return err;
+ val |= 0x00002020;
+- btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, val);
+- btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, 0x00010001);
+- btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
++ err = btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, val);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, 0x00010001);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
++ if (err < 0)
++ return err;
+ val |= BIT(0);
+- btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, val);
++ err = btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, val);
++ if (err < 0)
++ return err;
+ msleep(100);
+ } else if (dev_id == 0x7925) {
+- btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
++ err = btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
++ if (err < 0)
++ return err;
+ val |= (1 << 5);
+- btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
+- btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
++ err = btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
++ if (err < 0)
++ return err;
+ val &= 0xFFFF00FF;
++ if (err < 0)
++ return err;
+ val |= (1 << 13);
+- btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
+- btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, 0x00010001);
+- btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
++ err = btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, 0x00010001);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_read(data, MTK_BT_RESET_REG_CONNV3, &val);
++ if (err < 0)
++ return err;
+ val |= (1 << 0);
+- btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
+- btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
+- btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val);
+- btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF);
+- btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val);
++ err = btusb_mtk_uhw_reg_write(data, MTK_BT_RESET_REG_CONNV3, val);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val);
++ if (err < 0)
++ return err;
+ msleep(100);
+ } else {
+ /* It's Device EndPoint Reset Option Register */
+ bt_dev_dbg(hdev, "Initiating reset mechanism via uhw");
+- btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT);
+- btusb_mtk_uhw_reg_read(data, MTK_BT_WDT_STATUS, &val);
+-
++ err = btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_read(data, MTK_BT_WDT_STATUS, &val);
++ if (err < 0)
++ return err;
+ /* Reset the bluetooth chip via USB interface. */
+- btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 1);
+- btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
+- btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val);
+- btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF);
+- btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val);
++ err = btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 1);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT, &val);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT1, 0x000000FF);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_read(data, MTK_UDMA_INT_STA_BT1, &val);
++ if (err < 0)
++ return err;
+ /* MT7921 need to delay 20ms between toggle reset bit */
+ msleep(20);
+- btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0);
+- btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
++ err = btusb_mtk_uhw_reg_write(data, MTK_BT_SUBSYS_RST, 0);
++ if (err < 0)
++ return err;
++ err = btusb_mtk_uhw_reg_read(data, MTK_BT_SUBSYS_RST, &val);
++ if (err < 0)
++ return err;
+ }
+
+ err = readx_poll_timeout(btusb_mtk_reset_done, hdev, val,
+@@ -2857,11 +2908,14 @@ static int btusb_mtk_subsys_reset(struct hci_dev *hdev, u32 dev_id)
+ if (err < 0)
+ bt_dev_err(hdev, "Reset timeout");
+
+- if (dev_id == 0x7922)
+- btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
++ if (dev_id == 0x7922) {
++ err = btusb_mtk_uhw_reg_write(data, MTK_UDMA_INT_STA_BT, 0x000000FF);
++ if (err < 0)
++ return err;
++ }
+
+- btusb_mtk_id_get(data, 0x70010200, &val);
+- if (!val)
++ err = btusb_mtk_id_get(data, 0x70010200, &val);
++ if (err < 0 || !val)
+ bt_dev_err(hdev, "Can't get device id, subsys reset fail.");
+
+ return err;
+--
+2.53.0
+
--- /dev/null
+From 84a8c19bd0ce8045a4f7f5527a324cfb8a694904 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 10:35:32 +0800
+Subject: ext4: get rid of ppath in get_ext_path()
+
+From: Baokun Li <libaokun1@huawei.com>
+
+[ Upstream commit 6b854d552711aa33f59eda334e6d94a00d8825bb ]
+
+The use of path and ppath is now very confusing, so to make the code more
+readable, pass path between functions uniformly, and get rid of ppath.
+
+After getting rid of ppath in get_ext_path(), its caller may pass an error
+pointer to ext4_free_ext_path(), so it needs to teach ext4_free_ext_path()
+and ext4_ext_drop_refs() to skip the error pointer. No functional changes.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Tested-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Link: https://patch.msgid.link/20240822023545.1994557-13-libaokun@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/extents.c | 5 +++--
+ fs/ext4/move_extent.c | 34 +++++++++++++++++-----------------
+ 2 files changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index a94798e23c1afb..9c2d23958146bf 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -114,7 +114,7 @@ static void ext4_ext_drop_refs(struct ext4_ext_path *path)
+ {
+ int depth, i;
+
+- if (!path)
++ if (IS_ERR_OR_NULL(path))
+ return;
+ depth = path->p_depth;
+ for (i = 0; i <= depth; i++, path++) {
+@@ -125,6 +125,8 @@ static void ext4_ext_drop_refs(struct ext4_ext_path *path)
+
+ void ext4_free_ext_path(struct ext4_ext_path *path)
+ {
++ if (IS_ERR_OR_NULL(path))
++ return;
+ ext4_ext_drop_refs(path);
+ kfree(path);
+ }
+@@ -4242,7 +4244,6 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
+ path = ext4_find_extent(inode, map->m_lblk, NULL, 0);
+ if (IS_ERR(path)) {
+ err = PTR_ERR(path);
+- path = NULL;
+ goto out;
+ }
+
+diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
+index d5636a2a718a8d..96a84de321690d 100644
+--- a/fs/ext4/move_extent.c
++++ b/fs/ext4/move_extent.c
+@@ -17,27 +17,23 @@
+ * get_ext_path() - Find an extent path for designated logical block number.
+ * @inode: inode to be searched
+ * @lblock: logical block number to find an extent path
+- * @ppath: pointer to an extent path pointer (for output)
++ * @path: pointer to an extent path
+ *
+- * ext4_find_extent wrapper. Return 0 on success, or a negative error value
+- * on failure.
++ * ext4_find_extent wrapper. Return an extent path pointer on success,
++ * or an error pointer on failure.
+ */
+-static inline int
++static inline struct ext4_ext_path *
+ get_ext_path(struct inode *inode, ext4_lblk_t lblock,
+- struct ext4_ext_path **ppath)
++ struct ext4_ext_path *path)
+ {
+- struct ext4_ext_path *path = *ppath;
+-
+- *ppath = NULL;
+ path = ext4_find_extent(inode, lblock, path, EXT4_EX_NOCACHE);
+ if (IS_ERR(path))
+- return PTR_ERR(path);
++ return path;
+ if (path[ext_depth(inode)].p_ext == NULL) {
+ ext4_free_ext_path(path);
+- return -ENODATA;
++ return ERR_PTR(-ENODATA);
+ }
+- *ppath = path;
+- return 0;
++ return path;
+ }
+
+ /**
+@@ -95,9 +91,11 @@ mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count,
+ int ret = 0;
+ ext4_lblk_t last = from + count;
+ while (from < last) {
+- *err = get_ext_path(inode, from, &path);
+- if (*err)
+- goto out;
++ path = get_ext_path(inode, from, path);
++ if (IS_ERR(path)) {
++ *err = PTR_ERR(path);
++ return ret;
++ }
+ ext = path[ext_depth(inode)].p_ext;
+ if (unwritten != ext4_ext_is_unwritten(ext))
+ goto out;
+@@ -634,9 +632,11 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
+ int offset_in_page;
+ int unwritten, cur_len;
+
+- ret = get_ext_path(orig_inode, o_start, &path);
+- if (ret)
++ path = get_ext_path(orig_inode, o_start, path);
++ if (IS_ERR(path)) {
++ ret = PTR_ERR(path);
+ goto out;
++ }
+ ex = path[path->p_depth].p_ext;
+ cur_blk = le32_to_cpu(ex->ee_block);
+ cur_len = ext4_ext_get_actual_len(ex);
+--
+2.53.0
+
--- /dev/null
+From 9550f2749ed79cd29d7c7f68dcaff035e835d4eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 11:24:00 +0800
+Subject: LoongArch: Report dying CPU to RCU in stop_this_cpu()
+
+From: Huacai Chen <chenhuacai@loongson.cn>
+
+commit f2539c56c74691e7a88af6372ba2b48c06ed2fe4 upstream.
+
+This is a port of MIPS commit 9f3f3bdc6d9dac1 ("MIPS: smp: report dying
+CPU to RCU in stop_this_cpu()"). smp_send_stop() parks all secondary
+CPUs in stop_this_cpu(). And the function marks the CPU offline for the
+scheduler via set_cpu_online(false) but never informs RCU, so RCU keeps
+expecting a quiescent state from CPUs that are now spinning forever with
+interrupts disabled.
+
+As long as nothing waits for an RCU grace period after smp_send_stop()
+this is harmless, which is why it went unnoticed. However, since commit
+91840be8f710370 ("irq_work: Fix use-after-free in irq_work_single() on
+PREEMPT_RT"), irq_work_sync() calls synchronize_rcu() on architectures
+without an irq_work self-IPI, i.e. where arch_irq_work_has_interrupt()
+returns false. Any irq_work_sync() issued in the reboot/shutdown/halt
+path after smp_send_stop() then blocks on a grace period that can never
+complete, hanging the reboot:
+
+ WARNING: CPU: 0 PID: 15 at kernel/irq_work.c:144 irq_work_queue_on
+ ...
+ rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
+ rcu: Offline CPU 1 blocking current GP.
+ rcu: Offline CPU 2 blocking current GP.
+ rcu: Offline CPU 3 blocking current GP.
+
+This issue needs some hacks to reproduce, and it was not noticed on
+LoongArch because arch_irq_work_has_interrupt() usually returns true.
+
+Call rcutree_report_cpu_dead() once interrupts are disabled, mirroring
+the generic CPU-hotplug offline path, so RCU stops waiting on the parked
+CPUs and grace periods can still complete. LoongArch shuts down all CPUs
+here without going through the CPU-hotplug mechanism, so this report is
+not otherwise issued.
+
+Cc: <stable@vger.kernel.org>
+Fixes: 91840be8f710 ("irq_work: Fix use-after-free in irq_work_single() on PREEMPT_RT")
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/kernel/smp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
+index ed67629454374f..d3fafa5cdf6bc8 100644
+--- a/arch/loongarch/kernel/smp.c
++++ b/arch/loongarch/kernel/smp.c
+@@ -613,6 +613,7 @@ static void stop_this_cpu(void *dummy)
+ set_cpu_online(smp_processor_id(), false);
+ calculate_cpu_foreign_map();
+ local_irq_disable();
++ rcu_report_dead(smp_processor_id());
+ while (true);
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 758e60ccf99ed8315bf3ead7bcc511956af65e19 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 17:41:34 -0400
+Subject: nfsd: release layout stid on setlease failure
+
+From: Chris Mason <clm@meta.com>
+
+commit 30d55c8aabb261bc3f427d6b9aae7ef6206063f9 upstream.
+
+nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via
+idr_alloc_cyclic() under cl_lock before returning to
+nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then
+fails, the error path frees the layout stateid directly with
+kmem_cache_free() without ever calling idr_remove(), leaving the
+IDR slot pointing at freed slab memory. Any subsequent IDR walker
+(states_show, client teardown) dereferences the dangling pointer.
+
+The correct teardown for an IDR-published stid is nfs4_put_stid(),
+which removes the IDR slot under cl_lock, dispatches sc_free
+(nfsd4_free_layout_stateid) to release ls->ls_file via
+nfsd4_close_layout(), and drops the nfs4_file reference in its
+tail.
+
+A second issue blocks that switch: nfsd4_free_layout_stateid()
+unconditionally inspects ls->ls_fence_work via
+delayed_work_pending() under ls_lock, but
+INIT_DELAYED_WORK(&ls->ls_fence_work, ...) currently runs only
+after the setlease call. On the setlease-failure path the
+destructor would touch an uninitialized delayed_work.
+
+ nfsd4_alloc_layout_stateid()
+ nfs4_alloc_stid() /* idr_alloc_cyclic under cl_lock */
+ nfsd4_layout_setlease() /* fails */
+ nfs4_put_stid()
+ nfsd4_free_layout_stateid()
+ delayed_work_pending(&ls->ls_fence_work) /* needs INIT */
+ nfsd4_close_layout() /* nfsd_file_put(ls->ls_file) */
+ put_nfs4_file()
+
+Fix by hoisting the ls_fenced / ls_fence_delay / INIT_DELAYED_WORK
+initialization above the nfsd4_layout_setlease() call, and replace
+the manual nfsd_file_put + put_nfs4_file + kmem_cache_free cleanup
+with a single nfs4_put_stid(stp).
+
+Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls")
+Cc: stable@vger.kernel.org
+Assisted-by: kres (claude-opus-4-7)
+Signed-off-by: Chris Mason <clm@meta.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: no ls_fence_work in 6.6.y; dropped INIT_DELAYED_WORK hunk ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4layouts.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
+index 308214378fd352..84bb200e24adea 100644
+--- a/fs/nfsd/nfs4layouts.c
++++ b/fs/nfsd/nfs4layouts.c
+@@ -242,9 +242,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
+ BUG_ON(!ls->ls_file);
+
+ if (nfsd4_layout_setlease(ls)) {
+- nfsd_file_put(ls->ls_file);
+- put_nfs4_file(fp);
+- kmem_cache_free(nfs4_layout_stateid_cache, ls);
++ nfs4_put_stid(stp);
+ return NULL;
+ }
+
+--
+2.53.0
+
--- /dev/null
+From 37cec347e1b38e8e4dae313e3a0e98812790469a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 17:41:35 -0400
+Subject: nfsd: reset write verifier on deferred writeback errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit 2090b05803faab8a9fa62fbff871007862cac1b7 upstream.
+
+nfsd_vfs_write() and nfsd_commit() both call filemap_check_wb_err() to
+detect deferred writeback errors, but neither rotates the server's write
+verifier (nn->writeverf) when this check fails. Every other
+durable-storage-failure path in these functions calls
+commit_reset_write_verifier() before returning an error.
+
+The missing rotation means clients holding UNSTABLE write data under the
+current verifier will COMMIT, receive the unchanged verifier back, and
+conclude their data is durable — silently dropping data that failed
+writeback. This violates the UNSTABLE+COMMIT durability contract
+(RFC 1813 §3.3.7, RFC 8881 §18.32).
+
+Add commit_reset_write_verifier() calls at both filemap_check_wb_err()
+error sites, matching the pattern used by adjacent error paths in the
+same functions. The helper already filters -EAGAIN and -ESTALE
+internally, so the calls are unconditionally safe.
+
+Reported-by: Chris Mason <clm@meta.com>
+Fixes: 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t")
+Cc: stable@vger.kernel.org
+Assisted-by: kres:claude-opus-4-6
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+[ cel: 6.6.y predates the commit_reset_write_verifier() helper (v6.7);
+ open-coded nfsd_reset_write_verifier() and the reset tracepoint at
+ both sites, matching the other reset paths in these functions ]
+Signed-off-by: Chuck Lever <cel@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/vfs.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index ae1f43eb515a81..6658c92340f20b 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -1185,8 +1185,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
+ nfsd_stats_io_write_add(nn, exp, *cnt);
+ fsnotify_modify(file);
+ host_err = filemap_check_wb_err(file->f_mapping, since);
+- if (host_err < 0)
++ if (host_err < 0) {
++ nfsd_reset_write_verifier(nn);
++ trace_nfsd_writeverf_reset(nn, rqstp, host_err);
+ goto out_nfserr;
++ }
+
+ if (stable && use_wgather) {
+ host_err = wait_for_concurrent_writes(file);
+@@ -1330,6 +1333,10 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
+ nfsd_copy_write_verifier(verf, nn);
+ err2 = filemap_check_wb_err(nf->nf_file->f_mapping,
+ since);
++ if (err2 < 0) {
++ nfsd_reset_write_verifier(nn);
++ trace_nfsd_writeverf_reset(nn, rqstp, err2);
++ }
+ err = nfserrno(err2);
+ break;
+ case -EINVAL:
+--
+2.53.0
+
--- /dev/null
+From 24c5bb00ce525cdc1b995f82bcfadc551a7d9f58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Jul 2026 00:45:54 +0800
+Subject: perf: Fix dangling cgroup pointer in cpuctx backport
+
+From: Wentao Guan <guanwentao@uniontech.com>
+
+recently backport of ("perf: Fix dangling cgroup pointer in cpuctx")
+use a middle version, so aligned with the upstream commit:
+commit 3b7a34aebbdf ("perf: Fix dangling cgroup pointer in cpuctx")
+
+This is a fix for stable v6.6.143 backport commit, so no upstream commit.
+
+Link: https://lore.kernel.org/all/2026070200-uneaten-smock-4130@gregkh/
+Fixes: ae1ada0af162 ("perf: Fix dangling cgroup pointer in cpuctx")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/events/core.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index a4187dea6402a7..73a86db06cc9b1 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -2384,10 +2384,9 @@ __perf_remove_from_context(struct perf_event *event,
+ */
+ if (flags & DETACH_EXIT)
+ state = PERF_EVENT_STATE_EXIT;
+- if (flags & DETACH_DEAD) {
+- event->pending_disable = 1;
++ if (flags & DETACH_DEAD)
+ state = PERF_EVENT_STATE_DEAD;
+- }
++
+ event_sched_out(event, ctx);
+
+ if (event->state > PERF_EVENT_STATE_OFF)
+--
+2.53.0
+
bpf-arm64-reject-out-of-range-b.cond-targets.patch
+nfsd-release-layout-stid-on-setlease-failure.patch
+nfsd-reset-write-verifier-on-deferred-writeback-erro.patch
+ext4-get-rid-of-ppath-in-get_ext_path.patch
+loongarch-report-dying-cpu-to-rcu-in-stop_this_cpu.patch
+bluetooth-btmtk-apply-the-common-btmtk_fw_get_filena.patch
+bluetooth-btusb-mediatek-reset-the-controller-before.patch
+bluetooth-btusb-mediatek-add-mt7922-subsystem-reset.patch
+bluetooth-btusb-mediatek-remove-the-unnecessary-goto.patch
+bluetooth-btusb-mediatek-return-error-for-failed-reg.patch
+bluetooth-btmtk-move-btusb_mtk_-setup-shutdown-to-bt.patch
+bluetooth-btmtk-fix-failed-to-send-func-ctrl-for-med.patch
+bluetooth-btmtk-fix-wait_on_bit_timeout-interruption.patch
+userfaultfd-gate-must_wait-writability-check-on-pte_.patch
+perf-fix-dangling-cgroup-pointer-in-cpuctx-backport.patch
+bluetooth-btmtk-fix-btmtk.c-undefined-reference-buil.patch
--- /dev/null
+From 439676060e94503bfd25997db4fb954eda74311f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:49:04 +0100
+Subject: userfaultfd: gate must_wait writability check on pte_present()
+
+From: Kiryl Shutsemau <kas@kernel.org>
+
+[ Upstream commit 8e80af52db652fbc41320eee45a4f73bc029faf2 ]
+
+userfaultfd_must_wait() and userfaultfd_huge_must_wait() read the PTE
+without taking the page table lock and then apply pte_write() /
+huge_pte_write() to it. Those accessors decode bits from the present
+encoding only; on a swap or migration entry they read the offset bits that
+happen to share the same position and return an undefined result.
+
+The intent of the check is "is this fault still WP-blocked?". A
+non-marker swap entry means the page is in transit -- the userfault
+context the original fault delivered against is no longer the same, and
+the swap-in or migration completion path will re-deliver a fresh fault if
+userspace still needs to handle it. Worst case under the current code the
+garbage write bit says "wait", and the thread stays asleep until a
+UFFDIO_WAKE that may never arrive.
+
+Gate the writability check on pte_present() so the lockless re-check only
+inspects present-PTE bits when the entry is actually present. The
+non-present, non-marker case returns "don't wait" and lets the fault path
+retry.
+
+Link: https://lore.kernel.org/20260529172331.356655-6-kas@kernel.org
+Fixes: 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges")
+Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+
+[ kas: apply to fs/userfaultfd.c and fold the pte_present()/
+ huge_pte_present() gate into the existing writability checks; this tree
+ predates the marker/return-style refactor of these functions ]
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/userfaultfd.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index 74c468cc432e7f..49f07426259818 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -300,7 +300,12 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
+ */
+ if (huge_pte_none_mostly(pte))
+ ret = true;
+- if (!huge_pte_write(pte) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): huge_pte_write() on a
++ * non-present migration entry decodes random offset bits. The
++ * migration completion path re-delivers the fault if still needed.
++ */
++ if (pte_present(pte) && !huge_pte_write(pte) && (reason & VM_UFFD_WP))
+ ret = true;
+ out:
+ return ret;
+@@ -375,7 +380,12 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
+ ptent = ptep_get(pte);
+ if (pte_none_mostly(ptent))
+ ret = true;
+- if (!pte_write(ptent) && (reason & VM_UFFD_WP))
++ /*
++ * Gate the writability check on pte_present(): pte_write() on a
++ * non-present swap/migration entry decodes random offset bits. The
++ * page-in path re-delivers the fault if it still needs userspace.
++ */
++ if (pte_present(ptent) && !pte_write(ptent) && (reason & VM_UFFD_WP))
+ ret = true;
+ pte_unmap(pte);
+
+--
+2.53.0
+
--- /dev/null
+From ea519a7176053ec52a11367b7d72cbf92a7a79d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Jun 2026 07:15:17 -0700
+Subject: kernel/fork: clear PF_BLOCK_TS in copy_process()
+
+From: Usama Arif <usama.arif@linux.dev>
+
+[ Upstream commit fd38b75c4b43295b10d69772a46d1c74dbd6fc81 ]
+
+PF_BLOCK_TS is only set in blk_time_get_ns() when current->plug is
+non-NULL, and blk_finish_plug() clears it via __blk_flush_plug()
+before NULLing the plug pointer. copy_process() breaks the
+invariant by inheriting PF_BLOCK_TS from the parent while resetting
+the child's plug to NULL.
+
+Clear PF_BLOCK_TS alongside that assignment so callers can rely on
+"PF_BLOCK_TS set implies current->plug != NULL" and dereference
+current->plug unguarded.
+
+Fixes: 06b23f92af87 ("block: update cached timestamp post schedule/preemption")
+Cc: stable@vger.kernel.org
+Signed-off-by: Usama Arif <usama.arif@linux.dev>
+Link: https://patch.msgid.link/20260616141604.328820-2-usama.arif@linux.dev
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/fork.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 8ac38beae360b4..145bcc4c8e125e 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -2314,6 +2314,7 @@ __latent_entropy struct task_struct *copy_process(
+
+ #ifdef CONFIG_BLOCK
+ p->plug = NULL;
++ p->flags &= ~PF_BLOCK_TS;
+ #endif
+ futex_init_task(p);
+
+--
+2.53.0
+
--- /dev/null
+From 6a73384b2aa8b63997ea8be8b26439d785601b70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 12:41:52 +0200
+Subject: rust: str: clean unused import for Rust >= 1.98
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit 3fff4271809b57182c4011811e96556bdd4cb2f9 ]
+
+Starting with Rust 1.98.0 (expected 2026-08-20), the compiler has changed
+how the resolution algorithm works [1] in upstream commit c4d84db5f184
+("Resolver: Batched import resolution."), and it now spots:
+
+ error: unused import: `flags::*`
+ --> rust/kernel/str.rs:7:9
+ |
+ 7 | flags::*,
+ | ^^^^^^^^
+ |
+ = note: `-D unused-imports` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(unused_imports)]`
+
+It happens to not be needed because the `prelude::*` already provides
+the flags.
+
+Thus clean it up.
+
+Cc: stable@vger.kernel.org # Needed in 6.18.y and later (prelude added to `str`).
+Link: https://github.com/rust-lang/rust/pull/145108 [1]
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Reviewed-by: Alice Ryhl <aliceryhl@google.com>
+Link: https://patch.msgid.link/20260609104152.261145-2-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/str.rs | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
+index a7fccd4c4f3b18..4517c1bc547afb 100644
+--- a/rust/kernel/str.rs
++++ b/rust/kernel/str.rs
+@@ -4,7 +4,6 @@
+
+ use crate::{
+ alloc::{
+- flags::*,
+ AllocError,
+ KVec, //
+ },
+--
+2.53.0
+
--- /dev/null
+From 815c2486403f4adaede654c21a3a69ba390cb45a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jun 2026 12:41:51 +0200
+Subject: rust: str: use the "kernel vertical" imports style
+
+From: Miguel Ojeda <ojeda@kernel.org>
+
+[ Upstream commit 724a93a9f6033800b02a3530dbcb464638448e7f ]
+
+Convert the imports to use the "kernel vertical" imports style [1].
+
+No functional changes intended.
+
+Link: https://docs.kernel.org/rust/coding-guidelines.html#imports [1]
+Reviewed-by: Gary Guo <gary@garyguo.net>
+Link: https://patch.msgid.link/20260609104152.261145-1-ojeda@kernel.org
+Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
+Stable-dep-of: 3fff4271809b ("rust: str: clean unused import for Rust >= 1.98")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ rust/kernel/str.rs | 24 +++++++++++++++++++-----
+ 1 file changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
+index 8311d91549e15e..a7fccd4c4f3b18 100644
+--- a/rust/kernel/str.rs
++++ b/rust/kernel/str.rs
+@@ -3,14 +3,28 @@
+ //! String representations.
+
+ use crate::{
+- alloc::{flags::*, AllocError, KVec},
+- error::{to_result, Result},
+- fmt::{self, Write},
+- prelude::*,
++ alloc::{
++ flags::*,
++ AllocError,
++ KVec, //
++ },
++ error::{
++ to_result,
++ Result, //
++ },
++ fmt::{
++ self,
++ Write, //
++ },
++ prelude::*, //
+ };
+ use core::{
+ marker::PhantomData,
+- ops::{Deref, DerefMut, Index},
++ ops::{
++ Deref,
++ DerefMut,
++ Index, //
++ }, //
+ };
+
+ pub use crate::prelude::CStr;
+--
+2.53.0
+
--- /dev/null
+kernel-fork-clear-pf_block_ts-in-copy_process.patch
+rust-str-use-the-kernel-vertical-imports-style.patch
+rust-str-clean-unused-import-for-rust-1.98.patch
+userfaultfd-gate-must_wait-writability-check-on-pte_.patch
--- /dev/null
+From f4d83edd6af9af54985fb054ad39798d13d7d63e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Jul 2026 16:49:08 +0100
+Subject: userfaultfd: gate must_wait writability check on pte_present()
+
+From: Kiryl Shutsemau <kas@kernel.org>
+
+[ Upstream commit 8e80af52db652fbc41320eee45a4f73bc029faf2 ]
+
+userfaultfd_must_wait() and userfaultfd_huge_must_wait() read the PTE
+without taking the page table lock and then apply pte_write() /
+huge_pte_write() to it. Those accessors decode bits from the present
+encoding only; on a swap or migration entry they read the offset bits that
+happen to share the same position and return an undefined result.
+
+The intent of the check is "is this fault still WP-blocked?". A
+non-marker swap entry means the page is in transit -- the userfault
+context the original fault delivered against is no longer the same, and
+the swap-in or migration completion path will re-deliver a fresh fault if
+userspace still needs to handle it. Worst case under the current code the
+garbage write bit says "wait", and the thread stays asleep until a
+UFFDIO_WAKE that may never arrive.
+
+Gate the writability check on pte_present() so the lockless re-check only
+inspects present-PTE bits when the entry is actually present. The
+non-present, non-marker case returns "don't wait" and lets the fault path
+retry.
+
+Link: https://lore.kernel.org/20260529172331.356655-6-kas@kernel.org
+Fixes: 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges")
+Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
+Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: Balbir Singh <balbirs@nvidia.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+
+[ kas: apply to fs/userfaultfd.c; these checks moved to mm/userfaultfd.c
+ only after 7.1, the change is otherwise identical to upstream ]
+Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/userfaultfd.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index 390e4b7d9cb9fa..dba1172436b745 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -253,6 +253,15 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
+ /* UFFD PTE markers require userspace to resolve the fault. */
+ if (pte_is_uffd_marker(pte))
+ return true;
++ /*
++ * Concurrent migration may have replaced the present PTE with a
++ * non-marker swap entry between fault delivery and this lockless
++ * re-check. huge_pte_write() on a swap entry decodes random offset
++ * bits, so gate it on pte_present(). The migration completion path
++ * will re-deliver the fault if it still needs userspace.
++ */
++ if (!pte_present(pte))
++ return false;
+ /*
+ * If VMA has UFFD WP faults enabled and WP fault, wait for userspace to
+ * resolve the fault.
+@@ -339,6 +348,17 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
+ /* UFFD PTE markers require userspace to resolve the fault. */
+ if (pte_is_uffd_marker(ptent))
+ goto out;
++ /*
++ * Concurrent swap-out / migration may have replaced the present PTE
++ * with a non-marker swap entry between fault delivery and this
++ * lockless re-check. pte_write() on a swap entry decodes random
++ * offset bits, so gate it on pte_present(). The page-in path will
++ * re-deliver the fault if it still needs userspace.
++ */
++ if (!pte_present(ptent)) {
++ ret = false;
++ goto out;
++ }
+ /*
+ * If VMA has UFFD WP faults enabled and WP fault, wait for userspace to
+ * resolve the fault.
+--
+2.53.0
+