Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rust: drm: add DRM driver registration

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>

authored by

Asahi Lina and committed by
Danilo Krummrich
0600032c 1e4b8896

+60 -1
+59 -1
rust/kernel/drm/driver.rs
··· 4 4 //! 5 5 //! C header: [`include/linux/drm/drm_drv.h`](srctree/include/linux/drm/drm_drv.h) 6 6 7 - use crate::{bindings, drm, str::CStr}; 7 + use crate::{ 8 + bindings, device, 9 + devres::Devres, 10 + drm, 11 + error::{to_result, Result}, 12 + prelude::*, 13 + str::CStr, 14 + types::ARef, 15 + }; 8 16 use macros::vtable; 9 17 10 18 /// Driver use the GEM memory manager. This should be set for all modern drivers. ··· 110 102 111 103 /// IOCTL list. See `kernel::drm::ioctl::declare_drm_ioctls!{}`. 112 104 const IOCTLS: &'static [drm::ioctl::DrmIoctlDescriptor]; 105 + } 106 + 107 + /// The registration type of a `drm::Device`. 108 + /// 109 + /// Once the `Registration` structure is dropped, the device is unregistered. 110 + pub struct Registration<T: Driver>(ARef<drm::Device<T>>); 111 + 112 + impl<T: Driver> Registration<T> { 113 + /// Creates a new [`Registration`] and registers it. 114 + fn new(drm: &drm::Device<T>, flags: usize) -> Result<Self> { 115 + // SAFETY: `drm.as_raw()` is valid by the invariants of `drm::Device`. 116 + to_result(unsafe { bindings::drm_dev_register(drm.as_raw(), flags) })?; 117 + 118 + Ok(Self(drm.into())) 119 + } 120 + 121 + /// Same as [`Registration::new`}, but transfers ownership of the [`Registration`] to 122 + /// [`Devres`]. 123 + pub fn new_foreign_owned( 124 + drm: &drm::Device<T>, 125 + dev: &device::Device<device::Bound>, 126 + flags: usize, 127 + ) -> Result { 128 + if drm.as_ref().as_raw() != dev.as_raw() { 129 + return Err(EINVAL); 130 + } 131 + 132 + let reg = Registration::<T>::new(drm, flags)?; 133 + Devres::new_foreign_owned(dev, reg, GFP_KERNEL) 134 + } 135 + 136 + /// Returns a reference to the `Device` instance for this registration. 137 + pub fn device(&self) -> &drm::Device<T> { 138 + &self.0 139 + } 140 + } 141 + 142 + // SAFETY: `Registration` doesn't offer any methods or access to fields when shared between 143 + // threads, hence it's safe to share it. 144 + unsafe impl<T: Driver> Sync for Registration<T> {} 145 + 146 + // SAFETY: Registration with and unregistration from the DRM subsystem can happen from any thread. 147 + unsafe impl<T: Driver> Send for Registration<T> {} 148 + 149 + impl<T: Driver> Drop for Registration<T> { 150 + fn drop(&mut self) { 151 + // SAFETY: Safe by the invariant of `ARef<drm::Device<T>>`. The existence of this 152 + // `Registration` also guarantees the this `drm::Device` is actually registered. 153 + unsafe { bindings::drm_dev_unregister(self.0.as_raw()) }; 154 + } 113 155 }
+1
rust/kernel/drm/mod.rs
··· 9 9 pub use self::device::Device; 10 10 pub use self::driver::Driver; 11 11 pub use self::driver::DriverInfo; 12 + pub use self::driver::Registration; 12 13 13 14 pub(crate) mod private { 14 15 pub trait Sealed {}