summaryrefslogtreecommitdiff
path: root/rust/kernel
AgeCommit message (Collapse)Author
2025-05-11mm: rust: add lock_vma_under_rcuAlice Ryhl
Currently, the binder driver always uses the mmap lock to make changes to its vma. Because the mmap lock is global to the process, this can involve significant contention. However, the kernel has a feature called per-vma locks, which can significantly reduce contention. For example, you can take a vma lock in parallel with an mmap write lock. This is important because contention on the mmap lock has been a long-term recurring challenge for the Binder driver. This patch introduces support for using `lock_vma_under_rcu` from Rust. The Rust Binder driver will be able to use this to reduce contention on the mmap lock. Link: https://lkml.kernel.org/r/20250408-vma-v16-4-d8b446e885d9@google.com Signed-off-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Acked-by: Liam R. Howlett <Liam.Howlett@Oracle.com> Reviewed-by: Jann Horn <jannh@google.com> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Reviewed-by: Gary Guo <gary@garyguo.net> Cc: Alex Gaynor <alex.gaynor@gmail.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Balbir Singh <balbirs@nvidia.com> Cc: Benno Lossin <benno.lossin@proton.me> Cc: Björn Roy Baron <bjorn3_gh@protonmail.com> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Miguel Ojeda <ojeda@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Trevor Gross <tmgross@umich.edu> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2025-05-11mm: rust: add vm_insert_pageAlice Ryhl
The vm_insert_page method is only usable on vmas with the VM_MIXEDMAP flag, so we introduce a new type to keep track of such vmas. The approach used in this patch assumes that we will not need to encode many flag combinations in the type. I don't think we need to encode more than VM_MIXEDMAP and VM_PFNMAP as things are now. However, if that becomes necessary, using generic parameters in a single type would scale better as the number of flags increases. Link: https://lkml.kernel.org/r/20250408-vma-v16-3-d8b446e885d9@google.com Signed-off-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Acked-by: Liam R. Howlett <Liam.Howlett@Oracle.com> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Reviewed-by: Gary Guo <gary@garyguo.net> Cc: Alex Gaynor <alex.gaynor@gmail.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Balbir Singh <balbirs@nvidia.com> Cc: Benno Lossin <benno.lossin@proton.me> Cc: Björn Roy Baron <bjorn3_gh@protonmail.com> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Jann Horn <jannh@google.com> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Miguel Ojeda <ojeda@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Trevor Gross <tmgross@umich.edu> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2025-05-11mm: rust: add vm_area_struct methods that require read accessAlice Ryhl
This adds a type called VmaRef which is used when referencing a vma that you have read access to. Here, read access means that you hold either the mmap read lock or the vma read lock (or stronger). Additionally, a vma_lookup method is added to the mmap read guard, which enables you to obtain a &VmaRef in safe Rust code. This patch only provides a way to lock the mmap read lock, but a follow-up patch also provides a way to just lock the vma read lock. Link: https://lkml.kernel.org/r/20250408-vma-v16-2-d8b446e885d9@google.com Signed-off-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Acked-by: Liam R. Howlett <Liam.Howlett@Oracle.com> Reviewed-by: Jann Horn <jannh@google.com> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Reviewed-by: Gary Guo <gary@garyguo.net> Cc: Alex Gaynor <alex.gaynor@gmail.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Balbir Singh <balbirs@nvidia.com> Cc: Benno Lossin <benno.lossin@proton.me> Cc: Björn Roy Baron <bjorn3_gh@protonmail.com> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Miguel Ojeda <ojeda@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Trevor Gross <tmgross@umich.edu> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2025-05-11mm: rust: add abstraction for struct mm_structAlice Ryhl
Patch series "Rust support for mm_struct, vm_area_struct, and mmap", v16. This updates the vm_area_struct support to use the approach we discussed at LPC where there are several different Rust wrappers for vm_area_struct depending on the kind of access you have to the vma. Each case allows a different set of operations on the vma. This includes an MM MAINTAINERS entry as proposed by Lorenzo: https://lore.kernel.org/all/33e64b12-aa07-4e78-933a-b07c37ff1d84@lucifer.local/ This patch (of 9): These abstractions allow you to reference a `struct mm_struct` using both mmgrab and mmget refcounts. This is done using two Rust types: * Mm - represents an mm_struct where you don't know anything about the value of mm_users. * MmWithUser - represents an mm_struct where you know at compile time that mm_users is non-zero. This allows us to encode in the type system whether a method requires that mm_users is non-zero or not. For instance, you can always call `mmget_not_zero` but you can only call `mmap_read_lock` when mm_users is non-zero. The struct is called Mm to keep consistency with the C side. The ability to obtain `current->mm` is added later in this series. The mm module is defined to only exist when CONFIG_MMU is set. This avoids various errors due to missing types and functions when CONFIG_MMU is disabled. More fine-grained cfgs can be considered in the future. See the thread at [1] for more info. Link: https://lkml.kernel.org/r/20250408-vma-v16-9-d8b446e885d9@google.com Link: https://lkml.kernel.org/r/20250408-vma-v16-1-d8b446e885d9@google.com Link: https://lore.kernel.org/all/202503091916.QousmtcY-lkp@intel.com/ Signed-off-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Acked-by: Liam R. Howlett <Liam.Howlett@Oracle.com> Acked-by: Balbir Singh <balbirs@nvidia.com> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Reviewed-by: Gary Guo <gary@garyguo.net> Cc: Alex Gaynor <alex.gaynor@gmail.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Benno Lossin <benno.lossin@proton.me> Cc: Björn Roy Baron <bjorn3_gh@protonmail.com> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Jann Horn <jannh@google.com> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Miguel Ojeda <ojeda@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Trevor Gross <tmgross@umich.edu> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2025-05-12rust: replace rustdoc references to alloc::formatAndrew Ballance
Replace alloc::format[1] in the pr_* and dev_* macros' doc comments with std::format[2] because they are identical but less likely to get confused with the kernel's alloc crate. And add a url link for the std::format! macro. Link: https://doc.rust-lang.org/alloc/macro.format.html [1] Link: https://doc.rust-lang.org/std/macro.format.html [2] Reviewed-by: Benno Lossin <benno.lossin@proton.me> Signed-off-by: Andrew Ballance <andrewjballance@gmail.com> Link: https://lore.kernel.org/r/20250325133352.441425-1-andrewjballance@gmail.com [ Fixed typo and reworded slightly. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-05-12rust: convert raw URLs to Markdown autolinks in commentsXizhe Yin
Some comments in Rust files use raw URLs (http://example.com) rather than Markdown autolinks <URL>. This inconsistency makes the documentation less uniform and harder to maintain. This patch converts all remaining raw URLs in Rust code comments to use the Markdown autolink format, maintaining consistency with the rest of the codebase which already uses this style. Suggested-by: Miguel Ojeda <ojeda@kernel.org> Link: https://github.com/Rust-for-Linux/linux/issues/1153 Signed-off-by: Xizhe Yin <xizheyin@smail.nju.edu.cn> Link: https://lore.kernel.org/r/509F0B66E3C1575D+20250407033441.5567-1-xizheyin@smail.nju.edu.cn [ Used From form for Signed-off-by. Sorted tags. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-05-12rust: clarify the language unstable features in useMiguel Ojeda
We track the details of which Rust features we use at our usual "live list" [1] (and its sub-lists), but in light of a discussion in the LWN article [2], it would help to clarify it in the source code. In particular, we are very close to rely only on stable Rust language-wise -- essentially only two language features remain (including the `kernel` crate). Thus add some details in both the feature list of the `kernel` crate as well as the list of allowed features. This does not over every single feature, and there are quite a few non-language features that we use too. To have the full picture, please refer to [1]. Link: https://github.com/Rust-for-Linux/linux/issues/2 [1] Link: https://lwn.net/Articles/1015409/ [2] Suggested-by: Andreas Hindborg <a.hindborg@kernel.org> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Link: https://lore.kernel.org/r/20250327211302.286313-1-ojeda@kernel.org [ Improved comments with suggestions from the list. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-05-12rust: uaccess: take advantage of the prelude and `Result`'s defaultsMiguel Ojeda
The `kernel` prelude brings `Result` and the error codes; and the prelude itself is already available in the examples automatically. In addition, `Result` already defaults to `T = ()`. Thus simplify. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250429151445.438977-1-ojeda@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-05-12rust: static_assert: add optional messageAltan Ozlu
Add an optional panic message to the `static_assert!` macro. The panic message doesn't support argument formatting, because the `assert!` macro only supports formatting in non-const contexts. Suggested-by: Miguel Ojeda <ojeda@kernel.org> Link: https://github.com/Rust-for-Linux/linux/issues/1149 Signed-off-by: Altan Ozlu <altan@ozlu.eu> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Trevor Gross <tmgross@umich.edu> Link: https://lore.kernel.org/r/20250326202520.1176162-2-altan@ozlu.eu Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-05-12rust: page: optimize rust symbol generation for PageKunwu Chan
When build the kernel using the llvm-18.1.3-rust-1.85.0-x86_64 with ARCH=arm64, the following symbols are generated: $nm vmlinux | grep ' _R'.*Page | rustfilt ffff8000805b6f98 T <kernel::page::Page>::alloc_page ffff8000805b715c T <kernel::page::Page>::fill_zero_raw ffff8000805b720c T <kernel::page::Page>::copy_from_user_slice_raw ffff8000805b6fb4 T <kernel::page::Page>::read_raw ffff8000805b7088 T <kernel::page::Page>::write_raw ffff8000805b72fc T <kernel::page::Page as core::ops::drop::Drop>::drop These Rust symbols(alloc_page and drop) are trivial wrappers around the C functions alloc_pages and __free_pages. It doesn't make sense to go through a trivial wrapper for these functions, so mark them inline. Link: https://github.com/Rust-for-Linux/linux/issues/1145 Suggested-by: Alice Ryhl <aliceryhl@google.com> Co-developed-by: Grace Deng <Grace.Deng006@Gmail.com> Signed-off-by: Grace Deng <Grace.Deng006@Gmail.com> Signed-off-by: Kunwu Chan <kunwu.chan@hotmail.com> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250321080124.484647-1-kunwu.chan@linux.dev [ Removed spurious colon in title. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-05-07rust: alloc: add Vec::insert_within_capacityAlice Ryhl
This adds a variant of Vec::insert that does not allocate memory. This makes it safe to use this function while holding a spinlock. Rust Binder uses it for the range allocator fast path. Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250502-vec-methods-v5-7-06d20ad9366f@google.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-05-07rust: alloc: add Vec::removeAlice Ryhl
This is needed by Rust Binder in the range allocator, and by upcoming GPU drivers during firmware initialization. Panics in the kernel are best avoided when possible, so an error is returned if the index is out of bounds. An error type is used rather than just returning Option<T> to let callers handle errors with ?. Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250502-vec-methods-v5-6-06d20ad9366f@google.com [ Remove `# Panics` section; `Vec::remove() handles the error properly.` - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-05-07rust: alloc: add Vec::retainAlice Ryhl
This adds a common Vec method called `retain` that removes all elements that don't match a certain condition. Rust Binder uses it to find all processes that match a given pid. The stdlib retain method takes &T rather than &mut T and has a separate retain_mut for the &mut T case. However, this is considered an API mistake that can't be fixed now due to backwards compatibility. There's no reason for us to repeat that mistake. Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250502-vec-methods-v5-5-06d20ad9366f@google.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-05-07rust: alloc: add Vec::drain_allAlice Ryhl
This is like the stdlib method drain, except that it's hard-coded to use the entire vector's range. Rust Binder uses it in the range allocator to take ownership of everything in a vector in a case where reusing the vector is desirable. Implementing `DrainAll` in terms of `slice::IterMut` lets us reuse some nice optimizations in core for the case where T is a ZST. Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250502-vec-methods-v5-4-06d20ad9366f@google.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-05-07rust: alloc: add Vec::push_within_capacityAlice Ryhl
This introduces a new method called `push_within_capacity` for appending to a vector without attempting to allocate if the capacity is full. Rust Binder will use this in various places to safely push to a vector while holding a spinlock. The implementation is moved to a push_within_capacity_unchecked method. This is preferred over having push() call push_within_capacity() followed by an unwrap_unchecked() for simpler unsafe. Panics in the kernel are best avoided when possible, so an error is returned if the vector does not have sufficient capacity. An error type is used rather than just returning Result<(),T> to make it more convenient for callers (i.e. they can use ? or unwrap). Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250502-vec-methods-v5-3-06d20ad9366f@google.com [ Remove public visibility from `Vec::push_within_capacity_unchecked()`. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-05-07rust: alloc: add Vec::popAlice Ryhl
This introduces a basic method that our custom Vec is missing. I expect that it will be used in many places, but at the time of writing, Rust Binder has six calls to Vec::pop. Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250502-vec-methods-v5-2-06d20ad9366f@google.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-05-07rust: alloc: add Vec::clearAlice Ryhl
Our custom Vec type is missing the stdlib method `clear`, thus add it. It will be used in the miscdevice sample. Reviewed-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Tamir Duberstein <tamird@gmail.com> Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Link: https://lore.kernel.org/r/20250502-vec-methods-v5-1-06d20ad9366f@google.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-05-07rust: clean Rust 1.88.0's `clippy::uninlined_format_args` lintMiguel Ojeda
Starting with Rust 1.88.0 (expected 2025-06-26) [1], `rustc` may move back the `uninlined_format_args` to `style` from `pedantic` (it was there waiting for rust-analyzer suppotr), and thus we will start to see lints like: warning: variables can be used directly in the `format!` string --> rust/macros/kunit.rs:105:37 | 105 | let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{}", test); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args help: change this to | 105 - let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{}", test); 105 + let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{test}"); There is even a case that is a pure removal: warning: variables can be used directly in the `format!` string --> rust/macros/module.rs:51:13 | 51 | format!("{field}={content}\0", field = field, content = content) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args help: change this to | 51 - format!("{field}={content}\0", field = field, content = content) 51 + format!("{field}={content}\0") The lints all seem like nice cleanups, thus just apply them. We may want to disable `allow-mixed-uninlined-format-args` in the future. Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs). Link: https://github.com/rust-lang/rust-clippy/pull/14160 [1] Acked-by: Benno Lossin <lossin@kernel.org> Reviewed-by: Tamir Duberstein <tamird@gmail.com> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250502140237.1659624-6-ojeda@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-05-07rust: allow Rust 1.87.0's `clippy::ptr_eq` lintMiguel Ojeda
Starting with Rust 1.87.0 (expected 2025-05-15) [1], Clippy may expand the `ptr_eq` lint, e.g.: error: use `core::ptr::eq` when comparing raw pointers --> rust/kernel/list.rs:438:12 | 438 | if self.first == item { | ^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(self.first, item)` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq = note: `-D clippy::ptr-eq` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]` It is expected that a PR to relax the lint will be backported [2] by the time Rust 1.87.0 releases, since the lint was considered too eager (at least by default) [3]. Thus allow the lint temporarily just in case. Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs). Link: https://github.com/rust-lang/rust-clippy/pull/14339 [1] Link: https://github.com/rust-lang/rust-clippy/pull/14526 [2] Link: https://github.com/rust-lang/rust-clippy/issues/14525 [3] Link: https://lore.kernel.org/r/20250502140237.1659624-3-ojeda@kernel.org [ Converted to `allow`s since backport was confirmed. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-05-04rust: devres: implement Devres::access()Danilo Krummrich
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>
2025-05-04rust: revocable: implement Revocable::access()Danilo Krummrich
Implement an unsafe direct accessor for the data stored within the Revocable. This is useful for cases where we can prove that the data stored within the Revocable is not and cannot be revoked for the duration of the lifetime of the returned reference. Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Acked-by: Miguel Ojeda <ojeda@kernel.org> 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-2-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-05-01rust: xarray: Add an abstraction for XArrayTamir Duberstein
`XArray` is an efficient sparse array of pointers. Add a Rust abstraction for this type. This implementation bounds the element type on `ForeignOwnable` and requires explicit locking for all operations. Future work may leverage RCU to enable lockless operation. Inspired-by: Maíra Canal <mcanal@igalia.com> Inspired-by: Asahi Lina <lina@asahilina.net> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Signed-off-by: Tamir Duberstein <tamird@gmail.com> Link: https://lore.kernel.org/r/20250423-rust-xarray-bindings-v19-2-83cdcf11c114@gmail.com Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
2025-05-01rust: types: add `ForeignOwnable::PointedTo`Tamir Duberstein
Allow implementors to specify the foreign pointer type; this exposes information about the pointed-to type such as its alignment. This requires the trait to be `unsafe` since it is now possible for implementors to break soundness by returning a misaligned pointer. Encoding the pointer type in the trait (and avoiding pointer casts) allows the compiler to check that implementors return the correct pointer type. This is preferable to directly encoding the alignment in the trait using a constant as the compiler would be unable to check it. Acked-by: Danilo Krummrich <dakr@kernel.org> Signed-off-by: Tamir Duberstein <tamird@gmail.com> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250423-rust-xarray-bindings-v19-1-83cdcf11c114@gmail.com Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
2025-04-29rust: device: conditionally expect `dead_code` for `parent()`Miguel Ojeda
When `CONFIG_AUXILIARY_BUS` is disabled, `parent()` is still dead code: error: method `parent` is never used --> rust/kernel/device.rs:71:19 | 64 | impl<Ctx: DeviceContext> Device<Ctx> { | ------------------------------------ method in this implementation ... 71 | pub(crate) fn parent(&self) -> Option<&Self> { | ^^^^^^ | = note: `-D dead-code` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(dead_code)]` Thus reintroduce the `expect`, but now as a conditional one. Do so as `dead_code` since that is narrower. An `allow` would also be possible, but Danilo wants to catch new users in the future [1]. Link: https://lore.kernel.org/rust-for-linux/aBE8qQrpXOfru_K3@pollux/ [1] Fixes: ce735e73dd59 ("rust: auxiliary: add auxiliary device / driver abstractions") Signed-off-by: Miguel Ojeda <ojeda@kernel.org> Link: https://lore.kernel.org/r/20250429210629.513521-1-ojeda@kernel.org [ Adjust commit subject to "rust: device: conditionally expect `dead_code` for `parent()`". - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-29rust: time: Introduce Instant typeFUJITA Tomonori
Introduce a type representing a specific point in time. We could use the Ktime type but C's ktime_t is used for both timestamp and timedelta. To avoid confusion, introduce a new Instant type for timestamp. Rename Ktime to Instant and modify their methods for timestamp. Implement the subtraction operator for Instant: Delta = Instant A - Instant B Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Fiona Behrens <me@kloenk.dev> Tested-by: Daniel Almeida <daniel.almeida@collabora.com> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> Link: https://lore.kernel.org/r/20250423192857.199712-5-fujita.tomonori@gmail.com Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
2025-04-29rust: time: Introduce Delta typeFUJITA Tomonori
Introduce a type representing a span of time. Define our own type because `core::time::Duration` is large and could panic during creation. time::Ktime could be also used for time duration but timestamp and timedelta are different so better to use a new type. i64 is used instead of u64 to represent a span of time; some C drivers uses negative Deltas and i64 is more compatible with Ktime using i64 too (e.g., ktime_[us|ms]_delta() APIs return i64 so we create Delta object without type conversion. i64 is used instead of bindings::ktime_t because when the ktime_t type is used as timestamp, it represents values from 0 to KTIME_MAX, which is different from Delta. as_millis() method isn't used in this patchset. It's planned to be used in Binder driver. Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Fiona Behrens <me@kloenk.dev> Tested-by: Daniel Almeida <daniel.almeida@collabora.com> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> Link: https://lore.kernel.org/r/20250423192857.199712-4-fujita.tomonori@gmail.com Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
2025-04-29rust: time: Add PartialEq/Eq/PartialOrd/Ord trait to KtimeFUJITA Tomonori
Add PartialEq/Eq/PartialOrd/Ord trait to Ktime so two Ktime instances can be compared to determine whether a timeout is met or not. Use the derive implements; we directly touch C's ktime_t rather than using the C's accessors because it is more efficient and we already do in the existing code (Ktime::sub). Reviewed-by: Trevor Gross <tmgross@umich.edu> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Gary Guo <gary@garyguo.net> Reviewed-by: Fiona Behrens <me@kloenk.dev> Tested-by: Daniel Almeida <daniel.almeida@collabora.com> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> Link: https://lore.kernel.org/r/20250423192857.199712-3-fujita.tomonori@gmail.com Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
2025-04-29rust: hrtimer: Add Ktime temporarilyFUJITA Tomonori
Add Ktime temporarily until hrtimer is refactored to use Instant and Delta types. Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Reviewed-by: Boqun Feng <boqun.feng@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com> Link: https://lore.kernel.org/r/20250423192857.199712-2-fujita.tomonori@gmail.com Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
2025-04-28rust: drm: gem: Add GEM object abstractionAsahi Lina
DRM GEM is the DRM memory management subsystem used by most modern drivers; add a Rust abstraction for DRM GEM. This includes the BaseObject trait, which contains operations shared by all GEM object classes. Signed-off-by: Asahi Lina <lina@asahilina.net> Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Lyude Paul <lyude@redhat.com> Link: https://lore.kernel.org/r/20250410235546.43736-8-dakr@kernel.org [ Rework of GEM object abstractions * switch to the Opaque<T> type * fix (mutable) references to struct drm_gem_object (which in this context is UB) * drop all custom reference types in favor of AlwaysRefCounted * bunch of minor changes and simplifications (e.g. IntoGEMObject trait) * write and fix safety and invariant comments * remove necessity for and convert 'as' casts * original source archive: https://archive.is/dD5SL - Danilo ] [ Fix missing CONFIG_DRM guards in rust/helpers/drm.c. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-24rust: drm: file: Add File abstractionAsahi Lina
A DRM File is the DRM counterpart to a kernel file structure, representing an open DRM file descriptor. Add a Rust abstraction to allow drivers to implement their own File types that implement the DriverFile trait. Reviewed-by: Maxime Ripard <mripard@kernel.org> Signed-off-by: Asahi Lina <lina@asahilina.net> Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Lyude Paul <lyude@redhat.com> Link: https://lore.kernel.org/r/20250410235546.43736-7-dakr@kernel.org [ Rework of drm::File * switch to the Opaque<T> type * fix (mutable) references to struct drm_file (which in this context is UB) * restructure and rename functions to align with common kernel schemes * write and fix safety and invariant comments * remove necessity for and convert 'as' casts * original source archive: https://archive.is/GH8oy - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-24rust: drm: add DRM driver registrationAsahi Lina
Implement the DRM driver `Registration`. The `Registration` structure is responsible to register and unregister a DRM driver. It makes use of the `Devres` container in order to allow the `Registration` to be owned by devres, such that it is automatically dropped (and the DRM driver unregistered) once the parent device is unbound. Signed-off-by: Asahi Lina <lina@asahilina.net> Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Lyude Paul <lyude@redhat.com> Link: https://lore.kernel.org/r/20250410235546.43736-6-dakr@kernel.org [ Rework of drm::Registration * move VTABLE to drm::Device to prevent use-after-free bugs; VTABLE needs to be bound to the lifetime of drm::Device, not the drm::Registration * combine new() and register() to get rid of the registered boolean * remove file_operations * move struct drm_device creation to drm::Device * introduce Devres * original source archive: https://archive.is/Pl9ys - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-24rust: drm: add device abstractionAsahi Lina
Implement the abstraction for a `struct drm_device`. A `drm::Device` creates a static const `struct drm_driver` filled with the data from the `drm::Driver` trait implementation of the actual driver creating the `drm::Device`. Reviewed-by: Maxime Ripard <mripard@kernel.org> Signed-off-by: Asahi Lina <lina@asahilina.net> Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Lyude Paul <lyude@redhat.com> Link: https://lore.kernel.org/r/20250410235546.43736-5-dakr@kernel.org [ Rewrite of drm::Device * full rewrite of the drm::Device abstraction using the subclassing pattern * original source archive: http://archive.today/5NxBo - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-24rust: drm: add driver abstractionsAsahi Lina
Implement the DRM driver abstractions. The `Driver` trait provides the interface to the actual driver to fill in the driver specific data, such as the `DriverInfo`, driver features and IOCTLs. Reviewed-by: Maxime Ripard <mripard@kernel.org> Signed-off-by: Asahi Lina <lina@asahilina.net> Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Lyude Paul <lyude@redhat.com> Link: https://lore.kernel.org/r/20250410235546.43736-4-dakr@kernel.org [ MISC changes * remove unnecessary DRM features; make remaining ones crate private * add #[expect(unused)] to avoid warnings * add sealed trait * remove shmem::Object references * original source archive: https://archive.is/Pl9ys - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-24rust: drm: ioctl: Add DRM ioctl abstractionAsahi Lina
DRM drivers need to be able to declare which driver-specific ioctls they support. Add an abstraction implementing the required types and a helper macro to generate the ioctl definition inside the DRM driver. Note that this macro is not usable until further bits of the abstraction are in place (but it will not fail to compile on its own, if not called). Signed-off-by: Asahi Lina <lina@asahilina.net> Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Lyude Paul <lyude@redhat.com> Link: https://lore.kernel.org/r/20250410235546.43736-3-dakr@kernel.org [ MISC fixes * wrap raw_data in Opaque to avoid UB when creating a reference * fix IOCTL sample declaration * fix safety comment of IOCTL argument * original source archive: https://archive.is/LqHDQ - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-23rust: alloc: replace `Vec::set_len` with `inc_len`Tamir Duberstein
Rename `set_len` to `inc_len` and simplify its safety contract. Note that the usage in `CString::try_from_fmt` remains correct as the receiver is known to have `len == 0`. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Signed-off-by: Tamir Duberstein <tamird@gmail.com> Link: https://lore.kernel.org/r/20250416-vec-set-len-v4-4-112b222604cd@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-23rust: alloc: refactor `Vec::truncate` using `dec_len`Tamir Duberstein
Use `checked_sub` to satisfy the safety requirements of `dec_len` and replace nearly the whole body of `truncate` with a call to `dec_len`. Reviewed-by: Andrew Ballance <andrewjballance@gmail.com> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Signed-off-by: Tamir Duberstein <tamird@gmail.com> Link: https://lore.kernel.org/r/20250416-vec-set-len-v4-3-112b222604cd@gmail.com [ Remove #[expect(unused)] from dec_len(). - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-23rust: alloc: add `Vec::dec_len`Tamir Duberstein
Add `Vec::dec_len` that reduces the length of the receiver. This method is intended to be used from methods that remove elements from `Vec` such as `truncate`, `pop`, `remove`, and others. This method is intentionally not `pub`. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Signed-off-by: Tamir Duberstein <tamird@gmail.com> Link: https://lore.kernel.org/r/20250416-vec-set-len-v4-2-112b222604cd@gmail.com [ Add #[expect(unused)] to dec_len(). - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-23rust: alloc: add Vec::len() <= Vec::capacity invariantTamir Duberstein
Document the invariant that the vector's length is always less than or equal to its capacity. This is already implied by these other invariants: - `self.len` always represents the exact number of elements stored in the vector. - `self.layout` represents the absolute number of elements that can be stored within the vector without re-allocation. but it doesn't hurt to spell it out. Note that the language references `self.capacity` rather than `self.layout.len` as the latter is zero for a vector of ZSTs. Update a safety comment touched by this patch to correctly reference `realloc` rather than `alloc` and replace "leaves" with "leave" to improve grammar. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Signed-off-by: Tamir Duberstein <tamird@gmail.com> Link: https://lore.kernel.org/r/20250416-vec-set-len-v4-1-112b222604cd@gmail.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-22rust: alloc: allow coercion from `Box<T>` to `Box<dyn U>` if T implements UAlexandre Courbot
This enables the creation of trait objects backed by a Box, similarly to what can be done with the standard library. Suggested-by: Benno Lossin <benno.lossin@proton.me> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://lore.kernel.org/r/20250412-box_trait_objs-v3-1-f67ced62d520@nvidia.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-22rust/revocable: add try_access_with() convenience methodAlexandre Courbot
Revocable::try_access() returns a guard through which the wrapped object can be accessed. Code that can sleep is not allowed while the guard is held; thus, it is common for the caller to explicitly drop it before running sleepable code, e.g: let b = bar.try_access()?; let reg = b.readl(...); // Don't forget this or things could go wrong! drop(b); something_that_might_sleep(); let b = bar.try_access()?; let reg2 = b.readl(...); This is arguably error-prone. try_access_with() provides an arguably safer alternative, by taking a closure that is run while the guard is held, and by dropping the guard automatically after the closure completes. This way, code can be organized more clearly around the critical sections and the risk of forgetting to release the guard when needed is considerably reduced: let reg = bar.try_access_with(|b| b.readl(...))?; something_that_might_sleep(); let reg2 = bar.try_access_with(|b| b.readl(...))?; The closure can return nothing, or any value including a Result which is then wrapped inside the Option returned by try_access_with. Error management is driver-specific, so users are encouraged to create their own macros that map and flatten the returned values to something appropriate for the code they are working on. Suggested-by: Danilo Krummrich <dakr@kernel.org> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com> Acked-by: Miguel Ojeda <ojeda@kernel.org> Link: https://lore.kernel.org/r/20250411-try_with-v4-1-f470ac79e2e2@nvidia.com [ Link `None`, `Some`, `Option` in doc-comment. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-19rust: auxiliary: add auxiliary registrationDanilo Krummrich
Implement the `auxiliary::Registration` type, which provides an API to create and register new auxiliary devices in the system. Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250414131934.28418-5-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-19rust: auxiliary: add auxiliary device / driver abstractionsDanilo Krummrich
Implement the basic auxiliary abstractions required to implement a driver matching an auxiliary device. The design and implementation is analogous to PCI and platform and is based on the generic device / driver abstractions. Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250414131934.28418-4-dakr@kernel.org [ Fix typos, `let _ =` => `drop()`, use `kernel::ffi`. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-19rust: device: implement Device::parent()Danilo Krummrich
Device::parent() returns a reference to the device' parent device, if any. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/r/20250414131934.28418-3-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-19rust: types: add `Opaque::zeroed`Danilo Krummrich
Analogous to `Opaque::uninit` add `Opaque::zeroed`, which sets the corresponding memory to zero. In contrast to `Opaque::uninit`, the corresponding value, depending on its type, may be initialized. Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Miguel Ojeda <ojeda@kernel.org> Link: https://lore.kernel.org/r/20250414131934.28418-2-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-19rust: platform: impl TryFrom<&Device> for &platform::DeviceDanilo Krummrich
Implement TryFrom<&device::Device> for &Device. This allows us to get a &platform::Device from a generic &Device in a safe way; the conversion fails if the device' bus type does not match with the platform bus type. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Link: https://lore.kernel.org/r/20250321214826.140946-4-dakr@kernel.org [ Support device context types, use dev_is_platform() helper. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-19rust: pci: impl TryFrom<&Device> for &pci::DeviceDanilo Krummrich
Implement TryFrom<&device::Device> for &Device. This allows us to get a &pci::Device from a generic &Device in a safe way; the conversion fails if the device' bus type does not match with the PCI bus type. Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Benno Lossin <benno.lossin@proton.me> Link: https://lore.kernel.org/r/20250321214826.140946-3-dakr@kernel.org [ Support device context types, use dev_is_pci() helper. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-17rust: dma: require a bound deviceDanilo Krummrich
Require the Bound device context to be able to create new dma::CoherentAllocation instances. DMA memory allocations are only valid to be created for bound devices. Link: https://lore.kernel.org/r/20250413173758.12068-10-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-17rust: devres: require a bound deviceDanilo Krummrich
Require the Bound device context to be able to a new Devres container. This ensures that we can't register devres callbacks for unbound devices. Link: https://lore.kernel.org/r/20250413173758.12068-9-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-17rust: pci: move iomap_region() to impl Device<Bound>Danilo Krummrich
Require the Bound device context to be able to call iomap_region() and iomap_region_sized(). Creating I/O mapping requires the device to be bound. Reviewed-by: Benno Lossin <benno.lossin@proton.me> Link: https://lore.kernel.org/r/20250413173758.12068-8-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2025-04-17rust: device: implement Bound device contextDanilo Krummrich
The Bound device context indicates that a device is bound to a driver. It must be used for APIs that require the device to be bound, such as Devres or dma::CoherentAllocation. Implement Bound and add the corresponding Deref hierarchy, as well as the corresponding ARef conversion for this device context. Reviewed-by: Benno Lossin <benno.lossin@proton.me> Link: https://lore.kernel.org/r/20250413173758.12068-7-dakr@kernel.org [ Add missing `::` prefix in macros. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>