@@ -17,23 +17,35 @@ use macros::{pin_data, pinned_drop};
17
17
/// For instance, the PCI subsystem would set `RegType` to `bindings::pci_driver` and call
18
18
/// `bindings::__pci_register_driver` from `RegistrationOps::register` and
19
19
/// `bindings::pci_unregister_driver` from `RegistrationOps::unregister`.
20
- pub trait RegistrationOps {
20
+ ///
21
+ /// # Safety
22
+ ///
23
+ /// A call to [`RegistrationOps::unregister`] for a given instance of `RegType` is only valid if a
24
+ /// preceding call to [`RegistrationOps::register`] has been successful.
25
+ pub unsafe trait RegistrationOps {
21
26
/// The type that holds information about the registration. This is typically a struct defined
22
27
/// by the C portion of the kernel.
23
28
type RegType : Default ;
24
29
25
30
/// Registers a driver.
26
31
///
32
+ /// # Safety
33
+ ///
27
34
/// On success, `reg` must remain pinned and valid until the matching call to
28
35
/// [`RegistrationOps::unregister`].
29
- fn register (
36
+ unsafe fn register (
30
37
reg : & Opaque < Self :: RegType > ,
31
38
name : & ' static CStr ,
32
39
module : & ' static ThisModule ,
33
40
) -> Result ;
34
41
35
42
/// Unregisters a driver previously registered with [`RegistrationOps::register`].
36
- fn unregister ( reg : & Opaque < Self :: RegType > ) ;
43
+ ///
44
+ /// # Safety
45
+ ///
46
+ /// Must only be called after a preceding successful call to [`RegistrationOps::register`] for
47
+ /// the same `reg`.
48
+ unsafe fn unregister ( reg : & Opaque < Self :: RegType > ) ;
37
49
}
38
50
39
51
/// A [`Registration`] is a generic type that represents the registration of some driver type (e.g.
@@ -68,7 +80,8 @@ impl<T: RegistrationOps> Registration<T> {
68
80
// just been initialised above, so it's also valid for read.
69
81
let drv = unsafe { & * ( ptr as * const Opaque <T :: RegType >) } ;
70
82
71
- T :: register( drv, name, module)
83
+ // SAFETY: `drv` is guaranteed to be pinned until `T::unregister`.
84
+ unsafe { T :: register( drv, name, module) }
72
85
} ) ,
73
86
} )
74
87
}
@@ -77,7 +90,9 @@ impl<T: RegistrationOps> Registration<T> {
77
90
#[ pinned_drop]
78
91
impl < T : RegistrationOps > PinnedDrop for Registration < T > {
79
92
fn drop ( self : Pin < & mut Self > ) {
80
- T :: unregister ( & self . reg ) ;
93
+ // SAFETY: The existence of `self` guarantees that `self.reg` has previously been
94
+ // successfully registered with `T::register`
95
+ unsafe { T :: unregister ( & self . reg ) } ;
81
96
}
82
97
}
83
98
0 commit comments