+++ /dev/null
-From facf7db52fc5f02c2656c481b8e0438de2d21a34 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 11 Jun 2025 19:48:25 +0200
-Subject: rust: devres: do not dereference to the internal Revocable
-
-From: Danilo Krummrich <dakr@kernel.org>
-
-[ Upstream commit 20c96ed278e362ae4e324ed7d8c69fb48c508d3c ]
-
-We can't expose direct access to the internal Revocable, since this
-allows users to directly revoke the internal Revocable without Devres
-having the chance to synchronize with the devres callback -- we have to
-guarantee that the internal Revocable has been fully revoked before
-the device is fully unbound.
-
-Hence, remove the corresponding Deref implementation and, instead,
-provide indirect accessors for the internal Revocable.
-
-Note that we can still support Devres::revoke() by implementing the
-required synchronization (which would be almost identical to the
-synchronization in Devres::drop()).
-
-Fixes: 76c01ded724b ("rust: add devres abstraction")
-Reviewed-by: Benno Lossin <lossin@kernel.org>
-Link: https://lore.kernel.org/r/20250611174827.380555-1-dakr@kernel.org
-Signed-off-by: Danilo Krummrich <dakr@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- rust/kernel/devres.rs | 27 ++++++++++++++++-----------
- 1 file changed, 16 insertions(+), 11 deletions(-)
-
-diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
-index acb8e1d13ddd9..5f1a7be2ed512 100644
---- a/rust/kernel/devres.rs
-+++ b/rust/kernel/devres.rs
-@@ -12,13 +12,11 @@
- error::{Error, Result},
- ffi::c_void,
- prelude::*,
-- revocable::Revocable,
-- sync::{Arc, Completion},
-+ revocable::{Revocable, RevocableGuard},
-+ sync::{rcu, Arc, Completion},
- types::ARef,
- };
-
--use core::ops::Deref;
--
- #[pin_data]
- struct DevresInner<T> {
- dev: ARef<Device>,
-@@ -232,15 +230,22 @@ pub fn access<'a>(&'a self, dev: &'a Device<Bound>) -> Result<&'a T> {
- // SAFETY: `dev` being the same device as the device this `Devres` has been created for
- // proves that `self.0.data` hasn't been revoked and is guaranteed to not be revoked as
- // long as `dev` lives; `dev` lives at least as long as `self`.
-- Ok(unsafe { self.deref().access() })
-+ Ok(unsafe { self.0.data.access() })
- }
--}
-
--impl<T> Deref for Devres<T> {
-- type Target = Revocable<T>;
-+ /// [`Devres`] accessor for [`Revocable::try_access`].
-+ pub fn try_access(&self) -> Option<RevocableGuard<'_, T>> {
-+ self.0.data.try_access()
-+ }
-+
-+ /// [`Devres`] accessor for [`Revocable::try_access_with`].
-+ pub fn try_access_with<R, F: FnOnce(&T) -> R>(&self, f: F) -> Option<R> {
-+ self.0.data.try_access_with(f)
-+ }
-
-- fn deref(&self) -> &Self::Target {
-- &self.0.data
-+ /// [`Devres`] accessor for [`Revocable::try_access_with_guard`].
-+ pub fn try_access_with_guard<'a>(&'a self, guard: &'a rcu::Guard) -> Option<&'a T> {
-+ self.0.data.try_access_with_guard(guard)
- }
- }
-
-@@ -248,7 +253,7 @@ impl<T> Drop for Devres<T> {
- fn drop(&mut self) {
- // SAFETY: When `drop` runs, it is guaranteed that nobody is accessing the revocable data
- // anymore, hence it is safe not to wait for the grace period to finish.
-- if unsafe { self.revoke_nosync() } {
-+ if unsafe { self.0.data.revoke_nosync() } {
- // We revoked `self.0.data` before the devres action did, hence try to remove it.
- if !DevresInner::remove_action(&self.0) {
- // We could not remove the devres action, which means that it now runs concurrently,
---
-2.39.5
-
+++ /dev/null
-From 42055939a3a4cac8afbebff85a29571c2bd3238c Mon Sep 17 00:00:00 2001
-From: Miguel Ojeda <ojeda@kernel.org>
-Date: Sun, 11 May 2025 20:25:33 +0200
-Subject: rust: devres: fix doctest build under `!CONFIG_PCI`
-
-From: Miguel Ojeda <ojeda@kernel.org>
-
-commit 42055939a3a4cac8afbebff85a29571c2bd3238c upstream.
-
-The doctest requires `CONFIG_PCI`:
-
- error[E0432]: unresolved import `kernel::pci`
- --> rust/doctests_kernel_generated.rs:2689:44
- |
- 2689 | use kernel::{device::Core, devres::Devres, pci};
- | ^^^ no `pci` in the root
- |
- note: found an item that was configured out
- --> rust/kernel/lib.rs:96:9
- note: the item is gated here
- --> rust/kernel/lib.rs:95:1
-
-Thus conditionally compile it (which still checks the syntax).
-
-Fixes: f301cb978c06 ("rust: devres: implement Devres::access()")
-Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
-Link: https://lore.kernel.org/r/20250511182533.1016163-1-ojeda@kernel.org
-Signed-off-by: Danilo Krummrich <dakr@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- rust/kernel/devres.rs | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/rust/kernel/devres.rs
-+++ b/rust/kernel/devres.rs
-@@ -208,6 +208,7 @@ impl<T> Devres<T> {
- /// # Example
- ///
- /// ```no_run
-+ /// # #![cfg(CONFIG_PCI)]
- /// # use kernel::{device::Core, devres::Devres, pci};
- ///
- /// fn from_core(dev: &pci::Device<Core>, devres: Devres<pci::Bar<0x4>>) -> Result {
+++ /dev/null
-From 2ae36e7b63e3826ac02a631f6b209b7fbe13cda5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 12 Jun 2025 14:17:15 +0200
-Subject: rust: devres: fix race in Devres::drop()
-
-From: Danilo Krummrich <dakr@kernel.org>
-
-[ Upstream commit f744201c6159fc7323c40936fd079525f7063598 ]
-
-In Devres::drop() we first remove the devres action and then drop the
-wrapped device resource.
-
-The design goal is to give the owner of a Devres object control over when
-the device resource is dropped, but limit the overall scope to the
-corresponding device being bound to a driver.
-
-However, there's a race that was introduced with commit 8ff656643d30
-("rust: devres: remove action in `Devres::drop`"), but also has been
-(partially) present from the initial version on.
-
-In Devres::drop(), the devres action is removed successfully and
-subsequently the destructor of the wrapped device resource runs.
-However, there is no guarantee that the destructor of the wrapped device
-resource completes before the driver core is done unbinding the
-corresponding device.
-
-If in Devres::drop(), the devres action can't be removed, it means that
-the devres callback has been executed already, or is still running
-concurrently. In case of the latter, either Devres::drop() wins revoking
-the Revocable or the devres callback wins revoking the Revocable. If
-Devres::drop() wins, we (again) have no guarantee that the destructor of
-the wrapped device resource completes before the driver core is done
-unbinding the corresponding device.
-
-CPU0 CPU1
-------------------------------------------------------------------------
-Devres::drop() { Devres::devres_callback() {
- self.data.revoke() { this.data.revoke() {
- is_available.swap() == true
- is_available.swap == false
- }
- }
-
- // [...]
- // device fully unbound
- drop_in_place() {
- // release device resource
- }
- }
-}
-
-Depending on the specific device resource, this can potentially lead to
-user-after-free bugs.
-
-In order to fix this, implement the following logic.
-
-In the devres callback, we're always good when we get to revoke the
-device resource ourselves, i.e. Revocable::revoke() returns true.
-
-If Revocable::revoke() returns false, it means that Devres::drop(),
-concurrently, already drops the device resource and we have to wait for
-Devres::drop() to signal that it finished dropping the device resource.
-
-Note that if we hit the case where we need to wait for the completion of
-Devres::drop() in the devres callback, it means that we're actually
-racing with a concurrent Devres::drop() call, which already started
-revoking the device resource for us. This is rather unlikely and means
-that the concurrent Devres::drop() already started doing our work and we
-just need to wait for it to complete it for us. Hence, there should not
-be any additional overhead from that.
-
-(Actually, for now it's even better if Devres::drop() does the work for
-us, since it can bypass the synchronize_rcu() call implied by
-Revocable::revoke(), but this goes away anyways once I get to implement
-the split devres callback approach, which allows us to first flip the
-atomics of all registered Devres objects of a certain device, execute a
-single synchronize_rcu() and then drop all revocable objects.)
-
-In Devres::drop() we try to revoke the device resource. If that is *not*
-successful, it means that the devres callback already did and we're good.
-
-Otherwise, we try to remove the devres action, which, if successful,
-means that we're good, since the device resource has just been revoked
-by us *before* we removed the devres action successfully.
-
-If the devres action could not be removed, it means that the devres
-callback must be running concurrently, hence we signal that the device
-resource has been revoked by us, using the completion.
-
-This makes it safe to drop a Devres object from any task and at any point
-of time, which is one of the design goals.
-
-Fixes: 76c01ded724b ("rust: add devres abstraction")
-Reported-by: Alice Ryhl <aliceryhl@google.com>
-Closes: https://lore.kernel.org/lkml/aD64YNuqbPPZHAa5@google.com/
-Reviewed-by: Benno Lossin <lossin@kernel.org>
-Link: https://lore.kernel.org/r/20250612121817.1621-4-dakr@kernel.org
-Signed-off-by: Danilo Krummrich <dakr@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- rust/kernel/devres.rs | 37 +++++++++++++++++++++++++++++--------
- 1 file changed, 29 insertions(+), 8 deletions(-)
-
-diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
-index ddb1ce4a78d94..f3a4e3383b8d2 100644
---- a/rust/kernel/devres.rs
-+++ b/rust/kernel/devres.rs
-@@ -13,7 +13,7 @@
- ffi::c_void,
- prelude::*,
- revocable::Revocable,
-- sync::Arc,
-+ sync::{Arc, Completion},
- types::ARef,
- };
-
-@@ -25,13 +25,17 @@ struct DevresInner<T> {
- callback: unsafe extern "C" fn(*mut c_void),
- #[pin]
- data: Revocable<T>,
-+ #[pin]
-+ revoke: Completion,
- }
-
- /// This abstraction is meant to be used by subsystems to containerize [`Device`] bound resources to
- /// manage their lifetime.
- ///
- /// [`Device`] bound resources should be freed when either the resource goes out of scope or the
--/// [`Device`] is unbound respectively, depending on what happens first.
-+/// [`Device`] is unbound respectively, depending on what happens first. In any case, it is always
-+/// guaranteed that revoking the device resource is completed before the corresponding [`Device`]
-+/// is unbound.
- ///
- /// To achieve that [`Devres`] registers a devres callback on creation, which is called once the
- /// [`Device`] is unbound, revoking access to the encapsulated resource (see also [`Revocable`]).
-@@ -105,6 +109,7 @@ fn new(dev: &Device, data: T, flags: Flags) -> Result<Arc<DevresInner<T>>> {
- dev: dev.into(),
- callback: Self::devres_callback,
- data <- Revocable::new(data),
-+ revoke <- Completion::new(),
- }),
- flags,
- )?;
-@@ -133,26 +138,28 @@ fn as_ptr(&self) -> *const Self {
- self as _
- }
-
-- fn remove_action(this: &Arc<Self>) {
-+ fn remove_action(this: &Arc<Self>) -> bool {
- // SAFETY:
- // - `self.inner.dev` is a valid `Device`,
- // - the `action` and `data` pointers are the exact same ones as given to devm_add_action()
- // previously,
- // - `self` is always valid, even if the action has been released already.
-- let ret = unsafe {
-+ let success = unsafe {
- bindings::devm_remove_action_nowarn(
- this.dev.as_raw(),
- Some(this.callback),
- this.as_ptr() as _,
- )
-- };
-+ } == 0;
-
-- if ret == 0 {
-+ if success {
- // SAFETY: We leaked an `Arc` reference to devm_add_action() in `DevresInner::new`; if
- // devm_remove_action_nowarn() was successful we can (and have to) claim back ownership
- // of this reference.
- let _ = unsafe { Arc::from_raw(this.as_ptr()) };
- }
-+
-+ success
- }
-
- #[allow(clippy::missing_safety_doc)]
-@@ -164,7 +171,12 @@ fn remove_action(this: &Arc<Self>) {
- // `DevresInner::new`.
- let inner = unsafe { Arc::from_raw(ptr) };
-
-- inner.data.revoke();
-+ if !inner.data.revoke() {
-+ // If `revoke()` returns false, it means that `Devres::drop` already started revoking
-+ // `inner.data` for us. Hence we have to wait until `Devres::drop()` signals that it
-+ // completed revoking `inner.data`.
-+ inner.revoke.wait_for_completion();
-+ }
- }
- }
-
-@@ -196,6 +208,15 @@ fn deref(&self) -> &Self::Target {
-
- impl<T> Drop for Devres<T> {
- fn drop(&mut self) {
-- DevresInner::remove_action(&self.0);
-+ // SAFETY: When `drop` runs, it is guaranteed that nobody is accessing the revocable data
-+ // anymore, hence it is safe not to wait for the grace period to finish.
-+ if unsafe { self.revoke_nosync() } {
-+ // We revoked `self.0.data` before the devres action did, hence try to remove it.
-+ if !DevresInner::remove_action(&self.0) {
-+ // We could not remove the devres action, which means that it now runs concurrently,
-+ // hence signal that `self.0.data` has been revoked successfully.
-+ self.0.revoke.complete_all();
-+ }
-+ }
- }
- }
---
-2.39.5
-
+++ /dev/null
-From e9ec190d9683bcc4b1fe276c640b18cebd1bba45 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 28 Apr 2025 16:00:28 +0200
-Subject: rust: devres: implement Devres::access()
-
-From: Danilo Krummrich <dakr@kernel.org>
-
-[ Upstream commit f301cb978c068faa8fcd630be2cb317a2d0ec063 ]
-
-Implement a direct accessor for the data stored within the Devres for
-cases where we can prove that we own a reference to a Device<Bound>
-(i.e. a bound device) of the same device that was used to create the
-corresponding Devres container.
-
-Usually, when accessing the data stored within a Devres container, it is
-not clear whether the data has been revoked already due to the device
-being unbound and, hence, we have to try whether the access is possible
-and subsequently keep holding the RCU read lock for the duration of the
-access.
-
-However, when we can prove that we hold a reference to Device<Bound>
-matching the device the Devres container has been created with, we can
-guarantee that the device is not unbound for the duration of the
-lifetime of the Device<Bound> reference and, hence, it is not possible
-for the data within the Devres container to be revoked.
-
-Therefore, in this case, we can bypass the atomic check and the RCU read
-lock, which is a great optimization and simplification for drivers.
-
-Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com>
-Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
-Acked-by: Boqun Feng <boqun.feng@gmail.com>
-Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
-Link: https://lore.kernel.org/r/20250428140137.468709-3-dakr@kernel.org
-Signed-off-by: Danilo Krummrich <dakr@kernel.org>
-Stable-dep-of: 20c96ed278e3 ("rust: devres: do not dereference to the internal Revocable")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- rust/kernel/devres.rs | 38 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
-diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
-index f3a4e3383b8d2..acb8e1d13ddd9 100644
---- a/rust/kernel/devres.rs
-+++ b/rust/kernel/devres.rs
-@@ -196,6 +196,44 @@ pub fn new_foreign_owned(dev: &Device, data: T, flags: Flags) -> Result {
-
- Ok(())
- }
-+
-+ /// Obtain `&'a T`, bypassing the [`Revocable`].
-+ ///
-+ /// This method allows to directly obtain a `&'a T`, bypassing the [`Revocable`], by presenting
-+ /// a `&'a Device<Bound>` of the same [`Device`] this [`Devres`] instance has been created with.
-+ ///
-+ /// # Errors
-+ ///
-+ /// An error is returned if `dev` does not match the same [`Device`] this [`Devres`] instance
-+ /// has been created with.
-+ ///
-+ /// # Example
-+ ///
-+ /// ```no_run
-+ /// # use kernel::{device::Core, devres::Devres, pci};
-+ ///
-+ /// fn from_core(dev: &pci::Device<Core>, devres: Devres<pci::Bar<0x4>>) -> Result {
-+ /// let bar = devres.access(dev.as_ref())?;
-+ ///
-+ /// let _ = bar.read32(0x0);
-+ ///
-+ /// // might_sleep()
-+ ///
-+ /// bar.write32(0x42, 0x0);
-+ ///
-+ /// Ok(())
-+ /// }
-+ /// ```
-+ pub fn access<'a>(&'a self, dev: &'a Device<Bound>) -> Result<&'a T> {
-+ if self.0.dev.as_raw() != dev.as_raw() {
-+ return Err(EINVAL);
-+ }
-+
-+ // SAFETY: `dev` being the same device as the device this `Devres` has been created for
-+ // proves that `self.0.data` hasn't been revoked and is guaranteed to not be revoked as
-+ // long as `dev` lives; `dev` lives at least as long as `self`.
-+ Ok(unsafe { self.deref().access() })
-+ }
- }
-
- impl<T> Deref for Devres<T> {
---
-2.39.5
-
drm-nouveau-gsp-split-rpc-handling-out-on-its-own.patch
drm-nouveau-fix-a-use-after-free-in-r535_gsp_rpc_pus.patch
drm-nouveau-bl-increase-buffer-size-to-avoid-truncat.patch
-rust-devres-fix-race-in-devres-drop.patch
-rust-devres-implement-devres-access.patch
-rust-devres-do-not-dereference-to-the-internal-revoc.patch
drm-i915-pmu-fix-build-error-with-gcov-and-autofdo-e.patch
hwmon-occ-rework-attribute-registration-for-stack-us.patch
hwmon-occ-fix-unaligned-accesses.patch
smb-client-fix-max_sge-overflow-in-smb_extract_folioq_to_rdma.patch
edac-igen6-fix-null-pointer-dereference.patch
x86-its-fix-an-ifdef-typo-in-its_alloc.patch
-rust-devres-fix-doctest-build-under-config_pci.patch
dm-table-check-blk_feat_atomic_writes-inside-limits_lock.patch
tracing-do-not-free-head-on-error-path-of-filter_free_subsystem_filters.patch
documentation-nouveau-update-gsp-message-queue-kernel-doc-reference.patch