@@ -12,12 +12,16 @@ use crate::{
1212 error:: { to_result, Result } ,
1313 prelude:: * ,
1414} ;
15- use core:: { mem, ops:: Deref , ops:: DerefMut } ;
15+ use core:: { marker :: PhantomPinned , mem, ops:: Deref , ops:: DerefMut } ;
1616
1717/// GEM object functions, which must be implemented by drivers.
1818pub trait BaseDriverObject < T : BaseObject > : Sync + Send + Sized {
19+ /// The return type of the new() function. Should be `impl PinInit<Self, Error>`.
20+ /// TODO: Remove this when return_position_impl_trait_in_trait is stable.
21+ type Initializer : PinInit < Self , Error > ;
22+
1923 /// Create a new driver data object for a GEM object of a given size.
20- fn new ( dev : & device:: Device < T :: Driver > , size : usize ) -> Result < Self > ;
24+ fn new ( dev : & device:: Device < T :: Driver > , size : usize ) -> Self :: Initializer ;
2125
2226 /// Open a new handle to an existing object, associated with a File.
2327 fn open (
@@ -188,14 +192,21 @@ impl<T: IntoGEMObject> BaseObject for T {}
188192
189193/// A base GEM object.
190194#[ repr( C ) ]
195+ #[ pin_data]
191196pub struct Object < T : DriverObject > {
192197 obj : bindings:: drm_gem_object ,
193198 // The DRM core ensures the Device exists as long as its objects exist, so we don't need to
194199 // manage the reference count here.
195200 dev : * const bindings:: drm_device ,
201+ #[ pin]
196202 inner : T ,
203+ #[ pin]
204+ _p : PhantomPinned ,
197205}
198206
207+ // SAFETY: This struct is safe to zero-initialize
208+ unsafe impl init:: Zeroable for bindings:: drm_gem_object { }
209+
199210impl < T : DriverObject > Object < T > {
200211 /// The size of this object's structure.
201212 pub const SIZE : usize = mem:: size_of :: < Self > ( ) ;
@@ -217,23 +228,31 @@ impl<T: DriverObject> Object<T> {
217228 } ;
218229
219230 /// Create a new GEM object.
220- pub fn new ( dev : & device:: Device < T :: Driver > , size : usize ) -> Result < UniqueObjectRef < Self > > {
221- let mut obj: Box < Self > = Box :: try_new ( Self {
231+ pub fn new ( dev : & device:: Device < T :: Driver > , size : usize ) -> Result < Pin < UniqueObjectRef < Self > > > {
232+ let obj: Pin < Box < Self > > = Box :: pin_init ( try_pin_init ! ( Self {
222233 // SAFETY: This struct is expected to be zero-initialized
223- obj : unsafe { mem:: zeroed ( ) } ,
234+ obj: bindings:: drm_gem_object {
235+ funcs: & Self :: OBJECT_FUNCS ,
236+ ..Default :: default ( )
237+ } ,
238+ inner <- T :: new( dev, size) ,
224239 // SAFETY: The drm subsystem guarantees that the drm_device will live as long as
225240 // the GEM object lives, so we can conjure a reference out of thin air.
226241 dev: dev. drm. get( ) ,
227- inner : T :: new ( dev , size ) ? ,
228- } ) ?;
242+ _p : PhantomPinned
243+ } ) ) ?;
229244
230- obj. obj . funcs = & Self :: OBJECT_FUNCS ;
231245 to_result ( unsafe {
232- bindings:: drm_gem_object_init ( dev. raw ( ) as * mut _ , & mut obj. obj , size)
246+ bindings:: drm_gem_object_init ( dev. raw ( ) as * mut _ , & obj. obj as * const _ as * mut _ , size)
233247 } ) ?;
234248
235- let obj_ref = UniqueObjectRef {
236- ptr : Box :: leak ( obj) ,
249+ // SAFETY: We never move out of self
250+ let obj_ref = unsafe {
251+ Pin :: new_unchecked ( UniqueObjectRef {
252+ // SAFETY: We never move out of the Box
253+ ptr : Box :: leak ( Pin :: into_inner_unchecked ( obj) ) ,
254+ _p : PhantomPinned ,
255+ } )
237256 } ;
238257
239258 Ok ( obj_ref)
@@ -316,6 +335,7 @@ pub struct UniqueObjectRef<T: IntoGEMObject> {
316335 // Invariant: the pointer is valid and initialized, and this ObjectRef owns the only reference
317336 // to it.
318337 ptr : * mut T ,
338+ _p : PhantomPinned ,
319339}
320340
321341impl < T : IntoGEMObject > UniqueObjectRef < T > {
0 commit comments