Commit Graph

13 Commits

Author SHA1 Message Date
Philipp Stanner
97b281d7ed rust: list: Add unsafe blocks for container_of and safety comments
impl_list_item_mod.rs calls container_of! without unsafe blocks at a
couple of places. Since container_of! is unsafe, the blocks are strictly
necessary.

The problem was so far not visible because the "unsafe-op-in-unsafe-fn"
check is a lint rather than a hard compiler error, and Rust suppresses
lints triggered inside of a macro from another crate.

Thus, the error becomes only visible once someone from within the kernel
crate tries to use linked lists:

    error[E0133]: call to unsafe function `core::ptr::mut_ptr::<impl *mut T>::byte_sub`
    is unsafe and requires unsafe block
       --> rust/kernel/lib.rs:252:29
        |
    252 |           let container_ptr = field_ptr.byte_sub(offset).cast::<$Container>();
        |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
        |
       ::: rust/kernel/drm/jq.rs:98:1
        |
    98  | / impl_list_item! {
    99  | |     impl ListItem<0> for BasicItem { using ListLinks { self.links }; }
    100 | | }
        | |_- in this macro invocation
        |
    note: an unsafe function restricts its caller, but its body is safe by default
       --> rust/kernel/list/impl_list_item_mod.rs:216:13
        |
    216 |               unsafe fn view_value(me: *mut $crate::list::ListLinks<$num>) -> *const Self {
        |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
       ::: rust/kernel/drm/jq.rs:98:1
        |
    98  | / impl_list_item! {
    99  | |     impl ListItem<0> for BasicItem { using ListLinks { self.links }; }
    100 | | }
        | |_- in this macro invocation
        = note: requested on the command line with `-D unsafe-op-in-unsafe-fn`
        = note: this error originates in the macro `$crate::container_of` which comes
        from the expansion of the macro `impl_list_item`

Therefore, add unsafe blocks to container_of! calls to fix the issue.

[ As discussed, let's fix the build for those that want to use the
  macro within the `kernel` crate now and we can discuss the proper
  safety comments afterwards. Thus I removed the ones from the patch.

  However, we cannot just avoid the comments with `CLIPPY=1`, so I
  provided placeholders for now, like we did in the past. They were
  also needed for an `unsafe impl`.

  While I am not happy about it, it isn't worse than the current
  status (the comments were meant to be there), and at least this
  shows what is missing -- our pre-existing "good first issue" [1]
  may motivate new contributors to complete them properly.

  Finally, I moved one of the existing safety comments one line down
  so that Clippy could locate it.

  Link: https://github.com/Rust-for-Linux/linux/issues/351 [1]

    - Miguel ]

Cc: stable@vger.kernel.org
Fixes: c77f85b347 ("rust: list: remove OFFSET constants")
Suggested-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Philipp Stanner <phasta@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260216131613.45344-3-phasta@kernel.org
[ Fixed formatting. Reworded to fix the lint suppression
  explanation. Indent build error. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2026-02-20 01:59:51 +01:00
Miguel Ojeda
275ad5e793 rust: list: remove nonexistent generic parameter in link
`ListLinks` does not take a `T` generic parameter, unlike
`ListLinksSelfPtr`.

Thus fix it, which makes it also consistent with the rest of the links
in the file.

Fixes: 40c5329459 ("rust: list: add macro for implementing ListItem")
Reviewed-by: Tamir Duberstein <tamird@gmail.com>
Link: https://lore.kernel.org/r/20250719232500.822313-1-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-20 19:29:19 +02:00
Tamir Duberstein
c77f85b347 rust: list: remove OFFSET constants
Replace `ListLinksSelfPtr::LIST_LINKS_SELF_PTR_OFFSET` with `unsafe fn
raw_get_self_ptr` which returns a pointer to the field rather than
requiring the caller to do pointer arithmetic.

Implement `HasListLinks::raw_get_list_links` in `impl_has_list_links!`,
narrowing the interface of `HasListLinks` and replacing pointer
arithmetic with `container_of!`.

Modify `impl_list_item` to also invoke `impl_has_list_links!` or
`impl_has_list_links_self_ptr!`. This is necessary to allow
`impl_list_item` to see more of the tokens used by
`impl_has_list_links{,_self_ptr}!`.

A similar API change was discussed on the hrtimer series[1].

Link: https://lore.kernel.org/all/20250224-hrtimer-v3-v6-12-rc2-v9-1-5bd3bf0ce6cc@kernel.org/ [1]
Tested-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Link: https://lore.kernel.org/r/20250709-list-no-offset-v4-6-a429e75840a9@gmail.com
[ Fixed broken intra-doc links. Used the renamed
  `Opaque::cast_into`. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-19 23:18:18 +02:00
Tamir Duberstein
5d840b4c49 rust: list: add impl_list_item! examples
There's a comprehensive example in `rust/kernel/list.rs` but it doesn't
exercise the `using ListLinksSelfPtr` variant nor the generic cases. Add
that here. Generalize `impl_has_list_links_self_ptr` to handle nested
fields in the same manner as `impl_has_list_links`.

Tested-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Link: https://lore.kernel.org/r/20250709-list-no-offset-v4-5-a429e75840a9@gmail.com
[ Fixed Rust < 1.82 build by enabling the `offset_of_nested`
  feature. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-19 23:18:18 +02:00
Tamir Duberstein
6a13057d50 rust: list: use fully qualified path
Use a fully qualified path rooted at `$crate` rather than relying on
imports in the invoking scope.

Tested-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Link: https://lore.kernel.org/r/20250709-list-no-offset-v4-4-a429e75840a9@gmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-19 23:18:18 +02:00
Tamir Duberstein
9e626edd7b rust: list: use consistent self parameter name
Refer to the self parameter of `impl_list_item!` by the same name used
in `impl_has_list_links{,_self_ptr}!`.

Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com>
Tested-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Link: https://lore.kernel.org/r/20250709-list-no-offset-v4-3-a429e75840a9@gmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-19 23:18:18 +02:00
Tamir Duberstein
9cec86e4ae rust: list: use consistent type parameter style
Refer to the type parameters of `impl_has_list_links{,_self_ptr}!` by
the same name used in `impl_list_item!`. Capture type parameters of
`impl_list_item!` as `tt` using `{}` to match the style of all other
macros that work with generics.

Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com>
Tested-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Link: https://lore.kernel.org/r/20250709-list-no-offset-v4-2-a429e75840a9@gmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-19 23:18:18 +02:00
Tamir Duberstein
e71d7e39be rust: list: simplify macro capture
Avoid manually capturing generics; use `ty` to capture the whole type
instead.

Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com>
Tested-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Link: https://lore.kernel.org/r/20250709-list-no-offset-v4-1-a429e75840a9@gmail.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-19 23:18:18 +02:00
Miguel Ojeda
b0c7d8c9e8 rust: list: undo unintended replacement of method name
When we renamed `Opaque::raw_get` to `cast_into`, there was one
replacement that was not supposed to be there.

It does not cause an issue so far because it is inside a macro rule (the
`ListLinksSelfPtr` one) that is unused so far. However, it will start
to be used soon.

Thus fix it now.

Fixes: 64fb810bce ("rust: types: rename Opaque::raw_get to cast_into")
Reviewed-by: Tamir Duberstein <tamird@gmail.com>
Link: https://lore.kernel.org/r/20250719183649.596051-1-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-19 23:18:16 +02:00
Alice Ryhl
64fb810bce rust: types: rename Opaque::raw_get to cast_into
In the previous patch we added Opaque::cast_from() that performs the
opposite operation to Opaque::raw_get(). For consistency with this
naming, rename raw_get() to cast_from().

There are a few other options such as calling cast_from() something
closer to raw_get() rather than renaming this method. However, I could
not find a great naming scheme that works with raw_get(). The previous
version of this patch used from_raw(), but functions of that name
typically have a different signature, so that's not a great option.

Suggested-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Acked-by: Benno Lossin <lossin@kernel.org>
Acked-by: Andreas Hindborg <a.hindborg@kernel.org>
Acked-by: Boqun Feng <boqun.feng@gmail.com>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20250624-opaque-from-raw-v2-2-e4da40bdc59c@google.com
[ Removed `HrTimer::raw_get` change. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-15 22:26:11 +02:00
Tamir Duberstein
fcad9bbf9e rust: enable clippy::ptr_as_ptr lint
In Rust 1.51.0, Clippy introduced the `ptr_as_ptr` lint [1]:

> Though `as` casts between raw pointers are not terrible,
> `pointer::cast` is safer because it cannot accidentally change the
> pointer's mutability, nor cast the pointer to other types like `usize`.

There are a few classes of changes required:
- Modules generated by bindgen are marked
  `#[allow(clippy::ptr_as_ptr)]`.
- Inferred casts (` as _`) are replaced with `.cast()`.
- Ascribed casts (` as *... T`) are replaced with `.cast::<T>()`.
- Multistep casts from references (` as *const _ as *const T`) are
  replaced with `core::ptr::from_ref(&x).cast()` with or without `::<T>`
  according to the previous rules. The `core::ptr::from_ref` call is
  required because `(x as *const _).cast::<T>()` results in inference
  failure.
- Native literal C strings are replaced with `c_str!().as_char_ptr()`.
- `*mut *mut T as _` is replaced with `let *mut *const T = (*mut *mut
  T)`.cast();` since pointer to pointer can be confusing.

Apply these changes and enable the lint -- no functional change
intended.

Link: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr [1]
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20250615-ptr-as-ptr-v12-1-f43b024581e8@gmail.com
[ Added `.cast()` for `opp`. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-06-22 23:08:42 +02:00
Alice Ryhl
2003c04b05 rust: list: support heterogeneous lists
Support linked lists that can hold many different structs at once. This
is generally done using trait objects. The main challenge is figuring
what the struct is given only a pointer to the ListLinks.

We do this by storing a pointer to the struct next to the ListLinks
field. The container_of operation will then just read that pointer. When
the type is a trait object, that pointer will be a fat pointer whose
metadata is a vtable that tells you what kind of struct it is.

Heterogeneous lists are heavily used by Rust Binder. There are a lot of
so-called todo lists containing various events that need to be delivered
to userspace next time userspace calls into the driver. And there are
quite a few different todo item types: incoming transaction, changes to
refcounts, death notifications, and more.

Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20240814-linked-list-v5-9-f5f5e8075da0@google.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-08-23 06:26:57 +02:00
Alice Ryhl
40c5329459 rust: list: add macro for implementing ListItem
Adds a macro for safely implementing the ListItem trait. As part of the
implementation of the macro, we also provide a HasListLinks trait
similar to the workqueue's HasWorkItem trait.

The HasListLinks trait is only necessary if you are implementing
ListItem using the impl_list_item macro.

Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/r/20240814-linked-list-v5-5-f5f5e8075da0@google.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2024-08-23 06:26:57 +02:00