On Sun May 17, 2026 at 1:01 AM BST, Danilo Krummrich wrote:
> Generalize Registration<T> to Registration<F: ForLt> and
> Device::registration_data<F: ForLt>() to return Pin<&F::Of<'_>>.
>
> The stored 'static lifetime is shortened to the borrow lifetime of &self
> via ForLt::cast_ref; ForLt's covariance guarantee makes this sound.
>
> Signed-off-by: Danilo Krummrich <[email protected]>
> ---
>  drivers/gpu/nova-core/driver.rs       |  4 +-
>  rust/kernel/auxiliary.rs              | 68 +++++++++++++++++----------
>  samples/rust/rust_driver_auxiliary.rs |  8 ++--
>  3 files changed, 52 insertions(+), 28 deletions(-)
>
> [snip]
>
> @@ -389,43 +399,51 @@ struct RegistrationData<T> {
>  /// This type represents the registration of a [`struct auxiliary_device`]. 
> When its parent device
>  /// is unbound, the corresponding auxiliary device will be unregistered from 
> the system.
>  ///
> -/// The type parameter `T` is the type of the registration data owned by the 
> registering (parent)
> -/// driver. It can be accessed by the auxiliary driver through
> -/// [`Device::registration_data()`].
> +/// The type parameter `F` is a [`ForLt`](trait@ForLt) encoding of the 
> registration
> +/// data type. For non-lifetime-parameterized types, use 
> [`ForLt!(T)`](macro@ForLt).
> +/// The data can be accessed by the auxiliary driver through 
> [`Device::registration_data()`].
>  ///
>  /// # Invariants
>  ///
>  /// `self.adev` always holds a valid pointer to an initialized and registered
>  /// [`struct auxiliary_device`] whose `registration_data_rust` field points 
> to a
> -/// valid `Pin<KBox<RegistrationData<T>>>`.
> -pub struct Registration<T: 'static> {
> +/// valid `Pin<KBox<RegistrationData<F::Of<'static>>>>`.
> +pub struct Registration<F: ForLt> {
>      adev: NonNull<bindings::auxiliary_device>,
> -    _data: PhantomData<T>,
> +    _data: PhantomData<F>,
>  }
>  
> -impl<T: Send + Sync + 'static> Registration<T> {
> +impl<F: ForLt> Registration<F>
> +where
> +    for<'a> F::Of<'a>: Send + Sync,
> +{
>      /// Create and register a new auxiliary device with the given 
> registration data.
>      ///
>      /// The `data` is owned by the registration and can be accessed through 
> the auxiliary device
>      /// via [`Device::registration_data()`].
> -    pub fn new<E>(
> -        parent: &device::Device<device::Bound>,
> +    pub fn new<'bound, E>(
> +        parent: &'bound device::Device<device::Bound>,
>          name: &CStr,
>          id: u32,
>          modname: &CStr,
> -        data: impl PinInit<T, E>,
> +        data: impl PinInit<F::Of<'bound>, E>,
>      ) -> Result<Devres<Self>>

I think this is unsound for the reason that I gave in another email
https://lore.kernel.org/rust-for-linux/[email protected]/.

Best,
Gary

>      where
>          Error: From<E>,
>      {
>          let data = KBox::pin_init::<Error>(
>              try_pin_init!(RegistrationData {
> -                type_id: TypeId::of::<T>(),
> +                type_id: TypeId::of::<F::Of<'static>>(),
>                  data <- data,
>              }),
>              GFP_KERNEL,
>          )?;
>  
> +        // SAFETY: Lifetimes are erased and do not affect layout, so 
> RegistrationData<F::Of<'bound>>
> +        // and RegistrationData<F::Of<'static>> have identical 
> representation.
> +        let data: Pin<KBox<RegistrationData<F::Of<'static>>>> =
> +            unsafe { core::mem::transmute(data) };
> +
>          let boxed: KBox<Opaque<bindings::auxiliary_device>> = 
> KBox::zeroed(GFP_KERNEL)?;
>          let adev = boxed.get();
>  
> @@ -455,7 +473,9 @@ pub fn new<E>(
>          if ret != 0 {
>              // SAFETY: `registration_data` was set above via 
> `into_foreign()`.
>              drop(unsafe {
> -                
> Pin::<KBox<RegistrationData<T>>>::from_foreign((*adev).registration_data_rust)
> +                Pin::<KBox<RegistrationData<F::Of<'static>>>>::from_foreign(
> +                    (*adev).registration_data_rust,
> +                )
>              });
>  
>              // SAFETY: `adev` is guaranteed to be a valid pointer to a
> @@ -478,7 +498,7 @@ pub fn new<E>(
>      }
>  }

Reply via email to