xref: /linux-6.15/rust/kernel/lib.rs (revision e1dfaa33)
1247b365dSWedson Almeida Filho // SPDX-License-Identifier: GPL-2.0
2247b365dSWedson Almeida Filho 
3247b365dSWedson Almeida Filho //! The `kernel` crate.
4247b365dSWedson Almeida Filho //!
5247b365dSWedson Almeida Filho //! This crate contains the kernel APIs that have been ported or wrapped for
6247b365dSWedson Almeida Filho //! usage by Rust code in the kernel and is shared by all of them.
7247b365dSWedson Almeida Filho //!
8247b365dSWedson Almeida Filho //! In other words, all the rest of the Rust code in the kernel (e.g. kernel
9247b365dSWedson Almeida Filho //! modules written in Rust) depends on [`core`] and this crate.
10247b365dSWedson Almeida Filho //!
11247b365dSWedson Almeida Filho //! If you need a kernel C API that is not ported or wrapped yet here, then
12247b365dSWedson Almeida Filho //! do so first instead of bypassing this crate.
13247b365dSWedson Almeida Filho 
14247b365dSWedson Almeida Filho #![no_std]
15c95bbb59SGary Guo #![feature(arbitrary_self_types)]
1647cb6bf7SXiangfei Ding #![cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, feature(derive_coerce_pointee))]
1747cb6bf7SXiangfei Ding #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(coerce_unsized))]
1847cb6bf7SXiangfei Ding #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(dispatch_from_dyn))]
1947cb6bf7SXiangfei Ding #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(unsize))]
202aac4cd7SDanilo Krummrich #![feature(inline_const)]
211f9ed172SMiguel Ojeda #![feature(lint_reasons)]
22*e1dfaa33SAntonio Hickey // Stable in Rust 1.82
23*e1dfaa33SAntonio Hickey #![feature(raw_ref_op)]
249b90864bSDanilo Krummrich // Stable in Rust 1.83
259b90864bSDanilo Krummrich #![feature(const_maybe_uninit_as_mut_ptr)]
269b90864bSDanilo Krummrich #![feature(const_mut_refs)]
279b90864bSDanilo Krummrich #![feature(const_ptr_write)]
289b90864bSDanilo Krummrich #![feature(const_refs_to_cell)]
29247b365dSWedson Almeida Filho 
30247b365dSWedson Almeida Filho // Ensure conditional compilation based on the kernel configuration works;
31247b365dSWedson Almeida Filho // otherwise we may silently break things like initcall handling.
32247b365dSWedson Almeida Filho #[cfg(not(CONFIG_RUST))]
33247b365dSWedson Almeida Filho compile_error!("Missing kernel configuration for conditional compilation");
34247b365dSWedson Almeida Filho 
3590e53c5eSBenno Lossin // Allow proc-macros to refer to `::kernel` inside the `kernel` crate (this crate).
3690e53c5eSBenno Lossin extern crate self as kernel;
3790e53c5eSBenno Lossin 
38d072acdaSGary Guo pub use ffi;
39d072acdaSGary Guo 
4031d94d8fSWedson Almeida Filho pub mod alloc;
413253aba3SAndreas Hindborg #[cfg(CONFIG_BLOCK)]
423253aba3SAndreas Hindborg pub mod block;
43614724e7SMiguel Ojeda #[doc(hidden)]
44614724e7SMiguel Ojeda pub mod build_assert;
45a3df991dSWedson Almeida Filho pub mod cred;
46a674fefdSDanilo Krummrich pub mod device;
479b90864bSDanilo Krummrich pub mod device_id;
4876c01dedSDanilo Krummrich pub mod devres;
49ad2907b4SAbdiel Janulgue pub mod dma;
50ea7e1828SDanilo Krummrich pub mod driver;
51247b365dSWedson Almeida Filho pub mod error;
5278418f30SLyude Paul pub mod faux;
53de658283SDanilo Krummrich #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)]
54de658283SDanilo Krummrich pub mod firmware;
5585184982SWedson Almeida Filho pub mod fs;
5690e53c5eSBenno Lossin pub mod init;
579b880189SDanilo Krummrich pub mod io;
58ea76e08fSAsahi Lina pub mod ioctl;
596e59bcc9SAlice Ryhl pub mod jump_label;
60a66d733dSMiguel Ojeda #[cfg(CONFIG_KUNIT)]
61a66d733dSMiguel Ojeda pub mod kunit;
626cd34171SAlice Ryhl pub mod list;
63f893691eSAlice Ryhl pub mod miscdevice;
64f20fd544SFUJITA Tomonori #[cfg(CONFIG_NET)]
65f20fd544SFUJITA Tomonori pub mod net;
66bbe3b4d1SDanilo Krummrich pub mod of;
67fc6e66f4SAlice Ryhl pub mod page;
687e16820fSDanilo Krummrich #[cfg(CONFIG_PCI)]
697e16820fSDanilo Krummrich pub mod pci;
70e0020ba6SChristian Brauner pub mod pid_namespace;
71683a63beSDanilo Krummrich pub mod platform;
72247b365dSWedson Almeida Filho pub mod prelude;
73247b365dSWedson Almeida Filho pub mod print;
74a0d13aacSWedson Almeida Filho pub mod rbtree;
750494d9c8SWedson Almeida Filho pub mod revocable;
7694d356c0SAlice Ryhl pub mod security;
7722018a5aSAlice Ryhl pub mod seq_file;
78ece207a8SMiguel Ojeda pub mod sizes;
79ef9e3797SMiguel Ojeda mod static_assert;
80bee16889SNiklas Mohrin #[doc(hidden)]
81bee16889SNiklas Mohrin pub mod std_vendor;
82247b365dSWedson Almeida Filho pub mod str;
839dc04365SWedson Almeida Filho pub mod sync;
84313c4281SWedson Almeida Filho pub mod task;
8582e17087SAlice Ryhl pub mod time;
86ad37bcd9SAlice Ryhl pub mod tracepoint;
87ce1c54fdSAliet Exposito Garcia pub mod transmute;
88ba20915bSWedson Almeida Filho pub mod types;
891b580e7bSWedson Almeida Filho pub mod uaccess;
90d4d791d4SAlice Ryhl pub mod workqueue;
91247b365dSWedson Almeida Filho 
92247b365dSWedson Almeida Filho #[doc(hidden)]
93247b365dSWedson Almeida Filho pub use bindings;
94247b365dSWedson Almeida Filho pub use macros;
954e174665SAsahi Lina pub use uapi;
96247b365dSWedson Almeida Filho 
97247b365dSWedson Almeida Filho /// Prefix to appear before log messages printed from within the `kernel` crate.
98247b365dSWedson Almeida Filho const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
99247b365dSWedson Almeida Filho 
100247b365dSWedson Almeida Filho /// The top level entrypoint to implementing a kernel module.
101247b365dSWedson Almeida Filho ///
102247b365dSWedson Almeida Filho /// For any teardown or cleanup operations, your type may implement [`Drop`].
103323617f6SWedson Almeida Filho pub trait Module: Sized + Sync + Send {
104247b365dSWedson Almeida Filho     /// Called at module initialization time.
105247b365dSWedson Almeida Filho     ///
106247b365dSWedson Almeida Filho     /// Use this method to perform whatever setup or registration your module
107247b365dSWedson Almeida Filho     /// should do.
108247b365dSWedson Almeida Filho     ///
109247b365dSWedson Almeida Filho     /// Equivalent to the `module_init` macro in the C API.
init(module: &'static ThisModule) -> error::Result<Self>110247b365dSWedson Almeida Filho     fn init(module: &'static ThisModule) -> error::Result<Self>;
111247b365dSWedson Almeida Filho }
112247b365dSWedson Almeida Filho 
1137f15c46aSWedson Almeida Filho /// A module that is pinned and initialised in-place.
1147f15c46aSWedson Almeida Filho pub trait InPlaceModule: Sync + Send {
1157f15c46aSWedson Almeida Filho     /// Creates an initialiser for the module.
1167f15c46aSWedson Almeida Filho     ///
1177f15c46aSWedson Almeida Filho     /// It is called when the module is loaded.
init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error>118dbd5058bSBenno Lossin     fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error>;
1197f15c46aSWedson Almeida Filho }
1207f15c46aSWedson Almeida Filho 
1217f15c46aSWedson Almeida Filho impl<T: Module> InPlaceModule for T {
init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error>122dbd5058bSBenno Lossin     fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error> {
1237f15c46aSWedson Almeida Filho         let initer = move |slot: *mut Self| {
1247f15c46aSWedson Almeida Filho             let m = <Self as Module>::init(module)?;
1257f15c46aSWedson Almeida Filho 
1267f15c46aSWedson Almeida Filho             // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`.
1277f15c46aSWedson Almeida Filho             unsafe { slot.write(m) };
1287f15c46aSWedson Almeida Filho             Ok(())
1297f15c46aSWedson Almeida Filho         };
1307f15c46aSWedson Almeida Filho 
1317f15c46aSWedson Almeida Filho         // SAFETY: On success, `initer` always fully initialises an instance of `Self`.
132dbd5058bSBenno Lossin         unsafe { pin_init::pin_init_from_closure(initer) }
1337f15c46aSWedson Almeida Filho     }
1347f15c46aSWedson Almeida Filho }
1357f15c46aSWedson Almeida Filho 
136a790265cSDanilo Krummrich /// Metadata attached to a [`Module`] or [`InPlaceModule`].
137a790265cSDanilo Krummrich pub trait ModuleMetadata {
138a790265cSDanilo Krummrich     /// The name of the module as specified in the `module!` macro.
139a790265cSDanilo Krummrich     const NAME: &'static crate::str::CStr;
140a790265cSDanilo Krummrich }
141a790265cSDanilo Krummrich 
142247b365dSWedson Almeida Filho /// Equivalent to `THIS_MODULE` in the C API.
143247b365dSWedson Almeida Filho ///
1448b55dc86SYutaro Ohno /// C header: [`include/linux/init.h`](srctree/include/linux/init.h)
145247b365dSWedson Almeida Filho pub struct ThisModule(*mut bindings::module);
146247b365dSWedson Almeida Filho 
147247b365dSWedson Almeida Filho // SAFETY: `THIS_MODULE` may be used from all threads within a module.
148247b365dSWedson Almeida Filho unsafe impl Sync for ThisModule {}
149247b365dSWedson Almeida Filho 
150247b365dSWedson Almeida Filho impl ThisModule {
151247b365dSWedson Almeida Filho     /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer.
152247b365dSWedson Almeida Filho     ///
153247b365dSWedson Almeida Filho     /// # Safety
154247b365dSWedson Almeida Filho     ///
155247b365dSWedson Almeida Filho     /// The pointer must be equal to the right `THIS_MODULE`.
from_ptr(ptr: *mut bindings::module) -> ThisModule156247b365dSWedson Almeida Filho     pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> ThisModule {
157247b365dSWedson Almeida Filho         ThisModule(ptr)
158247b365dSWedson Almeida Filho     }
159d0f0241dSAlice Ryhl 
160d0f0241dSAlice Ryhl     /// Access the raw pointer for this module.
161d0f0241dSAlice Ryhl     ///
162d0f0241dSAlice Ryhl     /// It is up to the user to use it correctly.
as_ptr(&self) -> *mut bindings::module163d0f0241dSAlice Ryhl     pub const fn as_ptr(&self) -> *mut bindings::module {
164d0f0241dSAlice Ryhl         self.0
165d0f0241dSAlice Ryhl     }
166247b365dSWedson Almeida Filho }
167247b365dSWedson Almeida Filho 
168247b365dSWedson Almeida Filho #[cfg(not(any(testlib, test)))]
169247b365dSWedson Almeida Filho #[panic_handler]
panic(info: &core::panic::PanicInfo<'_>) -> !170247b365dSWedson Almeida Filho fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
171247b365dSWedson Almeida Filho     pr_emerg!("{}\n", info);
172247b365dSWedson Almeida Filho     // SAFETY: FFI call.
173247b365dSWedson Almeida Filho     unsafe { bindings::BUG() };
174247b365dSWedson Almeida Filho }
175e9441710SWedson Almeida Filho 
176e9441710SWedson Almeida Filho /// Produces a pointer to an object from a pointer to one of its fields.
177e9441710SWedson Almeida Filho ///
178e9441710SWedson Almeida Filho /// # Safety
179e9441710SWedson Almeida Filho ///
180e9441710SWedson Almeida Filho /// The pointer passed to this macro, and the pointer returned by this macro, must both be in
181e9441710SWedson Almeida Filho /// bounds of the same allocation.
182e9441710SWedson Almeida Filho ///
183e9441710SWedson Almeida Filho /// # Examples
184e9441710SWedson Almeida Filho ///
185e9441710SWedson Almeida Filho /// ```
186e9441710SWedson Almeida Filho /// # use kernel::container_of;
187e9441710SWedson Almeida Filho /// struct Test {
188e9441710SWedson Almeida Filho ///     a: u64,
189e9441710SWedson Almeida Filho ///     b: u32,
190e9441710SWedson Almeida Filho /// }
191e9441710SWedson Almeida Filho ///
192e9441710SWedson Almeida Filho /// let test = Test { a: 10, b: 20 };
193e9441710SWedson Almeida Filho /// let b_ptr = &test.b;
194e9441710SWedson Almeida Filho /// // SAFETY: The pointer points at the `b` field of a `Test`, so the resulting pointer will be
195e9441710SWedson Almeida Filho /// // in-bounds of the same allocation as `b_ptr`.
196e9441710SWedson Almeida Filho /// let test_alias = unsafe { container_of!(b_ptr, Test, b) };
197e9441710SWedson Almeida Filho /// assert!(core::ptr::eq(&test, test_alias));
198e9441710SWedson Almeida Filho /// ```
199e9441710SWedson Almeida Filho #[macro_export]
200e9441710SWedson Almeida Filho macro_rules! container_of {
201e9441710SWedson Almeida Filho     ($ptr:expr, $type:ty, $($f:tt)*) => {{
202e9441710SWedson Almeida Filho         let ptr = $ptr as *const _ as *const u8;
203e9441710SWedson Almeida Filho         let offset: usize = ::core::mem::offset_of!($type, $($f)*);
204e9441710SWedson Almeida Filho         ptr.sub(offset) as *const $type
205e9441710SWedson Almeida Filho     }}
206e9441710SWedson Almeida Filho }
207169484abSAlice Ryhl 
208169484abSAlice Ryhl /// Helper for `.rs.S` files.
209169484abSAlice Ryhl #[doc(hidden)]
210169484abSAlice Ryhl #[macro_export]
211169484abSAlice Ryhl macro_rules! concat_literals {
212169484abSAlice Ryhl     ($( $asm:literal )* ) => {
213169484abSAlice Ryhl         ::core::concat!($($asm),*)
214169484abSAlice Ryhl     };
215169484abSAlice Ryhl }
216169484abSAlice Ryhl 
217169484abSAlice Ryhl /// Wrapper around `asm!` configured for use in the kernel.
218169484abSAlice Ryhl ///
219169484abSAlice Ryhl /// Uses a semicolon to avoid parsing ambiguities, even though this does not match native `asm!`
220169484abSAlice Ryhl /// syntax.
221169484abSAlice Ryhl // For x86, `asm!` uses intel syntax by default, but we want to use at&t syntax in the kernel.
222169484abSAlice Ryhl #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
223169484abSAlice Ryhl #[macro_export]
224169484abSAlice Ryhl macro_rules! asm {
225169484abSAlice Ryhl     ($($asm:expr),* ; $($rest:tt)*) => {
226169484abSAlice Ryhl         ::core::arch::asm!( $($asm)*, options(att_syntax), $($rest)* )
227169484abSAlice Ryhl     };
228169484abSAlice Ryhl }
229169484abSAlice Ryhl 
230169484abSAlice Ryhl /// Wrapper around `asm!` configured for use in the kernel.
231169484abSAlice Ryhl ///
232169484abSAlice Ryhl /// Uses a semicolon to avoid parsing ambiguities, even though this does not match native `asm!`
233169484abSAlice Ryhl /// syntax.
234169484abSAlice Ryhl // For non-x86 arches we just pass through to `asm!`.
235169484abSAlice Ryhl #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
236169484abSAlice Ryhl #[macro_export]
237169484abSAlice Ryhl macro_rules! asm {
238169484abSAlice Ryhl     ($($asm:expr),* ; $($rest:tt)*) => {
239169484abSAlice Ryhl         ::core::arch::asm!( $($asm)*, $($rest)* )
240169484abSAlice Ryhl     };
241169484abSAlice Ryhl }
242