@@ -12,7 +12,7 @@ use crate::{
1212use core:: {
1313 marker:: PhantomData ,
1414 mem,
15- mem:: { ManuallyDrop , MaybeUninit } ,
15+ mem:: MaybeUninit ,
1616 ops:: { Deref , DerefMut } ,
1717 ptr:: addr_of_mut,
1818 slice,
@@ -70,23 +70,15 @@ pub struct Object<T: DriverObject> {
7070 obj : bindings:: drm_gem_shmem_object ,
7171 // The DRM core ensures the Device exists as long as its objects exist, so we don't need to
7272 // manage the reference count here.
73- dev : ManuallyDrop < device:: Device < T :: Driver > > ,
73+ dev : * const bindings:: drm_device ,
74+ #[ pin]
7475 inner : T ,
7576}
7677
7778unsafe extern "C" fn gem_create_object < T : DriverObject > (
78- raw_dev : * mut bindings:: drm_device ,
79+ dev : * mut bindings:: drm_device ,
7980 size : usize ,
8081) -> * mut bindings:: drm_gem_object {
81- // SAFETY: GEM ensures the device lives as long as its objects live,
82- // so we can conjure up a reference from thin air and never drop it.
83- let dev = ManuallyDrop :: new ( unsafe { device:: Device :: from_raw ( raw_dev) } ) ;
84-
85- let inner = match T :: new ( & * dev, size) {
86- Ok ( v) => v,
87- Err ( e) => return e. to_ptr ( ) ,
88- } ;
89-
9082 let p = unsafe {
9183 bindings:: krealloc (
9284 core:: ptr:: null ( ) ,
@@ -99,10 +91,19 @@ unsafe extern "C" fn gem_create_object<T: DriverObject>(
9991 return ENOMEM . to_ptr ( ) ;
10092 }
10193
102- // SAFETY: p is valid as long as the alloc succeeded
103- unsafe {
104- addr_of_mut ! ( ( * p) . dev) . write ( dev) ;
105- addr_of_mut ! ( ( * p) . inner) . write ( inner) ;
94+ let init = try_pin_init ! ( Object {
95+ obj <- init:: zeroed( ) ,
96+ // SAFETY: GEM ensures the device lives as long as its objects live
97+ inner <- T :: new( unsafe { device:: Device :: borrow( dev) } , size) ,
98+ dev,
99+ } ) ;
100+
101+ // SAFETY: p is a valid pointer to an uninitialized Object<T>.
102+ if let Err ( e) = unsafe { init. __pinned_init ( p) } {
103+ // SAFETY: p is a valid pointer from `krealloc` and __pinned_init guarantees we can dealloc it.
104+ unsafe { bindings:: kfree ( p as * mut _ ) } ;
105+
106+ return e. to_ptr ( ) ;
106107 }
107108
108109 // SAFETY: drm_gem_shmem_object is safe to zero-init, and
@@ -160,7 +161,7 @@ impl<T: DriverObject> Object<T> {
160161 pub fn new ( dev : & device:: Device < T :: Driver > , size : usize ) -> Result < gem:: UniqueObjectRef < Self > > {
161162 // SAFETY: This function can be called as long as the ALLOC_OPS are set properly
162163 // for this driver, and the gem_create_object is called.
163- let p = unsafe { bindings:: drm_gem_shmem_create ( dev. raw ( ) as * mut _ , size) } ;
164+ let p = unsafe { bindings:: drm_gem_shmem_create ( dev. raw_mut ( ) , size) } ;
164165 let p = crate :: container_of!( p, Object <T >, obj) as * mut _ ;
165166
166167 // SAFETY: The gem_create_object callback ensures this is a valid Object<T>,
@@ -172,7 +173,9 @@ impl<T: DriverObject> Object<T> {
172173
173174 /// Returns the `Device` that owns this GEM object.
174175 pub fn dev ( & self ) -> & device:: Device < T :: Driver > {
175- & self . dev
176+ // SAFETY: GEM ensures that the device outlives its objects, so we can
177+ // just borrow here.
178+ unsafe { device:: Device :: borrow ( self . dev ) }
176179 }
177180
178181 /// Creates (if necessary) and returns a scatter-gather table of DMA pages for this object.
0 commit comments