From: Greg Kroah-Hartman Date: Tue, 24 Jun 2025 10:03:41 +0000 (+0100) Subject: drop rust patches from 6.15 as they broke the build X-Git-Tag: v5.4.295~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2594fa410348b3e60d98ab0dedaf11787c8ef7a2;p=thirdparty%2Fkernel%2Fstable-queue.git drop rust patches from 6.15 as they broke the build --- diff --git a/queue-6.15/rust-devres-do-not-dereference-to-the-internal-revoc.patch b/queue-6.15/rust-devres-do-not-dereference-to-the-internal-revoc.patch deleted file mode 100644 index ca65a13b8a..0000000000 --- a/queue-6.15/rust-devres-do-not-dereference-to-the-internal-revoc.patch +++ /dev/null @@ -1,92 +0,0 @@ -From facf7db52fc5f02c2656c481b8e0438de2d21a34 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 11 Jun 2025 19:48:25 +0200 -Subject: rust: devres: do not dereference to the internal Revocable - -From: Danilo Krummrich - -[ 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 -Link: https://lore.kernel.org/r/20250611174827.380555-1-dakr@kernel.org -Signed-off-by: Danilo Krummrich -Signed-off-by: Sasha Levin ---- - 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 { - dev: ARef, -@@ -232,15 +230,22 @@ pub fn access<'a>(&'a self, dev: &'a Device) -> 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 Deref for Devres { -- type Target = Revocable; -+ /// [`Devres`] accessor for [`Revocable::try_access`]. -+ pub fn try_access(&self) -> Option> { -+ self.0.data.try_access() -+ } -+ -+ /// [`Devres`] accessor for [`Revocable::try_access_with`]. -+ pub fn try_access_with R>(&self, f: F) -> Option { -+ 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 Drop for Devres { - 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 - diff --git a/queue-6.15/rust-devres-fix-doctest-build-under-config_pci.patch b/queue-6.15/rust-devres-fix-doctest-build-under-config_pci.patch deleted file mode 100644 index 2702c471a3..0000000000 --- a/queue-6.15/rust-devres-fix-doctest-build-under-config_pci.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 42055939a3a4cac8afbebff85a29571c2bd3238c Mon Sep 17 00:00:00 2001 -From: Miguel Ojeda -Date: Sun, 11 May 2025 20:25:33 +0200 -Subject: rust: devres: fix doctest build under `!CONFIG_PCI` - -From: Miguel Ojeda - -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 -Link: https://lore.kernel.org/r/20250511182533.1016163-1-ojeda@kernel.org -Signed-off-by: Danilo Krummrich -Signed-off-by: Greg Kroah-Hartman ---- - 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 Devres { - /// # Example - /// - /// ```no_run -+ /// # #![cfg(CONFIG_PCI)] - /// # use kernel::{device::Core, devres::Devres, pci}; - /// - /// fn from_core(dev: &pci::Device, devres: Devres>) -> Result { diff --git a/queue-6.15/rust-devres-fix-race-in-devres-drop.patch b/queue-6.15/rust-devres-fix-race-in-devres-drop.patch deleted file mode 100644 index dfc4b7bd54..0000000000 --- a/queue-6.15/rust-devres-fix-race-in-devres-drop.patch +++ /dev/null @@ -1,210 +0,0 @@ -From 2ae36e7b63e3826ac02a631f6b209b7fbe13cda5 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 12 Jun 2025 14:17:15 +0200 -Subject: rust: devres: fix race in Devres::drop() - -From: Danilo Krummrich - -[ 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 -Closes: https://lore.kernel.org/lkml/aD64YNuqbPPZHAa5@google.com/ -Reviewed-by: Benno Lossin -Link: https://lore.kernel.org/r/20250612121817.1621-4-dakr@kernel.org -Signed-off-by: Danilo Krummrich -Signed-off-by: Sasha Levin ---- - 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 { - callback: unsafe extern "C" fn(*mut c_void), - #[pin] - data: Revocable, -+ #[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>> { - 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) { -+ fn remove_action(this: &Arc) -> 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) { - // `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 Drop for Devres { - 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 - diff --git a/queue-6.15/rust-devres-implement-devres-access.patch b/queue-6.15/rust-devres-implement-devres-access.patch deleted file mode 100644 index 3dd47d42b3..0000000000 --- a/queue-6.15/rust-devres-implement-devres-access.patch +++ /dev/null @@ -1,93 +0,0 @@ -From e9ec190d9683bcc4b1fe276c640b18cebd1bba45 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 28 Apr 2025 16:00:28 +0200 -Subject: rust: devres: implement Devres::access() - -From: Danilo Krummrich - -[ 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 -(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 -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 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 -Reviewed-by: Alexandre Courbot -Acked-by: Boqun Feng -Reviewed-by: Joel Fernandes -Link: https://lore.kernel.org/r/20250428140137.468709-3-dakr@kernel.org -Signed-off-by: Danilo Krummrich -Stable-dep-of: 20c96ed278e3 ("rust: devres: do not dereference to the internal Revocable") -Signed-off-by: Sasha Levin ---- - 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` 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, devres: Devres>) -> 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) -> 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 Deref for Devres { --- -2.39.5 - diff --git a/queue-6.15/series b/queue-6.15/series index 9ebfeea250..e49b790030 100644 --- a/queue-6.15/series +++ b/queue-6.15/series @@ -512,9 +512,6 @@ ionic-prevent-driver-fw-getting-out-of-sync-on-devcm.patch 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 @@ -564,7 +561,6 @@ smb-client-fix-first-command-failure-during-re-negotiation.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