summaryrefslogtreecommitdiff
path: root/rust/kernel
AgeCommit message (Collapse)Author
2025-07-16device: rust: rename Device::as_ref() to Device::from_raw()Alice Ryhl
The prefix as_* should not be used for a constructor. Constructors usually use the prefix from_* instead. Some prior art in the stdlib: Box::from_raw, CString::from_raw, Rc::from_raw, Arc::from_raw, Waker::from_raw, File::from_raw_fd. There is also prior art in the kernel crate: cpufreq::Policy::from_raw, fs::File::from_raw_file, Kuid::from_raw, ARef::from_raw, SeqFile::from_raw, VmaNew::from_raw, Io::from_raw. Link: https://lore.kernel.org/r/aCd8D5IA0RXZvtcv@pollux Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Benno Lossin <lossin@kernel.org> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Link: https://lore.kernel.org/r/20250711-device-as-ref-v2-1-1b16ab6402d7@google.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-15rust: device: implement Device::as_bound()Danilo Krummrich
Provide an unsafe functions for abstractions to convert a regular &Device to a &Device<Bound>. This is useful for registrations that provide certain guarantees for the scope of their callbacks, such as IRQs or certain class device registrations (e.g. PWM, miscdevice). Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250713182737.64448-2-dakr@kernel.org [ Remove unnecessary cast(). - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-15rust: devres: provide an accessor for the deviceDanilo Krummrich
Provide an accessor for the Device a Devres instance has been created with. For instance, this is useful when registrations want to provide a &Device<Bound> for a scope that is protected by Devres. Suggested-by: Benno Lossin <lossin@kernel.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250713182737.64448-1-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-15rust: devres: initialize Devres::inner::data lastDanilo Krummrich
Users may want to access the Devres object from callbacks registered through the initialization of Devres::inner::data. For those accesses to be valid, Devres::inner::data must be initialized last [1]. Credit to Boqun for spotting this [2]. Link: https://lore.kernel.org/lkml/DBBPHO26CPBS.2OVI1OERCB2J5@kernel.org/ [1] Link: https://lore.kernel.org/lkml/aHSmxWeIy3L-AKIV@Mac.home/ [2] Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250714113712.22158-1-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-09rust: pci: implement Driver::unbind()Danilo Krummrich
Currently, there's really only one core callback for drivers, which is probe(). Now, this isn't entirely true, since there is also the drop() callback of the driver type (serving as the driver's private data), which is returned by probe() and is dropped in remove(). On the C side remove() mainly serves two purposes: (1) Tear down the device that is operated by the driver, e.g. call bus specific functions, write I/O memory to reset the device, etc. (2) Free the resources that have been allocated by a driver for a specific device. The drop() callback mentioned above is intended to cover (2) as the Rust idiomatic way. However, it is partially insufficient and inefficient to cover (1) properly, since drop() can't be called with additional arguments, such as the reference to the corresponding device that has the correct device context, i.e. the Core device context. This makes it inefficient (but not impossible) to access device resources, e.g. to write device registers, and impossible to call device methods, which are only accessible under the Core device context. In order to solve this, add an additional callback for (1), which we call unbind(). The reason for calling it unbind() is that, unlike remove(), it is *only* meant to be used to perform teardown operations on the device (1), but *not* to release resources (2). Link: https://lore.kernel.org/r/20250621195118.124245-8-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-09rust: platform: implement Driver::unbind()Danilo Krummrich
Currently, there's really only one core callback for drivers, which is probe(). Now, this isn't entirely true, since there is also the drop() callback of the driver type (serving as the driver's private data), which is returned by probe() and is dropped in remove(). On the C side remove() mainly serves two purposes: (1) Tear down the device that is operated by the driver, e.g. call bus specific functions, write I/O memory to reset the device, etc. (2) Free the resources that have been allocated by a driver for a specific device. The drop() callback mentioned above is intended to cover (2) as the Rust idiomatic way. However, it is partially insufficient and inefficient to cover (1) properly, since drop() can't be called with additional arguments, such as the reference to the corresponding device that has the correct device context, i.e. the Core device context. This makes it inefficient (but not impossible) to access device resources, e.g. to write device registers, and impossible to call device methods, which are only accessible under the Core device context. In order to solve this, add an additional callback for (1), which we call unbind(). The reason for calling it unbind() is that, unlike remove(), it is *only* meant to be used to perform teardown operations on the device (1), but *not* to release resources (2). Link: https://lore.kernel.org/r/20250621195118.124245-7-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-09rust: auxiliary: use generic device drvdata accessorsDanilo Krummrich
Take advantage of the generic drvdata accessors of the generic Device type. While at it, use from_result() instead of match. Link: https://lore.kernel.org/r/20250621195118.124245-6-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-09rust: pci: use generic device drvdata accessorsDanilo Krummrich
Take advantage of the generic drvdata accessors of the generic Device type. While at it, use from_result() instead of match. Link: https://lore.kernel.org/r/20250621195118.124245-5-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-09rust: platform: use generic device drvdata accessorsDanilo Krummrich
Take advantage of the generic drvdata accessors of the generic Device type. While at it, use from_result() instead of match. Link: https://lore.kernel.org/r/20250621195118.124245-4-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-09rust: device: add drvdata accessorsDanilo Krummrich
Implement generic accessors for the private data of a driver bound to a device. Those accessors should be used by bus abstractions from their corresponding core callbacks, such as probe(), remove(), etc. Implementing them for device::CoreInternal guarantees that driver's can't interfere with the logic implemented by the bus abstraction. Acked-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250621195118.124245-3-dakr@kernel.org [ Improve safety comment as proposed by Benno. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-09rust: device: introduce device::CoreInternalDanilo Krummrich
Introduce an internal device context, which is semantically equivalent to the Core device context, but reserved for bus abstractions. This allows implementing methods for the Device type, which are limited to be used within the core context of bus abstractions, i.e. restrict the availability for drivers. Link: https://lore.kernel.org/r/20250621195118.124245-2-dakr@kernel.org [ Rename device::Internal to device::CoreInternal. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-07rust: pci: fix documentation related to Device instancesRahul Rameshbabu
Device instances in the pci crate represent a valid struct pci_dev, not a struct device. Fixes: 7b948a2af6b5 ("rust: pci: fix unrestricted &mut pci::Device") Signed-off-by: Rahul Rameshbabu <sergeantsagara@protonmail.com> Link: https://lore.kernel.org/r/20250706035944.18442-3-sergeantsagara@protonmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-05rust: devres: remove unused importTamir Duberstein
As far as I can tell, `c_str` was never used, hence remove it. Signed-off-by: Tamir Duberstein <tamird@gmail.com> Link: https://lore.kernel.org/r/20250704-cstr-include-devres-v1-1-4ee9e56fca09@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-05rust: auxiliary: remove unnecessary importTamir Duberstein
`kernel::str::CStr` is included in the prelude. Signed-off-by: Tamir Duberstein <tamird@gmail.com> Link: https://lore.kernel.org/r/20250704-cstr-include-aux-v1-1-e1a404ae92ac@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-05rust: platform: remove unnecessary importTamir Duberstein
`kernel::str::CStr` is included in the prelude. Signed-off-by: Tamir Duberstein <tamird@gmail.com> Link: https://lore.kernel.org/r/20250704-cstr-include-platform-v1-1-ff7803ee7a81@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-07-03rust: acpi: remove unneeded cast to clean future Clippy warningMiguel Ojeda
A future Clippy warning, `clippy::as_underscore`, is getting enabled in parallel in the rust-next tree: error: using `as _` conversion --> rust/kernel/acpi.rs:25:9 | 25 | self.0.driver_data as _ | ^^^^^^^^^^^^^^^^^^^^^^- | | | help: consider giving the type explicitly: `usize` The type is already `ulong`, which nowadays is always `usize`, so the cast is unneeded. Thus remove it, which in turn will avoid the warning in the future. Other abstractions of device tables do not use a cast here either. Signed-off-by: Miguel Ojeda <ojeda@kernel.org> Reviewed-by: Trevor Gross <tmgross@umich.edu> Link: https://lore.kernel.org/r/20250701174656.62205-1-ojeda@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-07-01rust: miscdevice: clarify invariant for `MiscDeviceRegistration`Shankari Anand
Reword and expand the invariant documentation for `MiscDeviceRegistration` to clarify what it means for the inner device to be "registered". It expands to explain: - `inner` points to a `miscdevice` registered via `misc_register`. - This registration stays valid for the entire lifetime of the object. - Deregistration is guaranteed on `Drop`, via `misc_deregister`. Reported-by: Benno Lossin <lossin@kernel.org> Closes: https://github.com/Rust-for-Linux/linux/issues/1168 Fixes: f893691e7426 ("rust: miscdevice: add base miscdevice abstraction") Signed-off-by: Shankari Anand <shankari.ak0208@gmail.com> Link: https://lore.kernel.org/r/20250626104520.563036-1-shankari.ak0208@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-07-01rust: fix typo in #[repr(transparent)] commentsFUJITA Tomonori
Fix a typo in several comments where `#[repr(transparent)]` was mistakenly written as `#[repr(transparent)` (missing closing bracket). Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> Link: https://lore.kernel.org/r/20250623225846.169805-1-fujita.tomonori@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-06-28rust: devres: get rid of Devres' inner ArcDanilo Krummrich
So far Devres uses an inner memory allocation and reference count, i.e. an inner Arc, in order to ensure that the devres callback can't run into a use-after-free in case where the Devres object is dropped while the devres callback runs concurrently. Instead, use a completion in order to avoid a potential UAF: In Devres::drop(), if we detect that we can't remove the devres action anymore, we wait for the completion that is completed from the devres callback. If, in turn, we were able to successfully remove the devres action, we can just go ahead. This, again, allows us to get rid of the internal Arc, and instead let Devres consume an `impl PinInit<T, E>` in order to return an `impl PinInit<Devres<T>, E>`, which enables us to get away with less memory allocations. Additionally, having the resulting explicit synchronization in Devres::drop() prevents potential subtle undesired side effects of the devres callback dropping the final Arc reference asynchronously within the devres callback. Reviewed-by: Benno Lossin <lossin@kernel.org> Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Link: https://lore.kernel.org/r/20250626200054.243480-4-dakr@kernel.org [ Move '# Invariants' below '# Examples'. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-28rust: devres: replace Devres::new_foreign_owned()Danilo Krummrich
Replace Devres::new_foreign_owned() with devres::register(). The current implementation of Devres::new_foreign_owned() creates a full Devres container instance, including the internal Revocable and completion. However, none of that is necessary for the intended use of giving full ownership of an object to devres and getting it dropped once the given device is unbound. Hence, implement devres::register(), which is limited to consume the given data, wrap it in a KBox and drop the KBox once the given device is unbound, without any other synchronization. Cc: Dave Airlie <airlied@redhat.com> Cc: Simona Vetter <simona.vetter@ffwll.ch> Cc: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Benno Lossin <lossin@kernel.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250626200054.243480-3-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-28rust: revocable: support fallible PinInit typesDanilo Krummrich
Currently, Revocable::new() only supports infallible PinInit implementations, i.e. impl PinInit<T, Infallible>. This has been sufficient so far, since users such as Devres do not support fallibility. Since this is about to change, make Revocable::new() generic over the error type E. Reviewed-by: Benno Lossin <lossin@kernel.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Miguel Ojeda <ojeda@kernel.org> Link: https://lore.kernel.org/r/20250626200054.243480-2-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-28Merge tag 'pin-init-v6.17-result-blanket' of ↵Danilo Krummrich
https://github.com/Rust-for-Linux/linux.git pin-init blanket implementation changes for v6.17 Remove the error from the blanket implementations for `[Pin]Init` and add implementations for `Result`. (Subsequent Devres improvements depend on those pin-init features.)
2025-06-28rust: implement `Wrapper<T>` for `Opaque<T>`Christian Schrefl
Moves the implementation for `pin-init` from an associated function to the trait function of the `Wrapper` trait and extends the implementation to support pin-initializers with error types. Adds a use for the `Wrapper` trait in `revocable.rs`, to use the new `pin-init` function. This is currently the only usage in the kernel. Reviewed-by: Gerald Wisböck <gerald.wisboeck@feather.ink> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Benno Lossin <lossin@kernel.org> Acked-by: Miguel Ojeda <ojeda@kernel.org> Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com> Link: https://lore.kernel.org/r/20250610-b4-rust_miscdevice_registrationdata-v6-1-b03f5dfce998@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-28rust: devres: require T: Send for DevresDanilo Krummrich
Due to calling Revocable::revoke() from Devres::devres_callback() T may be dropped from Devres::devres_callback() and hence must be Send. Fix this by adding the corresponding bound to Devres and DevresInner. Reported-by: Boqun Feng <boqun.feng@gmail.com> Closes: https://lore.kernel.org/lkml/aFzI5L__OcB9hqdG@Mac.home/ Fixes: 76c01ded724b ("rust: add devres abstraction") Reviewed-by: Boqun Feng <boqun.fenng@gmail.com> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250626132544.72866-1-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-26rust: platform: Add ACPI match table support to `Driver` traitIgor Korotin
Extend the `platform::Driver` trait to support ACPI device matching by adding the `ACPI_ID_TABLE` constant. This allows Rust platform drivers to define ACPI match tables alongside their existing OF match tables. These changes mirror the existing OF support and allow Rust platform drivers to match devices based on ACPI identifiers. Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com> Link: https://lore.kernel.org/r/20250620154334.298320-1-igor.korotin.linux@gmail.com [ Use 'LNUXBEEF' as ACPI ID. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-26rust: platform: Set `OF_ID_TABLE` default to `None` in `Driver` traitIgor Korotin
Provide a default value of `None` for `Driver::OF_ID_TABLE` to simplify driver implementations. Drivers that do not require OpenFirmware matching no longer need to import the `of` module or define the constant explicitly. This reduces unnecessary boilerplate and avoids pulling in unused dependencies. Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com> Link: https://lore.kernel.org/r/20250620154124.297158-1-igor.korotin.linux@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-26rust: driver: Add ACPI id table support to Adapter traitIgor Korotin
Extend the `Adapter` trait to support ACPI device identification. This mirrors the existing Open Firmware (OF) support (`of_id_table`) and enables Rust drivers to match and retrieve ACPI-specific device data when `CONFIG_ACPI` is enabled. To avoid breaking compilation, a stub implementation of `acpi_id_table()` is added to the Platform adapter; the full implementation will be provided in a subsequent patch. Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com> Link: https://lore.kernel.org/r/20250620153914.295679-1-igor.korotin.linux@gmail.com [ Fix clippy warning if #[cfg(not(CONFIG_OF))]; fix checkpatch.pl line length warnings. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-26rust: driver: Consolidate `Adapter::of_id_info` methods using `#[cfg]`Igor Korotin
Refactor the `of_id_info` methods in the `Adapter` trait to reduce duplication. Previously, the method had two versions selected via `#[cfg(...)]` and `#[cfg(not(...))]`. This change merges them into a single method by using `#[cfg]` blocks within the method body. Suggested-by: Benno Lossin <lossin@kernel.org> Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com> Link: https://lore.kernel.org/r/20250620153656.294468-1-igor.korotin.linux@gmail.com [ Fix clippy warning if #[cfg(not(CONFIG_OF))]; fix checkpatch.pl line length warnings. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-26rust: acpi: add `acpi::DeviceId` abstractionIgor Korotin
`acpi::DeviceId` is an abstraction around `struct acpi_device_id`. Enable drivers to build ACPI device ID tables, to be consumed by the corresponding bus abstractions, such as platform or I2C. Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com> Acked-by: Rafael J. Wysocki <rafael@kernel.org> Link: https://lore.kernel.org/r/20250620152425.285683-1-igor.korotin.linux@gmail.com [ Always inline DeviceId::new() and use &'static CStr; slightly reword commit message. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-25rust: device: implement FwNode::is_of_node()Danilo Krummrich
Implement FwNode::is_of_node() in order to check whether a FwNode instance is embedded in a struct device_node. Reviewed-by: Rob Herring (Arm) <robh@kernel.org> Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com> Link: https://lore.kernel.org/r/20250620151504.278766-1-igor.korotin.linux@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-25rust: device: Add property_get_reference_argsRemo Senekowitsch
Allow Rust code to read reference args from device properties. The wrapper type `FwNodeReferenceArgs` allows callers to access the buffer of read args safely. Signed-off-by: Remo Senekowitsch <remo@buenzli.dev> Link: https://lore.kernel.org/r/20250616154511.1862909-3-remo@buenzli.dev [ Move up NArgs; refer to FwNodeReferenceArgs in NArgs doc-comment. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-25rust: device: Add child accessor and iteratorRemo Senekowitsch
Allow Rust drivers to access children of a fwnode either by name or by iterating over all of them. In C, there is the function `fwnode_get_next_child_node` for iteration and the macro `fwnode_for_each_child_node` that helps with handling the pointers. Instead of a macro, a native iterator is used in Rust such that regular for-loops can be used. Tested-by: Dirk Behme <dirk.behme@de.bosch.com> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev> Link: https://lore.kernel.org/r/20250616154511.1862909-2-remo@buenzli.dev Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-23Merge 6.16-rc3 into driver-core-nextGreg Kroah-Hartman
We need the driver-core fixes that are in 6.16-rc3 into here as well to build on top of. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-06-18Merge tag 'driver-core-6.16-rc3' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core Pull driver core fixes from Danilo Krummrich: - Fix a race condition in Devres::drop(). This depends on two other patches: - (Minimal) Rust abstractions for struct completion - Let Revocable indicate whether its data is already being revoked - Fix Devres to avoid exposing the internal Revocable - Add .mailmap entry for Danilo Krummrich - Add Madhavan Srinivasan to embargoed-hardware-issues.rst * tag 'driver-core-6.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core: Documentation: embargoed-hardware-issues.rst: Add myself for Power mailmap: add entry for Danilo Krummrich rust: devres: do not dereference to the internal Revocable rust: devres: fix race in Devres::drop() rust: revocable: indicate whether `data` has been revoked already rust: completion: implement initial abstraction
2025-06-14Merge tag 'rust-fixes-6.16' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux Pull Rust fix from Miguel Ojeda: - 'hrtimer': fix future compile error when the 'impl_has_hr_timer!' macro starts to get called * tag 'rust-fixes-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: rust: time: Fix compile error in impl_has_hr_timer macro
2025-06-13rust: devres: do not dereference to the internal RevocableDanilo Krummrich
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>
2025-06-13rust: devres: fix race in Devres::drop()Danilo Krummrich
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>
2025-06-13rust: revocable: indicate whether `data` has been revoked alreadyDanilo Krummrich
Return a boolean from Revocable::revoke() and Revocable::revoke_nosync() to indicate whether the data has been revoked already. Return true if the data hasn't been revoked yet (i.e. this call revoked the data), false otherwise. This is required by Devres in order to synchronize the completion of the revoke process. Reviewed-by: Benno Lossin <lossin@kernel.org> Acked-by: Miguel Ojeda <ojeda@kernel.org> Link: https://lore.kernel.org/r/20250612121817.1621-3-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-13rust: completion: implement initial abstractionDanilo Krummrich
Implement a minimal abstraction for the completion synchronization primitive. This initial abstraction only adds complete_all() and wait_for_completion(), since that is what is required for the subsequent Devres patch. Cc: Ingo Molnar <mingo@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Juri Lelli <juri.lelli@redhat.com> Cc: Vincent Guittot <vincent.guittot@linaro.org> Cc: Dietmar Eggemann <dietmar.eggemann@arm.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Ben Segall <bsegall@google.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Valentin Schneider <vschneid@redhat.com> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Reviewed-by: Benno Lossin <lossin@kernel.org> Acked-by: Miguel Ojeda <ojeda@kernel.org> Link: https://lore.kernel.org/r/20250612121817.1621-2-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-13rust: device: Implement accessors for firmware propertiesRemo Senekowitsch
Add methods to FwNode for reading several firmware property types like strings, integers and arrays. Most types are read with the generic `property_read` method. There are two exceptions: * `property_read_bool` cannot fail, so the fallible function signature of `property_read` would not make sense for reading booleans. * `property_read_array_vec` can fail because of a dynamic memory allocation. This error must be handled separately, leading to a different function signature than `property_read`. The traits `Property` and `PropertyInt` drive the generic behavior of `property_read`. `PropertyInt` is necessary to associate specific integer types with the C functions to read them. While there is a C function to read integers of generic sizes called `fwnode_property_read_int_array`, it was preferred not to make this public. Tested-by: Dirk Behme <dirk.behme@de.bosch.com> Co-developed-by: Rob Herring (Arm) <robh@kernel.org> Signed-off-by: Rob Herring (Arm) <robh@kernel.org> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev> Link: https://lore.kernel.org/r/20250611102908.212514-7-remo@buenzli.dev [ Properly include kernel::device::private::Sealed; add explicit type annotations for core::mem::transmute(). - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-13rust: device: Introduce PropertyGuardRemo Senekowitsch
This abstraction is a way to force users to specify whether a property is supposed to be required or not. This allows us to move error logging of missing required properties into core, preventing a lot of boilerplate in drivers. It will be used by upcoming methods for reading device properties. Tested-by: Dirk Behme <dirk.behme@de.bosch.com> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev> Link: https://lore.kernel.org/r/20250611102908.212514-6-remo@buenzli.dev [ Use prelude::* to avoid build failure; move PropertyGuard below Display impl of FwNode. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-13rust: device: Enable printing fwnode name and pathRemo Senekowitsch
Add two new public methods `display_name` and `display_path` to `FwNode`. They can be used by driver authors for logging purposes. In addition, they will be used by core property abstractions for automatic logging, for example when a driver attempts to read a required but missing property. Tested-by: Dirk Behme <dirk.behme@de.bosch.com> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev> Link: https://lore.kernel.org/r/20250611102908.212514-5-remo@buenzli.dev [ Remove #[expect(dead_code)] from FwNode::from_raw(). - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-13rust: device: Move property_present() to FwNodeRemo Senekowitsch
The new FwNode abstraction will be used for accessing all device properties. It would be possible to duplicate the methods on the device itself, but since some of the methods on Device would have different type sigatures as the ones on FwNode, this would only lead to inconsistency and confusion. For this reason, property_present is removed from Device and existing users are updated. Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev> Link: https://lore.kernel.org/r/20250611102908.212514-4-remo@buenzli.dev Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-13rust: device: Enable accessing the FwNode of a DeviceRemo Senekowitsch
Subsequent patches will add methods for reading properties to FwNode. The first step to accessing these methods will be to access the "root" FwNode of a Device. Add the method `fwnode` to `Device`. Tested-by: Dirk Behme <dirk.behme@de.bosch.com> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev> Link: https://lore.kernel.org/r/20250611102908.212514-3-remo@buenzli.dev Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-12rust: device: Create FwNode abstraction for accessing device propertiesRemo Senekowitsch
Accessing device properties is currently done via methods on `Device` itself, using bindings to device_property_* functions. This is sufficient for the existing method property_present. However, it's not sufficient for other device properties we want to access. For example, iterating over child nodes of a device will yield a fwnode_handle. That's not a device, so it wouldn't be possible to read the properties of that child node. Thus, we need an abstraction over fwnode_handle and methods for reading its properties. Add a struct FwNode which abstracts over the C struct fwnode_handle. Implement its reference counting analogous to other Rust abstractions over reference-counted C structs. Subsequent patches will add functionality to access FwNode and read properties with it. Tested-by: Dirk Behme <dirk.behme@de.bosch.com> Signed-off-by: Remo Senekowitsch <remo@buenzli.dev> Link: https://lore.kernel.org/r/20250611102908.212514-2-remo@buenzli.dev [ Add temporary #[expect(dead_code)] to avoid a warning. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-06-12rust: cpu: Add CpuId::current() to retrieve current CPU IDViresh Kumar
Introduce `CpuId::current()`, a constructor that wraps the C function `raw_smp_processor_id()` to retrieve the current CPU identifier without guaranteeing stability. This function should be used only when the caller can ensure that the CPU ID won't change unexpectedly due to preemption or migration. Suggested-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
2025-06-12rust: Use CpuId in place of raw CPU numbersViresh Kumar
Use the newly defined `CpuId` abstraction instead of raw CPU numbers. This also fixes a doctest failure for configurations where `nr_cpu_ids < 4`. The C `cpumask_{set|clear}_cpu()` APIs emit a warning when given an invalid CPU number — but only if `CONFIG_DEBUG_PER_CPU_MAPS=y` is set. Meanwhile, `cpumask_weight()` only considers CPUs up to `nr_cpu_ids`, which can cause inconsistencies: a CPU number greater than `nr_cpu_ids` may be set in the mask, yet the weight calculation won't reflect it. This leads to doctest failures when `nr_cpu_ids < 4`, as the test tries to set CPUs 2 and 3: rust_doctest_kernel_cpumask_rs_0.location: rust/kernel/cpumask.rs:180 rust_doctest_kernel_cpumask_rs_0: ASSERTION FAILED at rust/kernel/cpumask.rs:190 Fixes: 8961b8cb3099 ("rust: cpumask: Add initial abstractions") Reported-by: Miguel Ojeda <ojeda@kernel.org> Closes: https://lore.kernel.org/rust-for-linux/CANiq72k3ozKkLMinTLQwvkyg9K=BeRxs1oYZSKhJHY-veEyZdg@mail.gmail.com/ Reported-by: Andreas Hindborg <a.hindborg@kernel.org> Closes: https://lore.kernel.org/all/87qzzy3ric.fsf@kernel.org/ Suggested-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
2025-06-12rust: cpu: Introduce CpuId abstractionViresh Kumar
This adds abstraction for representing a CPU identifier. Suggested-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
2025-06-11rust: pin-init: change blanket impls for `[Pin]Init` and add one for ↵Benno Lossin
`Result<T, E>` Remove the error from the blanket implementations `impl<T, E> Init<T, E> for T` (and also for `PinInit`). Add implementations for `Result<T, E>`. This allows one to easily construct (un)conditional failing initializers. It also improves the compatibility with APIs that do not use pin-init, because users can supply a `Result<T, E>` to a function taking an `impl PinInit<T, E>`. Suggested-by: Alice Ryhl <aliceryhl@google.com> Link: https://github.com/Rust-for-Linux/pin-init/pull/62/commits/58612514b256c6f4a4a0718be25298410e67387a [ Also fix a compile error in block. - Benno ] Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Link: https://lore.kernel.org/all/20250529081027.297648-2-lossin@kernel.org [ Add title prefix `rust: pin-init`. - Benno ] Signed-off-by: Benno Lossin <lossin@kernel.org>
2025-06-10rust: time: Fix compile error in impl_has_hr_timer macroFUJITA Tomonori
Fix a compile error in the `impl_has_hr_timer!` macro as follows: error[E0599]: no method named cast_mut found for raw pointer *mut Foo in the current scope The `container_of!` macro already returns a mutable pointer when used in a `*mut T` context so the `.cast_mut()` method is not available. [ We missed this one because there is no caller yet and it is a macro. - Miguel ] Fixes: 74d6a606c2b3 ("rust: retain pointer mut-ness in `container_of!`") Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> Reviewed-by: Benno Lossin <lossin@kernel.org> Acked-by: Andreas Hindborg <a.hindborg@kernel.org> Link: https://lore.kernel.org/r/20250606020505.3186533-1-fujita.tomonori@gmail.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org>