Guest User

Rust DRM Diff

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