A DRM registration whose associated data is 'static cannot outlive any
references held by that data. Add a safe constructor for this common
case so drivers do not have to promise manually that their registration
will never be forgotten.

Keep the existing unsafe constructor for registration data which
genuinely borrows from the bus binding.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Mike Lothian <[email protected]>
---
 rust/kernel/drm/driver.rs | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/rust/kernel/drm/driver.rs b/rust/kernel/drm/driver.rs
index 356be329a2b6..2e7987a71a7a 100644
--- a/rust/kernel/drm/driver.rs
+++ b/rust/kernel/drm/driver.rs
@@ -169,7 +169,8 @@ pub struct Registration<'a, T: Driver> {
 }
 
 impl<'a, T: Driver> Registration<'a, T> {
-    /// Register a new [`UnregisteredDevice`](drm::UnregisteredDevice) with 
userspace.
+    /// Registers a new [`UnregisteredDevice`](drm::UnregisteredDevice) with 
borrowed
+    /// registration data.
     ///
     /// # Safety
     ///
@@ -177,7 +178,7 @@ impl<'a, T: Driver> Registration<'a, T> {
     /// [`Drop`] implementation from running, since the registration data may 
contain borrowed
     /// references that become invalid after `'a` ends.
     pub unsafe fn new<E>(
-        dev: &'a device::Device<device::Bound>,
+        dev: &device::Device<device::Bound>,
         drm: drm::UnregisteredDevice<T>,
         reg_data: impl PinInit<T::RegistrationData<'a>, E>,
         flags: usize,
@@ -243,6 +244,29 @@ pub fn device(&self) -> &drm::Device<T> {
     }
 }
 
+impl<T: Driver> Registration<'static, T> {
+    /// Registers a new [`UnregisteredDevice`](drm::UnregisteredDevice) with 
owned registration
+    /// data.
+    ///
+    /// Unlike [`Registration::new`], this constructor is safe because its 
registration
+    /// data cannot contain non-static references. Forgetting the returned 
registration can leak
+    /// the DRM device and its parent reference, but cannot leave a live 
registration referring to
+    /// expired data.
+    pub fn new_static<E>(
+        dev: &device::Device<device::Bound>,
+        drm: drm::UnregisteredDevice<T>,
+        reg_data: impl PinInit<T::RegistrationData<'static>, E>,
+        flags: usize,
+    ) -> Result<Self>
+    where
+        Error: From<E>,
+    {
+        // SAFETY: `RegistrationData<'static>` cannot borrow data that expires 
while a forgotten
+        // registration remains accessible.
+        unsafe { Self::new(dev, drm, reg_data, flags) }
+    }
+}
+
 // SAFETY: `Registration` doesn't offer any methods or access to fields when 
shared between
 // threads, hence it's safe to share it.
 unsafe impl<T: Driver> Sync for Registration<'_, T> {}

Reply via email to