On Sun Jun 28, 2026 at 11:53 PM JST, Danilo Krummrich wrote: > Add a faux::Device type that wraps struct faux_device and implements > AsBusDevice, enabling faux devices to be used as parent devices for > subsystems that require a bus device, such as DRM. > > Update Registration to return &faux::Device<Bound> via AsRef. > > Signed-off-by: Danilo Krummrich <[email protected]>
Reviewed-by: Alexandre Courbot <[email protected]> (one small comment below) > --- > rust/kernel/drm/gem/shmem.rs | 11 +++-- > rust/kernel/faux.rs | 69 +++++++++++++++++++++++++++----- > samples/rust/rust_driver_faux.rs | 3 +- > 3 files changed, 68 insertions(+), 15 deletions(-) > > diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs > index 3ee19ef6264e..52de59b14dad 100644 > --- a/rust/kernel/drm/gem/shmem.rs > +++ b/rust/kernel/drm/gem/shmem.rs > @@ -692,10 +692,12 @@ impl drm::Driver for KunitDriver { > fn create_drm_dev() -> Result<(faux::Registration, > UnregisteredDevice<KunitDriver>)> { > // Create a faux DRM device so we can test gem object creation. > let data = try_pin_init!(KunitData {}); > - let dev = faux::Registration::new(c"Kunit", None)?; > - let drm = UnregisteredDevice::new(dev.as_ref(), data)?; > + let reg = faux::Registration::new(c"Kunit", None)?; > + let fdev = reg.as_ref(); > + let dev = fdev.as_ref(); > + let drm = UnregisteredDevice::new(dev, data)?; > > - Ok((dev, drm)) > + Ok((reg, drm)) > } > > #[test] > @@ -755,7 +757,8 @@ fn vmap_io() -> Result { > #[test] > fn fail_sg_table_on_wrong_dev() -> Result { > let (_dev, drm) = create_drm_dev()?; > - let wrong_dev = faux::Registration::new(c"EvilKunit", None)?; > + let reg = faux::Registration::new(c"EvilKunit", None)?; > + let wrong_dev = reg.as_ref(); > > let obj = Object::<KunitObject, _>::new(&drm, PAGE_SIZE, > ObjectConfig::default(), ())?; > > diff --git a/rust/kernel/faux.rs b/rust/kernel/faux.rs > index 36c92ae2943c..cd0724af446b 100644 > --- a/rust/kernel/faux.rs > +++ b/rust/kernel/faux.rs > @@ -9,15 +9,63 @@ > use crate::{ > bindings, > device, > - prelude::*, // > + prelude::*, > + types::Opaque, // > }; > -use core::ptr::{ > - addr_of_mut, > - null, > - null_mut, > - NonNull, // > +use core::{ > + marker::PhantomData, > + ptr::{ > + null, > + null_mut, > + NonNull, // > + }, > }; > > +/// A faux device. > +/// > +/// A faux device is a virtual device backed by the faux bus, primarily used > for scenarios where a > +/// real hardware device is not available or for testing. > +/// > +/// # Invariants > +/// > +/// The underlying `struct faux_device` is valid and the embedded `struct > device` is initialized. > +#[repr(transparent)] > +pub struct Device<Ctx: device::DeviceContext = device::Normal>( > + Opaque<bindings::faux_device>, > + PhantomData<Ctx>, > +); > + > +impl<Ctx: device::DeviceContext> Device<Ctx> { > + #[inline] > + fn as_raw(&self) -> *mut bindings::faux_device { > + self.0.get() > + } > + > + /// # Safety > + /// > + /// `ptr` must be a valid pointer to a `struct faux_device`. The invariant for `Device` also says: "... and the embedded `struct device` is valid". IIUC this requirement should also be mentioned here, unless we consider that a valid `struct faux_device` also implies that its embedded `struct device` is initialized, in which case that bit can be removed from the invariant section of `Device`.
