Guest User

Untitled

a guest
Apr 10th, 2025
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 59.47 KB | None | 0 0
  1. diff --git a/rust/kernel/drm/device.rs b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/device.rs
  2. index 90e0ff6d5915..c5a279e63010 100644
  3. --- a/rust/kernel/drm/device.rs
  4. +++ b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/device.rs
  5. @@ -2,72 +2,194 @@
  6.  
  7.  //! DRM device.
  8.  //!
  9. -//! C header: [`include/drm/drm_device.h`](../../../../include/drm/drm_device.h)
  10. +//! C header: [`include/linux/drm/drm_device.h`](srctree/include/linux/drm/drm_device.h)
  11.  
  12.  use crate::{
  13.      bindings, device, drm,
  14. -    types::{AlwaysRefCounted, ForeignOwnable},
  15. +    drm::driver::AllocImpl,
  16. +    error::from_err_ptr,
  17. +    error::Result,
  18. +    prelude::*,
  19. +    types::{ARef, AlwaysRefCounted, Opaque},
  20.  };
  21. -use core::cell::UnsafeCell;
  22. -use core::marker::PhantomData;
  23. -use core::ptr::NonNull;
  24. -
  25. -/// A typed DRM device with a specific driver. The device is always reference-counted.
  26. -#[repr(transparent)]
  27. -pub struct Device<T: drm::drv::Driver> {
  28. -    pub(super) drm: UnsafeCell<bindings::drm_device>,
  29. -    _p: PhantomData<T>,
  30. +use core::{mem, ops::Deref, ptr, ptr::NonNull};
  31. +
  32. +#[cfg(CONFIG_DRM_LEGACY)]
  33. +macro_rules! drm_legacy_fields {
  34. +    ( $($field:ident: $val:expr),* $(,)? ) => {
  35. +        bindings::drm_driver {
  36. +            $( $field: $val ),*,
  37. +            firstopen: None,
  38. +            preclose: None,
  39. +            dma_ioctl: None,
  40. +            dma_quiescent: None,
  41. +            context_dtor: None,
  42. +            irq_handler: None,
  43. +            irq_preinstall: None,
  44. +            irq_postinstall: None,
  45. +            irq_uninstall: None,
  46. +            get_vblank_counter: None,
  47. +            enable_vblank: None,
  48. +            disable_vblank: None,
  49. +            dev_priv_size: 0,
  50. +        }
  51. +    }
  52.  }
  53.  
  54. -impl<T: drm::drv::Driver> Device<T> {
  55. -    #[allow(dead_code, clippy::mut_from_ref)]
  56. -    pub(crate) unsafe fn raw_mut(&self) -> &mut bindings::drm_device {
  57. -        // SAFETY: Depends on safe usage by the caller
  58. -        unsafe { &mut *self.drm.get() }
  59. +#[cfg(not(CONFIG_DRM_LEGACY))]
  60. +macro_rules! drm_legacy_fields {
  61. +    ( $($field:ident: $val:expr),* $(,)? ) => {
  62. +        bindings::drm_driver {
  63. +            $( $field: $val ),*
  64. +        }
  65.      }
  66. +}
  67. +
  68. +/// A typed DRM device with a specific `drm::Driver` implementation. The device is always
  69. +/// reference-counted.
  70. +#[repr(C)]
  71. +#[pin_data]
  72. +pub struct Device<T: drm::Driver> {
  73. +    dev: Opaque<bindings::drm_device>,
  74. +    #[pin]
  75. +    data: T::Data,
  76. +}
  77. +
  78. +impl<T: drm::Driver> Device<T> {
  79. +    const VTABLE: bindings::drm_driver = drm_legacy_fields! {
  80. +        load: None,
  81. +        open: Some(drm::File::<T::File>::open_callback),
  82. +        postclose: Some(drm::File::<T::File>::postclose_callback),
  83. +        unload: None,
  84. +        release: None,
  85. +        master_set: None,
  86. +        master_drop: None,
  87. +        debugfs_init: None,
  88. +        gem_create_object: T::Object::ALLOC_OPS.gem_create_object,
  89. +        prime_handle_to_fd: T::Object::ALLOC_OPS.prime_handle_to_fd,
  90. +        prime_fd_to_handle: T::Object::ALLOC_OPS.prime_fd_to_handle,
  91. +        gem_prime_import: T::Object::ALLOC_OPS.gem_prime_import,
  92. +        gem_prime_import_sg_table: T::Object::ALLOC_OPS.gem_prime_import_sg_table,
  93. +        dumb_create: T::Object::ALLOC_OPS.dumb_create,
  94. +        dumb_map_offset: T::Object::ALLOC_OPS.dumb_map_offset,
  95. +        show_fdinfo: None,
  96. +        fbdev_probe: None,
  97. +
  98. +        major: T::INFO.major,
  99. +        minor: T::INFO.minor,
  100. +        patchlevel: T::INFO.patchlevel,
  101. +        name: T::INFO.name.as_char_ptr() as *mut _,
  102. +        desc: T::INFO.desc.as_char_ptr() as *mut _,
  103.  
  104. -    // Not intended to be called externally, except via declare_drm_ioctls!()
  105. +        driver_features: drm::driver::FEAT_GEM,
  106. +        ioctls: T::IOCTLS.as_ptr(),
  107. +        num_ioctls: T::IOCTLS.len() as i32,
  108. +        fops: &Self::GEM_FOPS as _,
  109. +    };
  110. +
  111. +    const GEM_FOPS: bindings::file_operations = drm::gem::create_fops();
  112. +
  113. +    /// Create a new `drm::Device` for a `drm::Driver`.
  114. +    pub fn new(dev: &device::Device, data: impl PinInit<T::Data, Error>) -> Result<ARef<Self>> {
  115. +        // SAFETY:
  116. +        // - `VTABLE`, as a `const` is pinned to the read-only section of the compilation,
  117. +        // - `dev` is valid by its type invarants,
  118. +        let raw_drm: *mut Self = unsafe {
  119. +            bindings::__drm_dev_alloc(
  120. +                dev.as_raw(),
  121. +                &Self::VTABLE,
  122. +                mem::size_of::<Self>(),
  123. +                mem::offset_of!(Self, dev),
  124. +            )
  125. +        }
  126. +        .cast();
  127. +        let raw_drm = NonNull::new(from_err_ptr(raw_drm)?).ok_or(ENOMEM)?;
  128. +
  129. +        // SAFETY: `raw_drm` is a valid pointer to `Self`.
  130. +        let raw_data = unsafe { ptr::addr_of_mut!((*raw_drm.as_ptr()).data) };
  131. +
  132. +        // SAFETY:
  133. +        // - `raw_data` is a valid pointer to uninitialized memory.
  134. +        // - `raw_data` will not move until it is dropped.
  135. +        unsafe { data.__pinned_init(raw_data) }.inspect_err(|_| {
  136. +            // SAFETY: `__drm_dev_alloc()` was successful, hence `raw_drm` must be valid and the
  137. +            // refcount must be non-zero.
  138. +            unsafe { bindings::drm_dev_put(ptr::addr_of_mut!((*raw_drm.as_ptr()).dev).cast()) };
  139. +        })?;
  140. +
  141. +        // SAFETY: The reference count is one, and now we take ownership of that reference as a
  142. +        // `drm::Device`.
  143. +        Ok(unsafe { ARef::from_raw(raw_drm) })
  144. +    }
  145. +
  146. +    pub(crate) fn as_raw(&self) -> *mut bindings::drm_device {
  147. +        self.dev.get()
  148. +    }
  149. +
  150. +    /// # Safety
  151. +    ///
  152. +    /// `ptr` must be a valid poiner to a `struct device` embedded in `Self`.
  153. +    unsafe fn from_drm_device(ptr: *const bindings::drm_device) -> *mut Self {
  154. +        // SAFETY: By the safety requirements of this function `ptr` is a valid pointer to a
  155. +        // `struct drm_device` embedded in `Self`.
  156. +        unsafe { crate::container_of!(ptr, Self, dev) }.cast_mut()
  157. +    }
  158. +
  159. +    /// Not intended to be called externally, except via declare_drm_ioctls!()
  160. +    ///
  161. +    /// # Safety
  162. +    ///
  163. +    /// Callers must ensure that `ptr` is valid, non-null, and has a non-zero reference count,
  164. +    /// i.e. it must be ensured that the reference count of the C `struct drm_device` `ptr` points
  165. +    /// to can't drop to zero, for the duration of this function call and the entire duration when
  166. +    /// the returned reference exists.
  167. +    ///
  168. +    /// Additionally, callers must ensure that the `struct device`, `ptr` is pointing to, is
  169. +    /// embedded in `Self`.
  170.      #[doc(hidden)]
  171. -    pub unsafe fn borrow<'a>(raw: *const bindings::drm_device) -> &'a Self {
  172. -        // SAFETY: Hidden helper, depends on safe usage by the caller
  173. -        unsafe { &*(raw as *const Self) }
  174. +    pub unsafe fn as_ref<'a>(ptr: *const bindings::drm_device) -> &'a Self {
  175. +        // SAFETY: By the safety requirements of this function `ptr` is a valid pointer to a
  176. +        // `struct drm_device` embedded in `Self`.
  177. +        let ptr = unsafe { Self::from_drm_device(ptr) };
  178. +
  179. +        // SAFETY: `ptr` is valid by the safety requirements of this function.
  180. +        unsafe { &*ptr.cast() }
  181.      }
  182. +}
  183. +
  184. +impl<T: drm::Driver> Deref for Device<T> {
  185. +    type Target = T::Data;
  186.  
  187. -    /// Returns a borrowed reference to the user data associated with this Device.
  188. -    pub fn data(&self) -> <T::Data as ForeignOwnable>::Borrowed<'_> {
  189. -        // SAFETY: dev_private is guaranteed to be initialized for all
  190. -        // Device objects exposed to users.
  191. -        unsafe { T::Data::borrow((*self.drm.get()).dev_private) }
  192. +    fn deref(&self) -> &Self::Target {
  193. +        &self.data
  194.      }
  195.  }
  196.  
  197.  // SAFETY: DRM device objects are always reference counted and the get/put functions
  198.  // satisfy the requirements.
  199. -unsafe impl<T: drm::drv::Driver> AlwaysRefCounted for Device<T> {
  200. +unsafe impl<T: drm::Driver> AlwaysRefCounted for Device<T> {
  201.      fn inc_ref(&self) {
  202. -        // SAFETY: We already have a reference per the contract.
  203. -        unsafe { bindings::drm_dev_get(&self.drm as *const _ as *mut _) };
  204. +        // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
  205. +        unsafe { bindings::drm_dev_get(self.as_raw()) };
  206.      }
  207.  
  208.      unsafe fn dec_ref(obj: NonNull<Self>) {
  209. -        // SAFETY: The Device<T> type has the same layout as drm_device,
  210. -        // so we can just cast.
  211. -        unsafe { bindings::drm_dev_put(obj.as_ptr() as *mut _) };
  212. +        // SAFETY: The safety requirements guarantee that the refcount is non-zero.
  213. +        unsafe { bindings::drm_dev_put(obj.cast().as_ptr()) };
  214.      }
  215.  }
  216.  
  217. -// SAFETY: `Device` only holds a pointer to a C device, which is safe to be used from any thread.
  218. -unsafe impl<T: drm::drv::Driver> Send for Device<T> {}
  219. -
  220. -// SAFETY: `Device` only holds a pointer to a C device, references to which are safe to be used
  221. -// from any thread.
  222. -unsafe impl<T: drm::drv::Driver> Sync for Device<T> {}
  223. -
  224. -// Make drm::Device work for dev_info!() and friends
  225. -// SAFETY: dev is initialized by C for all Device objects
  226. -unsafe impl<T: drm::drv::Driver> device::RawDevice for Device<T> {
  227. -    fn raw_device(&self) -> *mut bindings::device {
  228. -        // SAFETY: dev is initialized by C for all Device objects
  229. -        unsafe { (*self.drm.get()).dev }
  230. +impl<T: drm::Driver> AsRef<device::Device> for Device<T> {
  231. +    fn as_ref(&self) -> &device::Device {
  232. +        // SAFETY: `bindings::drm_device::dev` is valid as long as the DRM device itself is valid,
  233. +        // which is guaranteed by the type invariant.
  234. +        unsafe { device::Device::as_ref((*self.as_raw()).dev) }
  235.      }
  236.  }
  237. +
  238. +// SAFETY: A `drm::Device` can be released from any thread.
  239. +unsafe impl<T: drm::Driver> Send for Device<T> {}
  240. +
  241. +// SAFETY: A `drm::Device` can be shared among threads because all immutable methods are protected
  242. +// by the synchronization in `struct drm_device`.
  243. +unsafe impl<T: drm::Driver> Sync for Device<T> {}
  244. diff --git a/rust/kernel/drm/driver.rs b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/driver.rs
  245. index fe4441a2c41d..9d234b08a888 100644
  246. --- a/rust/kernel/drm/driver.rs
  247. +++ b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/driver.rs
  248. @@ -2,46 +2,21 @@
  249.  
  250.  //! DRM driver core.
  251.  //!
  252. -//! C header: [`include/drm/drm_drv.h`](../../../../include/drm/drm_drv.h)
  253. +//! C header: [`include/linux/drm/drm_drv.h`](srctree/include/linux/drm/drm_drv.h)
  254.  
  255.  use crate::{
  256. -    alloc::{box_ext::BoxExt, flags::*},
  257. -    bindings, device, drm,
  258. -    error::code::*,
  259. -    error::from_err_ptr,
  260. +    bindings, device,
  261. +    devres::Devres,
  262. +    drm,
  263.      error::{Error, Result},
  264.      prelude::*,
  265. -    private::Sealed,
  266.      str::CStr,
  267. -    types::{ARef, ForeignOwnable},
  268. -    ThisModule,
  269. -};
  270. -use core::{
  271. -    marker::{PhantomData, PhantomPinned},
  272. -    pin::Pin,
  273. -    ptr::NonNull,
  274. +    types::ARef,
  275.  };
  276.  use macros::vtable;
  277.  
  278.  /// Driver use the GEM memory manager. This should be set for all modern drivers.
  279.  pub const FEAT_GEM: u32 = bindings::drm_driver_feature_DRIVER_GEM;
  280. -/// Driver supports mode setting interfaces (KMS).
  281. -pub const FEAT_MODESET: u32 = bindings::drm_driver_feature_DRIVER_MODESET;
  282. -/// Driver supports dedicated render nodes.
  283. -pub const FEAT_RENDER: u32 = bindings::drm_driver_feature_DRIVER_RENDER;
  284. -/// Driver supports the full atomic modesetting userspace API.
  285. -///
  286. -/// Drivers which only use atomic internally, but do not support the full userspace API (e.g. not
  287. -/// all properties converted to atomic, or multi-plane updates are not guaranteed to be tear-free)
  288. -/// should not set this flag.
  289. -pub const FEAT_ATOMIC: u32 = bindings::drm_driver_feature_DRIVER_ATOMIC;
  290. -/// Driver supports DRM sync objects for explicit synchronization of command submission.
  291. -pub const FEAT_SYNCOBJ: u32 = bindings::drm_driver_feature_DRIVER_SYNCOBJ;
  292. -/// Driver supports the timeline flavor of DRM sync objects for explicit synchronization of command
  293. -/// submission.
  294. -pub const FEAT_SYNCOBJ_TIMELINE: u32 = bindings::drm_driver_feature_DRIVER_SYNCOBJ_TIMELINE;
  295. -/// Driver uses the GEM GPUVA manager.
  296. -pub const FEAT_GEM_GPUVA: u32 = bindings::drm_driver_feature_DRIVER_GEM_GPUVA;
  297.  
  298.  /// Information data for a DRM Driver.
  299.  pub struct DriverInfo {
  300. @@ -55,8 +30,6 @@ pub struct DriverInfo {
  301.      pub name: &'static CStr,
  302.      /// Driver description.
  303.      pub desc: &'static CStr,
  304. -    /// Driver date.
  305. -    pub date: &'static CStr,
  306.  }
  307.  
  308.  /// Internal memory management operation set, normally created by memory managers (e.g. GEM).
  309. @@ -117,18 +90,19 @@ pub struct AllocOps {
  310.  }
  311.  
  312.  /// Trait for memory manager implementations. Implemented internally.
  313. -pub trait AllocImpl: Sealed + drm::gem::IntoGEMObject {
  314. +pub trait AllocImpl: super::private::Sealed + drm::gem::IntoGEMObject {
  315.      /// The C callback operations for this memory manager.
  316.      const ALLOC_OPS: AllocOps;
  317.  }
  318.  
  319. -/// A DRM driver implementation.
  320. +/// The DRM `Driver` trait.
  321. +///
  322. +/// This trait must be implemented by drivers in order to create a `struct drm_device` and `struct
  323. +/// drm_driver` to be registered in the DRM subsystem.
  324.  #[vtable]
  325.  pub trait Driver {
  326.      /// Context data associated with the DRM driver
  327. -    ///
  328. -    /// Determines the type of the context data passed to each of the methods of the trait.
  329. -    type Data: ForeignOwnable + Sync + Send;
  330. +    type Data: Sync + Send;
  331.  
  332.      /// The type used to manage memory for this driver.
  333.      ///
  334. @@ -141,193 +115,56 @@ pub trait Driver {
  335.      /// Driver metadata
  336.      const INFO: DriverInfo;
  337.  
  338. -    /// Feature flags
  339. -    const FEATURES: u32;
  340. -
  341.      /// IOCTL list. See `kernel::drm::ioctl::declare_drm_ioctls!{}`.
  342.      const IOCTLS: &'static [drm::ioctl::DrmIoctlDescriptor];
  343.  }
  344.  
  345. -/// A registration of a DRM device
  346. -///
  347. -/// # Invariants:
  348. -///
  349. -/// drm is always a valid pointer to an allocated drm_device
  350. -pub struct Registration<T: Driver> {
  351. -    drm: ARef<drm::device::Device<T>>,
  352. -    registered: bool,
  353. -    fops: bindings::file_operations,
  354. -    vtable: Pin<Box<bindings::drm_driver>>,
  355. -    _p: PhantomData<T>,
  356. -    _pin: PhantomPinned,
  357. -}
  358. -
  359. -#[cfg(CONFIG_DRM_LEGACY)]
  360. -macro_rules! drm_legacy_fields {
  361. -    ( $($field:ident: $val:expr),* $(,)? ) => {
  362. -        bindings::drm_driver {
  363. -            $( $field: $val ),*,
  364. -            firstopen: None,
  365. -            preclose: None,
  366. -            dma_ioctl: None,
  367. -            dma_quiescent: None,
  368. -            context_dtor: None,
  369. -            irq_handler: None,
  370. -            irq_preinstall: None,
  371. -            irq_postinstall: None,
  372. -            irq_uninstall: None,
  373. -            get_vblank_counter: None,
  374. -            enable_vblank: None,
  375. -            disable_vblank: None,
  376. -            dev_priv_size: 0,
  377. -        }
  378. -    }
  379. -}
  380. -
  381. -#[cfg(not(CONFIG_DRM_LEGACY))]
  382. -macro_rules! drm_legacy_fields {
  383. -    ( $($field:ident: $val:expr),* $(,)? ) => {
  384. -        bindings::drm_driver {
  385. -            $( $field: $val ),*
  386. -        }
  387. -    }
  388. -}
  389. -
  390. -/// Registers a DRM device with the rest of the kernel.
  391. +/// The registration type of a `drm::Device`.
  392.  ///
  393. -/// It automatically picks up THIS_MODULE.
  394. -#[allow(clippy::crate_in_macro_def)]
  395. -#[macro_export]
  396. -macro_rules! drm_device_register {
  397. -    ($reg:expr, $data:expr, $flags:expr $(,)?) => {{
  398. -        $crate::drm::drv::Registration::register($reg, $data, $flags, &crate::THIS_MODULE)
  399. -    }};
  400. -}
  401. +/// Once the `Registration` structure is dropped, the device is unregistered.
  402. +pub struct Registration<T: Driver>(ARef<drm::Device<T>>);
  403.  
  404.  impl<T: Driver> Registration<T> {
  405. -    const VTABLE: bindings::drm_driver = drm_legacy_fields! {
  406. -        load: None,
  407. -        open: Some(drm::file::open_callback::<T::File>),
  408. -        postclose: Some(drm::file::postclose_callback::<T::File>),
  409. -        lastclose: None,
  410. -        unload: None,
  411. -        release: None,
  412. -        master_set: None,
  413. -        master_drop: None,
  414. -        debugfs_init: None,
  415. -        gem_create_object: T::Object::ALLOC_OPS.gem_create_object,
  416. -        prime_handle_to_fd: T::Object::ALLOC_OPS.prime_handle_to_fd,
  417. -        prime_fd_to_handle: T::Object::ALLOC_OPS.prime_fd_to_handle,
  418. -        gem_prime_import: T::Object::ALLOC_OPS.gem_prime_import,
  419. -        gem_prime_import_sg_table: T::Object::ALLOC_OPS.gem_prime_import_sg_table,
  420. -        dumb_create: T::Object::ALLOC_OPS.dumb_create,
  421. -        dumb_map_offset: T::Object::ALLOC_OPS.dumb_map_offset,
  422. -        show_fdinfo: None,
  423. -
  424. -        major: T::INFO.major,
  425. -        minor: T::INFO.minor,
  426. -        patchlevel: T::INFO.patchlevel,
  427. -        name: T::INFO.name.as_char_ptr() as *mut _,
  428. -        desc: T::INFO.desc.as_char_ptr() as *mut _,
  429. -        date: T::INFO.date.as_char_ptr() as *mut _,
  430. -
  431. -        driver_features: T::FEATURES,
  432. -        ioctls: T::IOCTLS.as_ptr(),
  433. -        num_ioctls: T::IOCTLS.len() as i32,
  434. -        fops: core::ptr::null_mut(),
  435. -    };
  436. -
  437. -    /// Creates a new [`Registration`] but does not register it yet.
  438. -    ///
  439. -    /// It is allowed to move.
  440. -    pub fn new(parent: &dyn device::RawDevice) -> Result<Self> {
  441. -        let vtable = Pin::new(Box::new(Self::VTABLE, GFP_KERNEL)?);
  442. -        // SAFETY: Safe to call at any time (with valid args)
  443. -        let raw_drm = unsafe { bindings::drm_dev_alloc(&*vtable, parent.raw_device()) };
  444. -        let raw_drm = NonNull::new(from_err_ptr(raw_drm)? as *mut _).ok_or(ENOMEM)?;
  445. -
  446. -        // SAFETY: The reference count is one, and now we take ownership of that reference as a
  447. -        // drm::device::Device.
  448. -        let drm = unsafe { ARef::from_raw(raw_drm) };
  449. +    /// Creates a new [`Registration`] and registers it.
  450. +    pub fn new(drm: &drm::Device<T>, flags: usize) -> Result<Self> {
  451. +        // SAFETY: Safe by the invariants of `drm::Device`.
  452. +        let ret = unsafe { bindings::drm_dev_register(drm.as_raw(), flags) };
  453. +        if ret < 0 {
  454. +            return Err(Error::from_errno(ret));
  455. +        }
  456.  
  457. -        Ok(Self {
  458. -            drm,
  459. -            registered: false,
  460. -            vtable,
  461. -            fops: drm::gem::create_fops(),
  462. -            _pin: PhantomPinned,
  463. -            _p: PhantomData,
  464. -        })
  465. +        Ok(Self(drm.into()))
  466.      }
  467.  
  468. -    /// Registers a DRM device with the rest of the kernel.
  469. -    ///
  470. -    /// Users are encouraged to use the [`drm_device_register!()`] macro because it automatically
  471. -    /// picks up the current module.
  472. -    pub fn register(
  473. -        self: Pin<&mut Self>,
  474. -        data: T::Data,
  475. -        flags: usize,
  476. -        module: &'static ThisModule,
  477. -    ) -> Result {
  478. -        if self.registered {
  479. -            // Already registered.
  480. +    /// Same as [`Registration::new`}, but transfers ownership of the [`Registration`] to
  481. +    /// [`Devres`].
  482. +    pub fn new_foreign_owned(drm: &drm::Device<T>, dev: &device::Device, flags: usize) -> Result {
  483. +        if drm.as_ref().as_raw() != dev.as_raw() {
  484.              return Err(EINVAL);
  485.          }
  486.  
  487. -        // SAFETY: We never move out of `this`.
  488. -        let this = unsafe { self.get_unchecked_mut() };
  489. -        let data_pointer = <T::Data as ForeignOwnable>::into_foreign(data);
  490. -        // SAFETY: This is the only code touching dev_private, so it is safe to upgrade to a
  491. -        // mutable reference.
  492. -        unsafe { this.drm.raw_mut() }.dev_private = data_pointer as *mut _;
  493. -
  494. -        this.fops.owner = module.0;
  495. -        this.vtable.fops = &this.fops;
  496. -
  497. -        // SAFETY: The device is now initialized and ready to be registered.
  498. -        let ret = unsafe { bindings::drm_dev_register(this.drm.raw_mut(), flags as u64) };
  499. -        if ret < 0 {
  500. -            // SAFETY: `data_pointer` was returned by `into_foreign` above.
  501. -            unsafe { T::Data::from_foreign(data_pointer) };
  502. -            return Err(Error::from_errno(ret));
  503. -        }
  504. -
  505. -        this.registered = true;
  506. -        Ok(())
  507. +        let reg = Registration::<T>::new(drm, flags)?;
  508. +        Devres::new_foreign_owned(dev, reg, GFP_KERNEL)
  509.      }
  510.  
  511.      /// Returns a reference to the `Device` instance for this registration.
  512. -    pub fn device(&self) -> &drm::device::Device<T> {
  513. -        // TODO: rework this, ensure this only works after registration
  514. -        &self.drm
  515. +    pub fn device(&self) -> &drm::Device<T> {
  516. +        &self.0
  517.      }
  518.  }
  519.  
  520. -// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between threads
  521. -// or CPUs, so it is safe to share it.
  522. +// SAFETY: `Registration` doesn't offer any methods or access to fields when shared between
  523. +// threads, hence it's safe to share it.
  524.  unsafe impl<T: Driver> Sync for Registration<T> {}
  525.  
  526. -#[allow(clippy::non_send_fields_in_send_ty)]
  527. -// SAFETY: Registration with and unregistration from the drm subsystem can happen from any thread.
  528. -// Additionally, `T::Data` (which is dropped during unregistration) is `Send`, so it is ok to move
  529. -// `Registration` to different threads.
  530. +// SAFETY: Registration with and unregistration from the DRM subsystem can happen from any thread.
  531.  unsafe impl<T: Driver> Send for Registration<T> {}
  532.  
  533.  impl<T: Driver> Drop for Registration<T> {
  534.      /// Removes the registration from the kernel if it has completed successfully before.
  535.      fn drop(&mut self) {
  536. -        if self.registered {
  537. -            // Get a pointer to the data stored in device before destroying it.
  538. -            // SAFETY: `drm` is valid per the type invariant
  539. -            let data_pointer = unsafe { self.drm.raw_mut().dev_private };
  540. -
  541. -            // SAFETY: Since `registered` is true, `self.drm` is both valid and registered.
  542. -            unsafe { bindings::drm_dev_unregister(self.drm.raw_mut()) };
  543. -
  544. -            // Free data as well.
  545. -            // SAFETY: `data_pointer` was returned by `into_foreign` during registration.
  546. -            unsafe { <T::Data as ForeignOwnable>::from_foreign(data_pointer) };
  547. -        }
  548. +        // SAFETY: Safe by the invariant of `ARef<drm::Device<T>>`. The existence of this
  549. +        // `Registration` also guarantees the this `drm::Device` is actually registered.
  550. +        unsafe { bindings::drm_dev_unregister(self.0.as_raw()) };
  551.      }
  552.  }
  553. diff --git a/rust/kernel/drm/file.rs b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/file.rs
  554. index a20ab4b8769b..3b97728f03e0 100644
  555. --- a/rust/kernel/drm/file.rs
  556. +++ b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/file.rs
  557. @@ -2,116 +2,98 @@
  558.  
  559.  //! DRM File objects.
  560.  //!
  561. -//! C header: [`include/drm/drm_file.h`](../../../../include/drm/drm_file.h)
  562. +//! C header: [`include/linux/drm/drm_file.h`](srctree/include/linux/drm/drm_file.h)
  563.  
  564. -use crate::{bindings, drm, error::Result};
  565. -use alloc::boxed::Box;
  566. +use crate::{bindings, drm, error::Result, prelude::*, types::Opaque};
  567.  use core::marker::PhantomData;
  568.  use core::pin::Pin;
  569.  
  570.  /// Trait that must be implemented by DRM drivers to represent a DRM File (a client instance).
  571.  pub trait DriverFile {
  572.      /// The parent `Driver` implementation for this `DriverFile`.
  573. -    type Driver: drm::drv::Driver;
  574. +    type Driver: drm::Driver;
  575.  
  576.      /// Open a new file (called when a client opens the DRM device).
  577. -    fn open(device: &drm::device::Device<Self::Driver>) -> Result<Pin<Box<Self>>>;
  578. +    fn open(device: &drm::Device<Self::Driver>) -> Result<Pin<KBox<Self>>>;
  579.  }
  580.  
  581.  /// An open DRM File.
  582.  ///
  583.  /// # Invariants
  584. -/// `raw` is a valid pointer to a `drm_file` struct.
  585. +///
  586. +/// `self.0` is always a valid pointer to an open `struct drm_file`.
  587.  #[repr(transparent)]
  588. -pub struct File<T: DriverFile> {
  589. -    raw: *mut bindings::drm_file,
  590. -    _p: PhantomData<T>,
  591. -}
  592. -
  593. -pub(super) unsafe extern "C" fn open_callback<T: DriverFile>(
  594. -    raw_dev: *mut bindings::drm_device,
  595. -    raw_file: *mut bindings::drm_file,
  596. -) -> core::ffi::c_int {
  597. -    // SAFETY: The raw_drm arg is always a valid borrowed reference
  598. -    let drm = unsafe { drm::device::Device::borrow(raw_dev) };
  599. -    // SAFETY: This reference won't escape this function
  600. -    let file = unsafe { &mut *raw_file };
  601. -
  602. -    let inner = match T::open(drm) {
  603. -        Err(e) => {
  604. -            return e.to_errno();
  605. -        }
  606. -        Ok(i) => i,
  607. -    };
  608. -
  609. -    // SAFETY: This pointer is treated as pinned, and the Drop guarantee is upheld below.
  610. -    file.driver_priv = Box::into_raw(unsafe { Pin::into_inner_unchecked(inner) }) as *mut _;
  611. -
  612. -    0
  613. -}
  614. -
  615. -pub(super) unsafe extern "C" fn postclose_callback<T: DriverFile>(
  616. -    _dev: *mut bindings::drm_device,
  617. -    raw_file: *mut bindings::drm_file,
  618. -) {
  619. -    // SAFETY: This reference won't escape this function
  620. -    let file = unsafe { &*raw_file };
  621. -
  622. -    // Drop the DriverFile
  623. -    // SAFETY: file.driver_priv is always a Box<T> pointer
  624. -    unsafe { drop(Box::from_raw(file.driver_priv as *mut T)) };
  625. -}
  626. +pub struct File<T: DriverFile>(Opaque<bindings::drm_file>, PhantomData<T>);
  627.  
  628.  impl<T: DriverFile> File<T> {
  629. -    // Not intended to be called externally, except via declare_drm_ioctls!()
  630.      #[doc(hidden)]
  631. -    pub unsafe fn from_raw(raw_file: *mut bindings::drm_file) -> File<T> {
  632. -        File {
  633. -            raw: raw_file,
  634. -            _p: PhantomData,
  635. -        }
  636. +    /// Not intended to be called externally, except via declare_drm_ioctls!()
  637. +    ///
  638. +    /// # Safety
  639. +    ///
  640. +    /// `raw_file` must be a valid pointer to an open `struct drm_file`, opened through `T::open`.
  641. +    pub unsafe fn as_ref<'a>(ptr: *mut bindings::drm_file) -> &'a File<T> {
  642. +        // SAFETY: `raw_file` is valid by the safety requirements of this function.
  643. +        unsafe { &*ptr.cast() }
  644.      }
  645.  
  646. -    #[allow(dead_code)]
  647. -    /// Return the raw pointer to the underlying `drm_file`.
  648. -    pub(super) fn raw(&self) -> *const bindings::drm_file {
  649. -        self.raw
  650. +    pub(super) fn as_raw(&self) -> *mut bindings::drm_file {
  651. +        self.0.get()
  652.      }
  653.  
  654. -    /// Return an immutable reference to the raw `drm_file` structure.
  655. -    pub(super) fn file(&self) -> &bindings::drm_file {
  656. -        // SAFETY: The raw pointer is always valid per usage in declare_drm_ioctls!()
  657. -        unsafe { &*self.raw }
  658. +    fn driver_priv(&self) -> *mut T {
  659. +        // SAFETY: By the type invariants of `Self`, `self.as_raw()` is always valid.
  660. +        unsafe { (*self.as_raw()).driver_priv }.cast()
  661.      }
  662.  
  663.      /// Return a pinned reference to the driver file structure.
  664.      pub fn inner(&self) -> Pin<&T> {
  665. -        // SAFETY: The driver_priv pointer is always a pinned reference to the driver
  666. -        // file structure.
  667. -        unsafe { Pin::new_unchecked(&*(self.file().driver_priv as *const T)) }
  668. +        // SAFETY: By the type invariant the pointer `self.as_raw()` points to a valid and opened
  669. +        // `struct drm_file`, hence `driver_priv` has been properly initialized by `open_callback`.
  670. +        unsafe { Pin::new_unchecked(&*(self.driver_priv())) }
  671.      }
  672. -}
  673.  
  674. -impl<T: DriverFile> crate::private::Sealed for File<T> {}
  675. +    /// The open callback of a `struct drm_file`.
  676. +    pub(crate) extern "C" fn open_callback(
  677. +        raw_dev: *mut bindings::drm_device,
  678. +        raw_file: *mut bindings::drm_file,
  679. +    ) -> core::ffi::c_int {
  680. +        // SAFETY: A callback from `struct drm_driver::open` guarantees that
  681. +        // - `raw_dev` is valid pointer to a `sturct drm_device`,
  682. +        // - the corresponding `sturct drm_device` has been registered.
  683. +        let drm = unsafe { drm::Device::as_ref(raw_dev) };
  684. +
  685. +        // SAFETY: `raw_file` valid pointer to a `struct drm_file`.
  686. +        let file = unsafe { File::<T>::as_ref(raw_file) };
  687. +
  688. +        let inner = match T::open(drm) {
  689. +            Err(e) => {
  690. +                return e.to_errno();
  691. +            }
  692. +            Ok(i) => i,
  693. +        };
  694. +
  695. +        // SAFETY: This pointer is treated as pinned, and the Drop guarantee is upheld in
  696. +        // `postclose_callback()`.
  697. +        let driver_priv = KBox::into_raw(unsafe { Pin::into_inner_unchecked(inner) });
  698. +
  699. +        // SAFETY: By the type invariants of `Self`, `self.as_raw()` is always valid.
  700. +        unsafe { (*file.as_raw()).driver_priv = driver_priv.cast() };
  701. +
  702. +        0
  703. +    }
  704.  
  705. -/// Generic trait to allow users that don't care about driver specifics to accept any File<T>.
  706. -///
  707. -/// # Safety
  708. -/// Must only be implemented for File<T> and return the pointer, following the normal invariants
  709. -/// of that type.
  710. -pub unsafe trait GenericFile: crate::private::Sealed {
  711. -    /// Returns the raw const pointer to the `struct drm_file`
  712. -    fn raw(&self) -> *const bindings::drm_file;
  713. -    /// Returns the raw mut pointer to the `struct drm_file`
  714. -    fn raw_mut(&mut self) -> *mut bindings::drm_file;
  715. -}
  716. +    /// The postclose callback of a `struct drm_file`.
  717. +    pub(crate) extern "C" fn postclose_callback(
  718. +        _raw_dev: *mut bindings::drm_device,
  719. +        raw_file: *mut bindings::drm_file,
  720. +    ) {
  721. +        // SAFETY: This reference won't escape this function
  722. +        let file = unsafe { File::<T>::as_ref(raw_file) };
  723.  
  724. -// SAFETY: Follows the invariants of the File<T>.
  725. -unsafe impl<T: DriverFile> GenericFile for File<T> {
  726. -    fn raw(&self) -> *const bindings::drm_file {
  727. -        self.raw
  728. -    }
  729. -    fn raw_mut(&mut self) -> *mut bindings::drm_file {
  730. -        self.raw
  731. +        // SAFETY: `file.driver_priv` has been created in `open_callback` through `KBox::into_raw`.
  732. +        let _ = unsafe { KBox::from_raw(file.driver_priv()) };
  733.      }
  734.  }
  735. +
  736. +impl<T: DriverFile> super::private::Sealed for File<T> {}
  737. diff --git a/rust/kernel/drm/gem/mod.rs b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/gem/mod.rs
  738. index fdcd415e585f..6f4ca75bc7d5 100644
  739. --- a/rust/kernel/drm/gem/mod.rs
  740. +++ b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/gem/mod.rs
  741. @@ -2,182 +2,135 @@
  742.  
  743.  //! DRM GEM API
  744.  //!
  745. -//! C header: [`include/linux/drm/drm_gem.h`](../../../../include/linux/drm/drm_gem.h)
  746. -
  747. -#[cfg(CONFIG_DRM_GEM_SHMEM_HELPER = "y")]
  748. -pub mod shmem;
  749. -
  750. -use alloc::boxed::Box;
  751. +//! C header: [`include/linux/drm/drm_gem.h`](srctree/include/linux/drm/drm_gem.h)
  752.  
  753.  use crate::{
  754.      alloc::flags::*,
  755. -    bindings,
  756. -    drm::{device, drv, file},
  757. +    bindings, drm,
  758. +    drm::driver::{AllocImpl, AllocOps},
  759.      error::{to_result, Result},
  760.      prelude::*,
  761. +    types::{ARef, Opaque},
  762.  };
  763. -use core::{marker::PhantomPinned, mem, ops::Deref, ops::DerefMut};
  764. +use core::{mem, ops::Deref, ptr};
  765.  
  766.  /// GEM object functions, which must be implemented by drivers.
  767.  pub trait BaseDriverObject<T: BaseObject>: Sync + Send + Sized {
  768. -    /// The return type of the new() function. Should be `impl PinInit<Self, Error>`.
  769. -    /// TODO: Remove this when return_position_impl_trait_in_trait is stable.
  770. -    type Initializer: PinInit<Self, Error>;
  771. -
  772.      /// Create a new driver data object for a GEM object of a given size.
  773. -    fn new(dev: &device::Device<T::Driver>, size: usize) -> Self::Initializer;
  774. +    fn new(dev: &drm::Device<T::Driver>, size: usize) -> impl PinInit<Self, Error>;
  775.  
  776.      /// Open a new handle to an existing object, associated with a File.
  777.      fn open(
  778. -        _obj: &<<T as IntoGEMObject>::Driver as drv::Driver>::Object,
  779. -        _file: &file::File<<<T as IntoGEMObject>::Driver as drv::Driver>::File>,
  780. +        _obj: &<<T as IntoGEMObject>::Driver as drm::Driver>::Object,
  781. +        _file: &drm::File<<<T as IntoGEMObject>::Driver as drm::Driver>::File>,
  782.      ) -> Result {
  783.          Ok(())
  784.      }
  785.  
  786.      /// Close a handle to an existing object, associated with a File.
  787.      fn close(
  788. -        _obj: &<<T as IntoGEMObject>::Driver as drv::Driver>::Object,
  789. -        _file: &file::File<<<T as IntoGEMObject>::Driver as drv::Driver>::File>,
  790. +        _obj: &<<T as IntoGEMObject>::Driver as drm::Driver>::Object,
  791. +        _file: &drm::File<<<T as IntoGEMObject>::Driver as drm::Driver>::File>,
  792.      ) {
  793.      }
  794.  }
  795.  
  796.  /// Trait that represents a GEM object subtype
  797. -pub trait IntoGEMObject: Sized + crate::private::Sealed {
  798. +pub trait IntoGEMObject: Sized + super::private::Sealed {
  799.      /// Owning driver for this type
  800. -    type Driver: drv::Driver;
  801. +    type Driver: drm::Driver;
  802.  
  803.      /// Returns a reference to the raw `drm_gem_object` structure, which must be valid as long as
  804.      /// this owning object is valid.
  805. -    fn gem_obj(&self) -> &bindings::drm_gem_object;
  806. +    #[allow(clippy::wrong_self_convention)]
  807. +    fn into_gem_obj(&self) -> &Opaque<bindings::drm_gem_object>;
  808.  
  809. -    /// Returns a reference to the raw `drm_gem_object` structure, which must be valid as long as
  810. -    /// this owning object is valid.
  811. -    fn mut_gem_obj(&mut self) -> &mut bindings::drm_gem_object;
  812. -
  813. -    /// Converts a pointer to a `drm_gem_object` into a pointer to this type.
  814. -    ///
  815. -    /// # Safety
  816. -    ///
  817. -    /// The argument must an object owned by this Driver.
  818. -    unsafe fn from_gem_obj(obj: *mut bindings::drm_gem_object) -> *mut Self;
  819. +    /// Converts a pointer to a `struct drm_gem_object` into a pointer to `Self`.
  820. +    fn from_gem_obj(obj: *mut bindings::drm_gem_object) -> *mut Self;
  821.  }
  822.  
  823.  /// Trait which must be implemented by drivers using base GEM objects.
  824.  pub trait DriverObject: BaseDriverObject<Object<Self>> {
  825.      /// Parent `Driver` for this object.
  826. -    type Driver: drv::Driver;
  827. +    type Driver: drm::Driver;
  828.  }
  829.  
  830. -unsafe extern "C" fn free_callback<T: DriverObject>(obj: *mut bindings::drm_gem_object) {
  831. -    // SAFETY: All of our objects are Object<T>.
  832. -    let this = unsafe { crate::container_of!(obj, Object<T>, obj) as *mut Object<T> };
  833. -
  834. -    // SAFETY: The pointer we got has to be valid
  835. -    unsafe { bindings::drm_gem_object_release(obj) };
  836. -
  837. -    // SAFETY: All of our objects are allocated via Box<>, and we're in the
  838. -    // free callback which guarantees this object has zero remaining references,
  839. -    // so we can drop it
  840. -    unsafe { drop(Box::from_raw(this)) };
  841. -}
  842. -
  843. -unsafe extern "C" fn open_callback<T: BaseDriverObject<U>, U: BaseObject>(
  844. +extern "C" fn open_callback<T: BaseDriverObject<U>, U: BaseObject>(
  845.      raw_obj: *mut bindings::drm_gem_object,
  846.      raw_file: *mut bindings::drm_file,
  847.  ) -> core::ffi::c_int {
  848. -    // SAFETY: The file pointer is valid when called from the C side.
  849. +    // SAFETY: `open_callback` is only ever called with a valid pointer to a `struct drm_file`.
  850.      let file = unsafe {
  851. -        file::File::<<<U as IntoGEMObject>::Driver as drv::Driver>::File>::from_raw(raw_file)
  852. +        drm::File::<<<U as IntoGEMObject>::Driver as drm::Driver>::File>::as_ref(raw_file)
  853.      };
  854. -    // SAFETY: The object pointer is valid and owned by us when called from the C side.
  855. -    let obj = unsafe {
  856. -        <<<U as IntoGEMObject>::Driver as drv::Driver>::Object as IntoGEMObject>::from_gem_obj(
  857. +    let obj =
  858. +        <<<U as IntoGEMObject>::Driver as drm::Driver>::Object as IntoGEMObject>::from_gem_obj(
  859.              raw_obj,
  860. -        )
  861. -    };
  862. +        );
  863.  
  864. -    // SAFETY: from_gem_obj() returns a valid pointer as long as the type is
  865. -    // correct and the raw_obj we got is valid.
  866. -    match T::open(unsafe { &*obj }, &file) {
  867. +    // SAFETY: `from_gem_obj()` returns a valid pointer as long as the type is correct and the
  868. +    // `raw_obj` we got is valid.
  869. +    match T::open(unsafe { &*obj }, file) {
  870.          Err(e) => e.to_errno(),
  871.          Ok(()) => 0,
  872.      }
  873.  }
  874.  
  875. -unsafe extern "C" fn close_callback<T: BaseDriverObject<U>, U: BaseObject>(
  876. +extern "C" fn close_callback<T: BaseDriverObject<U>, U: BaseObject>(
  877.      raw_obj: *mut bindings::drm_gem_object,
  878.      raw_file: *mut bindings::drm_file,
  879.  ) {
  880. -    // SAFETY: The pointer we got has to be valid.
  881. +    // SAFETY: `open_callback` is only ever called with a valid pointer to a `struct drm_file`.
  882.      let file = unsafe {
  883. -        file::File::<<<U as IntoGEMObject>::Driver as drv::Driver>::File>::from_raw(raw_file)
  884. +        drm::File::<<<U as IntoGEMObject>::Driver as drm::Driver>::File>::as_ref(raw_file)
  885.      };
  886. -    // SAFETY: The object pointer is valid and owned by us when called from the C side.
  887. -    let obj = unsafe {
  888. -        <<<U as IntoGEMObject>::Driver as drv::Driver>::Object as IntoGEMObject>::from_gem_obj(
  889. +    let obj =
  890. +        <<<U as IntoGEMObject>::Driver as drm::Driver>::Object as IntoGEMObject>::from_gem_obj(
  891.              raw_obj,
  892. -        )
  893. -    };
  894. +        );
  895.  
  896. -    // SAFETY: from_gem_obj() returns a valid pointer as long as the type is
  897. -    // correct and the raw_obj we got is valid.
  898. -    T::close(unsafe { &*obj }, &file);
  899. +    // SAFETY: `from_gem_obj()` returns a valid pointer as long as the type is correct and the
  900. +    // `raw_obj` we got is valid.
  901. +    T::close(unsafe { &*obj }, file);
  902.  }
  903.  
  904.  impl<T: DriverObject> IntoGEMObject for Object<T> {
  905.      type Driver = T::Driver;
  906.  
  907. -    fn gem_obj(&self) -> &bindings::drm_gem_object {
  908. +    fn into_gem_obj(&self) -> &Opaque<bindings::drm_gem_object> {
  909.          &self.obj
  910.      }
  911.  
  912. -    fn mut_gem_obj(&mut self) -> &mut bindings::drm_gem_object {
  913. -        &mut self.obj
  914. -    }
  915. -
  916. -    unsafe fn from_gem_obj(obj: *mut bindings::drm_gem_object) -> *mut Object<T> {
  917. -        // SAFETY: Safe as long as the safety invariants of this trait method hold.
  918. -        unsafe { crate::container_of!(obj, Object<T>, obj) as *mut Object<T> }
  919. +    fn from_gem_obj(obj: *mut bindings::drm_gem_object) -> *mut Self {
  920. +        // SAFETY: All of our objects are Object<T>.
  921. +        unsafe { crate::container_of!(obj, Object<T>, obj).cast_mut() }
  922.      }
  923.  }
  924.  
  925.  /// Base operations shared by all GEM object classes
  926. -pub trait BaseObject: IntoGEMObject {
  927. +pub trait BaseObject
  928. +where
  929. +    Self: crate::types::AlwaysRefCounted + IntoGEMObject,
  930. +{
  931.      /// Returns the size of the object in bytes.
  932.      fn size(&self) -> usize {
  933. -        self.gem_obj().size
  934. -    }
  935. -
  936. -    /// Sets the exportable flag, which controls whether the object can be exported via PRIME.
  937. -    fn set_exportable(&mut self, exportable: bool) {
  938. -        self.mut_gem_obj().exportable = exportable;
  939. -    }
  940. -
  941. -    /// Creates a new reference to the object.
  942. -    fn reference(&self) -> ObjectRef<Self> {
  943. -        // SAFETY: Having a reference to an Object implies holding a GEM reference
  944. -        unsafe {
  945. -            bindings::drm_gem_object_get(self.gem_obj() as *const _ as *mut _);
  946. -        }
  947. -        ObjectRef {
  948. -            ptr: self as *const _,
  949. -        }
  950. +        // SAFETY: `self.into_gem_obj()` is guaranteed to be a pointer to a valid `struct
  951. +        // drm_gem_object`.
  952. +        unsafe { (*self.into_gem_obj().get()).size }
  953.      }
  954.  
  955.      /// Creates a new handle for the object associated with a given `File`
  956.      /// (or returns an existing one).
  957.      fn create_handle(
  958.          &self,
  959. -        file: &file::File<<<Self as IntoGEMObject>::Driver as drv::Driver>::File>,
  960. +        file: &drm::File<<<Self as IntoGEMObject>::Driver as drm::Driver>::File>,
  961.      ) -> Result<u32> {
  962.          let mut handle: u32 = 0;
  963.          // SAFETY: The arguments are all valid per the type invariants.
  964.          to_result(unsafe {
  965.              bindings::drm_gem_handle_create(
  966. -                file.raw() as *mut _,
  967. -                self.gem_obj() as *const _ as *mut _,
  968. +                file.as_raw().cast(),
  969. +                self.into_gem_obj().get(),
  970.                  &mut handle,
  971.              )
  972.          })?;
  973. @@ -186,58 +139,54 @@ fn create_handle(
  974.  
  975.      /// Looks up an object by its handle for a given `File`.
  976.      fn lookup_handle(
  977. -        file: &file::File<<<Self as IntoGEMObject>::Driver as drv::Driver>::File>,
  978. +        file: &drm::File<<<Self as IntoGEMObject>::Driver as drm::Driver>::File>,
  979.          handle: u32,
  980. -    ) -> Result<ObjectRef<Self>> {
  981. +    ) -> Result<ARef<Self>> {
  982.          // SAFETY: The arguments are all valid per the type invariants.
  983. -        let ptr = unsafe { bindings::drm_gem_object_lookup(file.raw() as *mut _, handle) };
  984. -
  985. -        if ptr.is_null() {
  986. -            Err(ENOENT)
  987. -        } else {
  988. -            Ok(ObjectRef {
  989. -                ptr: ptr as *const _,
  990. -            })
  991. -        }
  992. +        let ptr = unsafe { bindings::drm_gem_object_lookup(file.as_raw().cast(), handle) };
  993. +        let ptr = <Self as IntoGEMObject>::from_gem_obj(ptr);
  994. +        let ptr = ptr::NonNull::new(ptr).ok_or(ENOENT)?;
  995. +
  996. +        // SAFETY: We take ownership of the reference of `drm_gem_object_lookup()`.
  997. +        Ok(unsafe { ARef::from_raw(ptr) })
  998.      }
  999.  
  1000.      /// Creates an mmap offset to map the object from userspace.
  1001.      fn create_mmap_offset(&self) -> Result<u64> {
  1002.          // SAFETY: The arguments are valid per the type invariant.
  1003. -        to_result(unsafe {
  1004. -            // TODO: is this threadsafe?
  1005. -            bindings::drm_gem_create_mmap_offset(self.gem_obj() as *const _ as *mut _)
  1006. -        })?;
  1007. -        // SAFETY: Safe to call on vma_node (which is guaranteed to be valid after the above)
  1008. +        to_result(unsafe { bindings::drm_gem_create_mmap_offset(self.into_gem_obj().get()) })?;
  1009. +
  1010. +        // SAFETY: The arguments are valid per the type invariant.
  1011.          Ok(unsafe {
  1012. -            bindings::drm_vma_node_offset_addr(&self.gem_obj().vma_node as *const _ as *mut _)
  1013. +            bindings::drm_vma_node_offset_addr(ptr::addr_of_mut!(
  1014. +                (*self.into_gem_obj().get()).vma_node
  1015. +            ))
  1016.          })
  1017.      }
  1018.  }
  1019.  
  1020. -impl<T: IntoGEMObject> BaseObject for T {}
  1021. +impl<T> BaseObject for T where Self: crate::types::AlwaysRefCounted + IntoGEMObject {}
  1022.  
  1023.  /// A base GEM object.
  1024. +///
  1025. +/// Invariants
  1026. +///
  1027. +/// `self.dev` is always a valid pointer to a `struct drm_device`.
  1028.  #[repr(C)]
  1029.  #[pin_data]
  1030. -pub struct Object<T: DriverObject> {
  1031. -    obj: bindings::drm_gem_object,
  1032. -    dev: *const bindings::drm_device,
  1033. +pub struct Object<T: DriverObject + Send + Sync> {
  1034. +    obj: Opaque<bindings::drm_gem_object>,
  1035. +    dev: ptr::NonNull<bindings::drm_device>,
  1036.      #[pin]
  1037. -    inner: T,
  1038. -    #[pin]
  1039. -    _p: PhantomPinned,
  1040. +    data: T,
  1041.  }
  1042.  
  1043. -// SAFETY: This struct is safe to zero-initialize
  1044. -unsafe impl init::Zeroable for bindings::drm_gem_object {}
  1045. -
  1046.  impl<T: DriverObject> Object<T> {
  1047.      /// The size of this object's structure.
  1048.      pub const SIZE: usize = mem::size_of::<Self>();
  1049.  
  1050.      const OBJECT_FUNCS: bindings::drm_gem_object_funcs = bindings::drm_gem_object_funcs {
  1051. -        free: Some(free_callback::<T>),
  1052. +        free: Some(Self::free_callback),
  1053.          open: Some(open_callback::<T, Object<T>>),
  1054.          close: Some(close_callback::<T, Object<T>>),
  1055.          print_info: None,
  1056. @@ -249,174 +198,124 @@ impl<T: DriverObject> Object<T> {
  1057.          vunmap: None,
  1058.          mmap: None,
  1059.          status: None,
  1060. -        rss: None,
  1061.          vm_ops: core::ptr::null_mut(),
  1062.          evict: None,
  1063. +        rss: None,
  1064.      };
  1065.  
  1066.      /// Create a new GEM object.
  1067. -    pub fn new(dev: &device::Device<T::Driver>, size: usize) -> Result<Pin<UniqueObjectRef<Self>>> {
  1068. -        let obj: Pin<Box<Self>> = Box::try_pin_init(
  1069. +    pub fn new(dev: &drm::Device<T::Driver>, size: usize) -> Result<ARef<Self>> {
  1070. +        let obj: Pin<KBox<Self>> = KBox::pin_init(
  1071.              try_pin_init!(Self {
  1072. -                // SAFETY: This struct is expected to be zero-initialized
  1073. -                obj: bindings::drm_gem_object {
  1074. -                    funcs: &Self::OBJECT_FUNCS,
  1075. -                    ..Default::default()
  1076. -                },
  1077. -                inner <- T::new(dev, size),
  1078. -                dev: dev.drm.get(),
  1079. -                _p: PhantomPinned
  1080. +                obj: Opaque::new(bindings::drm_gem_object::default()),
  1081. +                data <- T::new(dev, size),
  1082. +                // INVARIANT: The drm subsystem guarantees that the `struct drm_device` will live
  1083. +                // as long as the GEM object lives.
  1084. +                //
  1085. +                // SAFETY: By the type invariants of `drm::Device`, `dev.as_raw()` must be valid.
  1086. +                dev: unsafe { ptr::NonNull::new_unchecked(dev.as_raw()) },
  1087.              }),
  1088.              GFP_KERNEL,
  1089.          )?;
  1090.  
  1091. -        // SAFETY: Safe to call as long as the pointer is a properly allocated GEM object
  1092. -        to_result(unsafe {
  1093. -            bindings::drm_gem_object_init(dev.raw_mut(), &obj.obj as *const _ as *mut _, size)
  1094. -        })?;
  1095. +        // SAFETY: `obj.as_raw()` is guaranteed to be valid by the initialization above.
  1096. +        unsafe { (*obj.as_raw()).funcs = &Self::OBJECT_FUNCS };
  1097.  
  1098. -        // SAFETY: We never move out of self
  1099. -        let obj_ref = unsafe {
  1100. -            Pin::new_unchecked(UniqueObjectRef {
  1101. -                // SAFETY: We never move out of the Box
  1102. -                ptr: Box::leak(Pin::into_inner_unchecked(obj)),
  1103. -                _p: PhantomPinned,
  1104. -            })
  1105. -        };
  1106. +        // SAFETY: The arguments are all valid per the type invariants.
  1107. +        to_result(unsafe { bindings::drm_gem_object_init(dev.as_raw(), obj.obj.get(), size) })?;
  1108. +
  1109. +        // SAFETY: We never move out of `Self`.
  1110. +        let ptr = KBox::into_raw(unsafe { Pin::into_inner_unchecked(obj) });
  1111. +
  1112. +        // SAFETY: `ptr` comes from `KBox::into_raw` and hence can't be NULL.
  1113. +        let ptr = unsafe { ptr::NonNull::new_unchecked(ptr) };
  1114.  
  1115. -        Ok(obj_ref)
  1116. +        // SAFETY: We take over the initial reference count from `drm_gem_object_init()`.
  1117. +        Ok(unsafe { ARef::from_raw(ptr) })
  1118.      }
  1119.  
  1120.      /// Returns the `Device` that owns this GEM object.
  1121. -    pub fn dev(&self) -> &device::Device<T::Driver> {
  1122. -        // SAFETY: The drm subsystem guarantees that the drm_device will live as long as
  1123. +    pub fn dev(&self) -> &drm::Device<T::Driver> {
  1124. +        // SAFETY: The DRM subsystem guarantees that the `struct drm_device` will live as long as
  1125.          // the GEM object lives, so we can just borrow from the raw pointer.
  1126. -        unsafe { device::Device::borrow(self.dev) }
  1127. -    }
  1128. -}
  1129. -
  1130. -impl<T: DriverObject> crate::private::Sealed for Object<T> {}
  1131. -
  1132. -impl<T: DriverObject> Deref for Object<T> {
  1133. -    type Target = T;
  1134. -
  1135. -    fn deref(&self) -> &Self::Target {
  1136. -        &self.inner
  1137. +        unsafe { drm::Device::as_ref(self.dev.as_ptr()) }
  1138.      }
  1139. -}
  1140.  
  1141. -impl<T: DriverObject> DerefMut for Object<T> {
  1142. -    fn deref_mut(&mut self) -> &mut Self::Target {
  1143. -        &mut self.inner
  1144. +    fn as_raw(&self) -> *mut bindings::drm_gem_object {
  1145. +        self.obj.get()
  1146.      }
  1147. -}
  1148.  
  1149. -impl<T: DriverObject> drv::AllocImpl for Object<T> {
  1150. -    const ALLOC_OPS: drv::AllocOps = drv::AllocOps {
  1151. -        gem_create_object: None,
  1152. -        prime_handle_to_fd: None,
  1153. -        prime_fd_to_handle: None,
  1154. -        gem_prime_import: None,
  1155. -        gem_prime_import_sg_table: None,
  1156. -        dumb_create: None,
  1157. -        dumb_map_offset: None,
  1158. -    };
  1159. -}
  1160. -
  1161. -/// A reference-counted shared reference to a base GEM object.
  1162. -pub struct ObjectRef<T: IntoGEMObject> {
  1163. -    // Invariant: the pointer is valid and initialized, and this ObjectRef owns a reference to it.
  1164. -    ptr: *const T,
  1165. -}
  1166. +    extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) {
  1167. +        // SAFETY: All of our objects are of type `Object<T>`.
  1168. +        let this = unsafe { crate::container_of!(obj, Self, obj) }.cast_mut();
  1169.  
  1170. -/// SAFETY: GEM object references are safe to share between threads.
  1171. -unsafe impl<T: IntoGEMObject> Send for ObjectRef<T> {}
  1172. -/// SAFETY: GEM object references are safe to share between threads.
  1173. -unsafe impl<T: IntoGEMObject> Sync for ObjectRef<T> {}
  1174. +        // SAFETY: The C code only ever calls this callback with a valid pointer to a `struct
  1175. +        // drm_gem_object`.
  1176. +        unsafe { bindings::drm_gem_object_release(obj) };
  1177.  
  1178. -impl<T: IntoGEMObject> Clone for ObjectRef<T> {
  1179. -    fn clone(&self) -> Self {
  1180. -        self.reference()
  1181. +        // SAFETY: All of our objects are allocated via `KBox`, and we're in the
  1182. +        // free callback which guarantees this object has zero remaining references,
  1183. +        // so we can drop it.
  1184. +        let _ = unsafe { KBox::from_raw(this) };
  1185.      }
  1186.  }
  1187.  
  1188. -impl<T: IntoGEMObject> Drop for ObjectRef<T> {
  1189. -    fn drop(&mut self) {
  1190. -        // SAFETY: Having an ObjectRef implies holding a GEM reference.
  1191. -        // The free callback will take care of deallocation.
  1192. -        unsafe {
  1193. -            bindings::drm_gem_object_put((*self.ptr).gem_obj() as *const _ as *mut _);
  1194. -        }
  1195. +// SAFETY: Instances of `Object<T>` are always reference-counted.
  1196. +unsafe impl<T: DriverObject> crate::types::AlwaysRefCounted for Object<T> {
  1197. +    fn inc_ref(&self) {
  1198. +        // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
  1199. +        unsafe { bindings::drm_gem_object_get(self.as_raw()) };
  1200.      }
  1201. -}
  1202.  
  1203. -impl<T: IntoGEMObject> Deref for ObjectRef<T> {
  1204. -    type Target = T;
  1205. +    unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
  1206. +        // SAFETY: `obj` is a valid pointer to an `Object<T>`.
  1207. +        let obj = unsafe { obj.as_ref() };
  1208.  
  1209. -    fn deref(&self) -> &Self::Target {
  1210. -        // SAFETY: The pointer is valid per the invariant
  1211. -        unsafe { &*self.ptr }
  1212. +        // SAFETY: The safety requirements guarantee that the refcount is non-zero.
  1213. +        unsafe { bindings::drm_gem_object_put(obj.as_raw()) }
  1214.      }
  1215.  }
  1216.  
  1217. -/// A unique reference to a base GEM object.
  1218. -pub struct UniqueObjectRef<T: IntoGEMObject> {
  1219. -    // Invariant: the pointer is valid and initialized, and this ObjectRef owns the only reference
  1220. -    // to it.
  1221. -    ptr: *mut T,
  1222. -    _p: PhantomPinned,
  1223. -}
  1224. +impl<T: DriverObject> super::private::Sealed for Object<T> {}
  1225.  
  1226. -impl<T: IntoGEMObject> UniqueObjectRef<T> {
  1227. -    /// Downgrade this reference to a shared reference.
  1228. -    pub fn into_ref(self) -> ObjectRef<T> {
  1229. -        let ptr = self.ptr as *const _;
  1230. -        core::mem::forget(self);
  1231. -
  1232. -        ObjectRef { ptr }
  1233. -    }
  1234. -}
  1235. -
  1236. -impl<T: IntoGEMObject> Drop for UniqueObjectRef<T> {
  1237. -    fn drop(&mut self) {
  1238. -        // SAFETY: Having a UniqueObjectRef implies holding a GEM
  1239. -        // reference. The free callback will take care of deallocation.
  1240. -        unsafe {
  1241. -            bindings::drm_gem_object_put((*self.ptr).gem_obj() as *const _ as *mut _);
  1242. -        }
  1243. -    }
  1244. -}
  1245. -
  1246. -impl<T: IntoGEMObject> Deref for UniqueObjectRef<T> {
  1247. +impl<T: DriverObject> Deref for Object<T> {
  1248.      type Target = T;
  1249.  
  1250.      fn deref(&self) -> &Self::Target {
  1251. -        // SAFETY: The pointer is valid per the invariant
  1252. -        unsafe { &*self.ptr }
  1253. +        &self.data
  1254.      }
  1255.  }
  1256.  
  1257. -impl<T: IntoGEMObject> DerefMut for UniqueObjectRef<T> {
  1258. -    fn deref_mut(&mut self) -> &mut Self::Target {
  1259. -        // SAFETY: The pointer is valid per the invariant
  1260. -        unsafe { &mut *self.ptr }
  1261. -    }
  1262. +impl<T: DriverObject> AllocImpl for Object<T> {
  1263. +    const ALLOC_OPS: AllocOps = AllocOps {
  1264. +        gem_create_object: None,
  1265. +        prime_handle_to_fd: None,
  1266. +        prime_fd_to_handle: None,
  1267. +        gem_prime_import: None,
  1268. +        gem_prime_import_sg_table: None,
  1269. +        dumb_create: None,
  1270. +        dumb_map_offset: None,
  1271. +    };
  1272.  }
  1273.  
  1274. -pub(super) fn create_fops() -> bindings::file_operations {
  1275. -    bindings::file_operations {
  1276. -        owner: core::ptr::null_mut(),
  1277. -        open: Some(bindings::drm_open),
  1278. -        release: Some(bindings::drm_release),
  1279. -        unlocked_ioctl: Some(bindings::drm_ioctl),
  1280. -        #[cfg(CONFIG_COMPAT)]
  1281. -        compat_ioctl: Some(bindings::drm_compat_ioctl),
  1282. -        #[cfg(not(CONFIG_COMPAT))]
  1283. -        compat_ioctl: None,
  1284. -        poll: Some(bindings::drm_poll),
  1285. -        read: Some(bindings::drm_read),
  1286. -        llseek: Some(bindings::noop_llseek),
  1287. -        mmap: Some(bindings::drm_gem_mmap),
  1288. -        ..Default::default()
  1289. +pub(super) const fn create_fops() -> bindings::file_operations {
  1290. +    // SAFETY: As by the type invariant, it is safe to initialize `bindings::file_operations`
  1291. +    // zeroed.
  1292. +    let mut fops: bindings::file_operations = unsafe { core::mem::zeroed() };
  1293. +
  1294. +    fops.owner = core::ptr::null_mut();
  1295. +    fops.open = Some(bindings::drm_open);
  1296. +    fops.release = Some(bindings::drm_release);
  1297. +    fops.unlocked_ioctl = Some(bindings::drm_ioctl);
  1298. +    #[cfg(CONFIG_COMPAT)]
  1299. +    {
  1300. +        fops.compat_ioctl = Some(bindings::drm_compat_ioctl);
  1301.      }
  1302. +    fops.poll = Some(bindings::drm_poll);
  1303. +    fops.read = Some(bindings::drm_read);
  1304. +    fops.llseek = Some(bindings::noop_llseek);
  1305. +    fops.mmap = Some(bindings::drm_gem_mmap);
  1306. +    fops.fop_flags = bindings::FOP_UNSIGNED_OFFSET;
  1307. +
  1308. +    fops
  1309.  }
  1310. diff --git a/rust/kernel/drm/ioctl.rs b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/ioctl.rs
  1311. index 39846cd35da2..9f503d9cdfed 100644
  1312. --- a/rust/kernel/drm/ioctl.rs
  1313. +++ b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/ioctl.rs
  1314. @@ -1,33 +1,36 @@
  1315.  // SPDX-License-Identifier: GPL-2.0 OR MIT
  1316. -#![allow(non_snake_case)]
  1317.  
  1318.  //! DRM IOCTL definitions.
  1319.  //!
  1320. -//! C header: [`include/drm/drm_ioctl.h`](../../../../include/drm/drm_ioctl.h)
  1321. +//! C header: [`include/linux/drm/drm_ioctl.h`](srctree/include/linux/drm/drm_ioctl.h)
  1322.  
  1323.  use crate::ioctl;
  1324.  
  1325. -const BASE: u32 = bindings::DRM_IOCTL_BASE as u32;
  1326. +const BASE: u32 = uapi::DRM_IOCTL_BASE as u32;
  1327.  
  1328.  /// Construct a DRM ioctl number with no argument.
  1329. +#[allow(non_snake_case)]
  1330.  #[inline(always)]
  1331.  pub const fn IO(nr: u32) -> u32 {
  1332.      ioctl::_IO(BASE, nr)
  1333.  }
  1334.  
  1335.  /// Construct a DRM ioctl number with a read-only argument.
  1336. +#[allow(non_snake_case)]
  1337.  #[inline(always)]
  1338.  pub const fn IOR<T>(nr: u32) -> u32 {
  1339.      ioctl::_IOR::<T>(BASE, nr)
  1340.  }
  1341.  
  1342.  /// Construct a DRM ioctl number with a write-only argument.
  1343. +#[allow(non_snake_case)]
  1344.  #[inline(always)]
  1345.  pub const fn IOW<T>(nr: u32) -> u32 {
  1346.      ioctl::_IOW::<T>(BASE, nr)
  1347.  }
  1348.  
  1349.  /// Construct a DRM ioctl number with a read-write argument.
  1350. +#[allow(non_snake_case)]
  1351.  #[inline(always)]
  1352.  pub const fn IOWR<T>(nr: u32) -> u32 {
  1353.      ioctl::_IOWR::<T>(BASE, nr)
  1354. @@ -49,8 +52,8 @@ pub const fn IOWR<T>(nr: u32) -> u32 {
  1355.  
  1356.  /// Anything that could potentially wreak a master file descriptor needs to have this flag set.
  1357.  ///
  1358. -/// Current that’s only for the SETMASTER and DROPMASTER ioctl, which e.g. logind can call to force
  1359. -/// a non-behaving master (display compositor) into compliance.
  1360. +/// Current that’s only for the SETMASTER and DROPMASTER ioctl, which e.g. logind can call to
  1361. +/// force a non-behaving master (display compositor) into compliance.
  1362.  ///
  1363.  /// This is equivalent to callers with the SYSADMIN capability.
  1364.  pub const ROOT_ONLY: u32 = bindings::drm_ioctl_flags_DRM_ROOT_ONLY;
  1365. @@ -61,7 +64,7 @@ pub const fn IOWR<T>(nr: u32) -> u32 {
  1366.  /// DRM_AUTH because they do not require authentication.
  1367.  pub const RENDER_ALLOW: u32 = bindings::drm_ioctl_flags_DRM_RENDER_ALLOW;
  1368.  
  1369. -/// Internal structures used by the [`declare_drm_ioctls!{}`] macro. Do not use directly.
  1370. +/// Internal structures used by the `declare_drm_ioctls!{}` macro. Do not use directly.
  1371.  #[doc(hidden)]
  1372.  pub mod internal {
  1373.      pub use bindings::drm_device;
  1374. @@ -78,17 +81,17 @@ pub mod internal {
  1375.  /// `argument_type` is the type name within the `bindings` crate.
  1376.  /// `user_callback` should have the following prototype:
  1377.  ///
  1378. -/// ```
  1379. -/// fn foo(device: &kernel::drm::device::Device<Self>,
  1380. +/// ```ignore
  1381. +/// fn foo(device: &kernel::drm::Device<Self>,
  1382.  ///        data: &mut bindings::argument_type,
  1383. -///        file: &kernel::drm::file::File<Self::File>,
  1384. +///        file: &kernel::drm::File<Self::File>,
  1385.  /// )
  1386.  /// ```
  1387.  /// where `Self` is the drm::drv::Driver implementation these ioctls are being declared within.
  1388.  ///
  1389.  /// # Examples
  1390.  ///
  1391. -/// ```
  1392. +/// ```ignore
  1393.  /// kernel::declare_drm_ioctls! {
  1394.  ///     (FOO_GET_PARAM, drm_foo_get_param, ioctl::RENDER_ALLOW, my_get_param_handler),
  1395.  /// }
  1396. @@ -102,11 +105,12 @@ macro_rules! declare_drm_ioctls {
  1397.              const _:() = {
  1398.                  let i: u32 = $crate::uapi::DRM_COMMAND_BASE;
  1399.                  // Assert that all the IOCTLs are in the right order and there are no gaps,
  1400. -                // and that the sizeof of the specified type is correct.
  1401. +                // and that the size of the specified type is correct.
  1402.                  $(
  1403.                      let cmd: u32 = $crate::macros::concat_idents!(DRM_IOCTL_, $cmd);
  1404.                      ::core::assert!(i == $crate::ioctl::_IOC_NR(cmd));
  1405. -                    ::core::assert!(core::mem::size_of::<$crate::uapi::$struct>() == $crate::ioctl::_IOC_SIZE(cmd));
  1406. +                    ::core::assert!(core::mem::size_of::<$crate::uapi::$struct>() ==
  1407. +                                    $crate::ioctl::_IOC_SIZE(cmd));
  1408.                      let i: u32 = i + 1;
  1409.                  )*
  1410.              };
  1411. @@ -119,24 +123,30 @@ macro_rules! declare_drm_ioctls {
  1412.                          unsafe extern "C" fn $cmd(
  1413.                                  raw_dev: *mut $crate::drm::ioctl::internal::drm_device,
  1414.                                  raw_data: *mut ::core::ffi::c_void,
  1415. -                                raw_file_priv: *mut $crate::drm::ioctl::internal::drm_file,
  1416. +                                raw_file: *mut $crate::drm::ioctl::internal::drm_file,
  1417.                          ) -> core::ffi::c_int {
  1418. -                            // SAFETY: The DRM core ensures the device lives while callbacks are
  1419. -                            // being called.
  1420. +                            // SAFETY:
  1421. +                            // - The DRM core ensures the device lives while callbacks are being
  1422. +                            //   called.
  1423. +                            // - The DRM device must have been registered when we're called through
  1424. +                            //   an IOCTL.
  1425.                              //
  1426.                              // FIXME: Currently there is nothing enforcing that the types of the
  1427.                              // dev/file match the current driver these ioctls are being declared
  1428.                              // for, and it's not clear how to enforce this within the type system.
  1429. -                            let dev = $crate::drm::device::Device::borrow(raw_dev);
  1430. -                            // SAFETY: This is just the ioctl argument, which hopefully has the right type
  1431. -                            // (we've done our best checking the size).
  1432. -                            let data = unsafe { &mut *(raw_data as *mut $crate::uapi::$struct) };
  1433. +                            let dev = $crate::drm::device::Device::as_ref(raw_dev);
  1434. +                            // SAFETY: This is just the ioctl argument, which hopefully has the
  1435. +                            // right type (we've done our best checking the size).
  1436. +                            let data = unsafe {
  1437. +                                &*(raw_data as *const $crate::types::Opaque<$crate::uapi::$struct>)
  1438. +                            };
  1439.                              // SAFETY: This is just the DRM file structure
  1440. -                            let file = unsafe { $crate::drm::file::File::from_raw(raw_file_priv) };
  1441. +                            let file = unsafe { $crate::drm::File::as_ref(raw_file) };
  1442.  
  1443. -                            match $func(dev, data, &file) {
  1444. +                            match $func(dev, data, file) {
  1445.                                  Err(e) => e.to_errno(),
  1446. -                                Ok(i) => i.try_into().unwrap_or(code::ERANGE.to_errno()),
  1447. +                                Ok(i) => i.try_into()
  1448. +                                            .unwrap_or($crate::error::code::ERANGE.to_errno()),
  1449.                              }
  1450.                          }
  1451.                          Some($cmd)
  1452. diff --git a/rust/kernel/drm/mod.rs b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/mod.rs
  1453. index 50d1bb9139dc..1b82b6945edf 100644
  1454. --- a/rust/kernel/drm/mod.rs
  1455. +++ b/home/danilo/projects/linux/drm-misc/drm-misc-next/rust/kernel/drm/mod.rs
  1456. @@ -3,12 +3,17 @@
  1457.  //! DRM subsystem abstractions.
  1458.  
  1459.  pub mod device;
  1460. -pub mod drv;
  1461. +pub mod driver;
  1462.  pub mod file;
  1463.  pub mod gem;
  1464. -#[cfg(CONFIG_DRM_GPUVM = "y")]
  1465. -pub mod gpuvm;
  1466.  pub mod ioctl;
  1467. -pub mod mm;
  1468. -pub mod sched;
  1469. -pub mod syncobj;
  1470. +
  1471. +pub use self::device::Device;
  1472. +pub use self::driver::Driver;
  1473. +pub use self::driver::DriverInfo;
  1474. +pub use self::driver::Registration;
  1475. +pub use self::file::File;
  1476. +
  1477. +pub(crate) mod private {
  1478. +    pub trait Sealed {}
  1479. +}
Advertisement
Add Comment
Please, Sign In to add comment