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