xref: /linux/rust/kernel/module.rs (revision 54f846db7b35069959833d2f6ace998c2e11c908)
10752a2e9SAlvin Sun // SPDX-License-Identifier: GPL-2.0
20752a2e9SAlvin Sun 
30752a2e9SAlvin Sun //! Module-related types and helpers.
40752a2e9SAlvin Sun 
50752a2e9SAlvin Sun /// The entrypoint to implementing a kernel module.
60752a2e9SAlvin Sun ///
70752a2e9SAlvin Sun /// For any teardown or cleanup operations, your type may implement [`Drop`].
80752a2e9SAlvin Sun pub trait Module: Sized + Sync + Send {
90752a2e9SAlvin Sun     /// Called at module initialization time.
100752a2e9SAlvin Sun     ///
110752a2e9SAlvin Sun     /// Use this method to perform whatever setup or registration your module
120752a2e9SAlvin Sun     /// should do.
130752a2e9SAlvin Sun     ///
140752a2e9SAlvin Sun     /// Equivalent to the `module_init` macro in the C API.
150752a2e9SAlvin Sun     fn init(module: &'static ThisModule) -> crate::error::Result<Self>;
160752a2e9SAlvin Sun }
170752a2e9SAlvin Sun 
180752a2e9SAlvin Sun /// A module that is pinned and initialised in-place.
190752a2e9SAlvin Sun pub trait InPlaceModule: Sync + Send {
200752a2e9SAlvin Sun     /// Creates an initialiser for the module.
210752a2e9SAlvin Sun     ///
220752a2e9SAlvin Sun     /// It is called when the module is loaded.
230752a2e9SAlvin Sun     fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, crate::error::Error>;
240752a2e9SAlvin Sun }
250752a2e9SAlvin Sun 
260752a2e9SAlvin Sun impl<T: Module> InPlaceModule for T {
270752a2e9SAlvin Sun     fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, crate::error::Error> {
280752a2e9SAlvin Sun         let initer = move |slot: *mut Self| {
290752a2e9SAlvin Sun             let m = <Self as Module>::init(module)?;
300752a2e9SAlvin Sun 
310752a2e9SAlvin Sun             // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`.
320752a2e9SAlvin Sun             unsafe { slot.write(m) };
330752a2e9SAlvin Sun             Ok(())
340752a2e9SAlvin Sun         };
350752a2e9SAlvin Sun 
360752a2e9SAlvin Sun         // SAFETY: On success, `initer` always fully initialises an instance of `Self`.
370752a2e9SAlvin Sun         unsafe { pin_init::pin_init_from_closure(initer) }
380752a2e9SAlvin Sun     }
390752a2e9SAlvin Sun }
400752a2e9SAlvin Sun 
410752a2e9SAlvin Sun /// Metadata attached to a [`Module`] or [`InPlaceModule`].
420752a2e9SAlvin Sun pub trait ModuleMetadata {
430752a2e9SAlvin Sun     /// The name of the module as specified in the `module!` macro.
440752a2e9SAlvin Sun     const NAME: &'static crate::str::CStr;
45*54f846dbSAlvin Sun 
46*54f846dbSAlvin Sun     /// The module's `THIS_MODULE` pointer.
47*54f846dbSAlvin Sun     const THIS_MODULE: ThisModule;
48*54f846dbSAlvin Sun }
49*54f846dbSAlvin Sun 
50*54f846dbSAlvin Sun /// Returns a reference to the `THIS_MODULE` of the given module type.
51*54f846dbSAlvin Sun #[inline]
52*54f846dbSAlvin Sun pub const fn this_module<M: ModuleMetadata>() -> &'static ThisModule {
53*54f846dbSAlvin Sun     &M::THIS_MODULE
540752a2e9SAlvin Sun }
550752a2e9SAlvin Sun 
560752a2e9SAlvin Sun /// Equivalent to `THIS_MODULE` in the C API.
570752a2e9SAlvin Sun ///
580752a2e9SAlvin Sun /// C header: [`include/linux/init.h`](srctree/include/linux/init.h)
590752a2e9SAlvin Sun pub struct ThisModule(*mut crate::bindings::module);
600752a2e9SAlvin Sun 
610752a2e9SAlvin Sun // SAFETY: `THIS_MODULE` may be used from all threads within a module.
620752a2e9SAlvin Sun unsafe impl Sync for ThisModule {}
630752a2e9SAlvin Sun 
640752a2e9SAlvin Sun impl ThisModule {
650752a2e9SAlvin Sun     /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer.
660752a2e9SAlvin Sun     ///
670752a2e9SAlvin Sun     /// # Safety
680752a2e9SAlvin Sun     ///
690752a2e9SAlvin Sun     /// The pointer must be equal to the right `THIS_MODULE`.
700752a2e9SAlvin Sun     pub const unsafe fn from_ptr(ptr: *mut crate::bindings::module) -> ThisModule {
710752a2e9SAlvin Sun         ThisModule(ptr)
720752a2e9SAlvin Sun     }
730752a2e9SAlvin Sun 
740752a2e9SAlvin Sun     /// Access the raw pointer for this module.
750752a2e9SAlvin Sun     ///
760752a2e9SAlvin Sun     /// It is up to the user to use it correctly.
770752a2e9SAlvin Sun     pub const fn as_ptr(&self) -> *mut crate::bindings::module {
780752a2e9SAlvin Sun         self.0
790752a2e9SAlvin Sun     }
800752a2e9SAlvin Sun }
81