xref: /linux/rust/kernel/module.rs (revision 0752a2e96e131ef1dff9740e1d4eb4a960778edb)
1*0752a2e9SAlvin Sun // SPDX-License-Identifier: GPL-2.0
2*0752a2e9SAlvin Sun 
3*0752a2e9SAlvin Sun //! Module-related types and helpers.
4*0752a2e9SAlvin Sun 
5*0752a2e9SAlvin Sun /// The entrypoint to implementing a kernel module.
6*0752a2e9SAlvin Sun ///
7*0752a2e9SAlvin Sun /// For any teardown or cleanup operations, your type may implement [`Drop`].
8*0752a2e9SAlvin Sun pub trait Module: Sized + Sync + Send {
9*0752a2e9SAlvin Sun     /// Called at module initialization time.
10*0752a2e9SAlvin Sun     ///
11*0752a2e9SAlvin Sun     /// Use this method to perform whatever setup or registration your module
12*0752a2e9SAlvin Sun     /// should do.
13*0752a2e9SAlvin Sun     ///
14*0752a2e9SAlvin Sun     /// Equivalent to the `module_init` macro in the C API.
15*0752a2e9SAlvin Sun     fn init(module: &'static ThisModule) -> crate::error::Result<Self>;
16*0752a2e9SAlvin Sun }
17*0752a2e9SAlvin Sun 
18*0752a2e9SAlvin Sun /// A module that is pinned and initialised in-place.
19*0752a2e9SAlvin Sun pub trait InPlaceModule: Sync + Send {
20*0752a2e9SAlvin Sun     /// Creates an initialiser for the module.
21*0752a2e9SAlvin Sun     ///
22*0752a2e9SAlvin Sun     /// It is called when the module is loaded.
23*0752a2e9SAlvin Sun     fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, crate::error::Error>;
24*0752a2e9SAlvin Sun }
25*0752a2e9SAlvin Sun 
26*0752a2e9SAlvin Sun impl<T: Module> InPlaceModule for T {
27*0752a2e9SAlvin Sun     fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, crate::error::Error> {
28*0752a2e9SAlvin Sun         let initer = move |slot: *mut Self| {
29*0752a2e9SAlvin Sun             let m = <Self as Module>::init(module)?;
30*0752a2e9SAlvin Sun 
31*0752a2e9SAlvin Sun             // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`.
32*0752a2e9SAlvin Sun             unsafe { slot.write(m) };
33*0752a2e9SAlvin Sun             Ok(())
34*0752a2e9SAlvin Sun         };
35*0752a2e9SAlvin Sun 
36*0752a2e9SAlvin Sun         // SAFETY: On success, `initer` always fully initialises an instance of `Self`.
37*0752a2e9SAlvin Sun         unsafe { pin_init::pin_init_from_closure(initer) }
38*0752a2e9SAlvin Sun     }
39*0752a2e9SAlvin Sun }
40*0752a2e9SAlvin Sun 
41*0752a2e9SAlvin Sun /// Metadata attached to a [`Module`] or [`InPlaceModule`].
42*0752a2e9SAlvin Sun pub trait ModuleMetadata {
43*0752a2e9SAlvin Sun     /// The name of the module as specified in the `module!` macro.
44*0752a2e9SAlvin Sun     const NAME: &'static crate::str::CStr;
45*0752a2e9SAlvin Sun }
46*0752a2e9SAlvin Sun 
47*0752a2e9SAlvin Sun /// Equivalent to `THIS_MODULE` in the C API.
48*0752a2e9SAlvin Sun ///
49*0752a2e9SAlvin Sun /// C header: [`include/linux/init.h`](srctree/include/linux/init.h)
50*0752a2e9SAlvin Sun pub struct ThisModule(*mut crate::bindings::module);
51*0752a2e9SAlvin Sun 
52*0752a2e9SAlvin Sun // SAFETY: `THIS_MODULE` may be used from all threads within a module.
53*0752a2e9SAlvin Sun unsafe impl Sync for ThisModule {}
54*0752a2e9SAlvin Sun 
55*0752a2e9SAlvin Sun impl ThisModule {
56*0752a2e9SAlvin Sun     /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer.
57*0752a2e9SAlvin Sun     ///
58*0752a2e9SAlvin Sun     /// # Safety
59*0752a2e9SAlvin Sun     ///
60*0752a2e9SAlvin Sun     /// The pointer must be equal to the right `THIS_MODULE`.
61*0752a2e9SAlvin Sun     pub const unsafe fn from_ptr(ptr: *mut crate::bindings::module) -> ThisModule {
62*0752a2e9SAlvin Sun         ThisModule(ptr)
63*0752a2e9SAlvin Sun     }
64*0752a2e9SAlvin Sun 
65*0752a2e9SAlvin Sun     /// Access the raw pointer for this module.
66*0752a2e9SAlvin Sun     ///
67*0752a2e9SAlvin Sun     /// It is up to the user to use it correctly.
68*0752a2e9SAlvin Sun     pub const fn as_ptr(&self) -> *mut crate::bindings::module {
69*0752a2e9SAlvin Sun         self.0
70*0752a2e9SAlvin Sun     }
71*0752a2e9SAlvin Sun }
72