kernel/
lib.rs

1// SPDX-License-Identifier: GPL-2.0
2
3//! The `kernel` crate.
4//!
5//! This crate contains the kernel APIs that have been ported or wrapped for
6//! usage by Rust code in the kernel and is shared by all of them.
7//!
8//! In other words, all the rest of the Rust code in the kernel (e.g. kernel
9//! modules written in Rust) depends on [`core`] and this crate.
10//!
11//! If you need a kernel C API that is not ported or wrapped yet here, then
12//! do so first instead of bypassing this crate.
13
14#![no_std]
15#![feature(arbitrary_self_types)]
16#![cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, feature(derive_coerce_pointee))]
17#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(coerce_unsized))]
18#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(dispatch_from_dyn))]
19#![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(unsize))]
20#![feature(inline_const)]
21#![feature(lint_reasons)]
22// Stable in Rust 1.82
23#![feature(raw_ref_op)]
24// Stable in Rust 1.83
25#![feature(const_maybe_uninit_as_mut_ptr)]
26#![feature(const_mut_refs)]
27#![feature(const_ptr_write)]
28#![feature(const_refs_to_cell)]
29// To be determined.
30#![feature(used_with_arg)]
31
32// Ensure conditional compilation based on the kernel configuration works;
33// otherwise we may silently break things like initcall handling.
34#[cfg(not(CONFIG_RUST))]
35compile_error!("Missing kernel configuration for conditional compilation");
36
37// Allow proc-macros to refer to `::kernel` inside the `kernel` crate (this crate).
38extern crate self as kernel;
39
40pub use ffi;
41
42pub mod alloc;
43#[cfg(CONFIG_BLOCK)]
44pub mod block;
45#[doc(hidden)]
46pub mod build_assert;
47pub mod cred;
48pub mod device;
49pub mod device_id;
50pub mod devres;
51pub mod dma;
52pub mod driver;
53pub mod error;
54pub mod faux;
55#[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)]
56pub mod firmware;
57pub mod fs;
58pub mod init;
59pub mod io;
60pub mod ioctl;
61pub mod jump_label;
62#[cfg(CONFIG_KUNIT)]
63pub mod kunit;
64pub mod list;
65pub mod miscdevice;
66#[cfg(CONFIG_NET)]
67pub mod net;
68pub mod of;
69pub mod page;
70#[cfg(CONFIG_PCI)]
71pub mod pci;
72pub mod pid_namespace;
73pub mod platform;
74pub mod prelude;
75pub mod print;
76pub mod rbtree;
77pub mod revocable;
78pub mod security;
79pub mod seq_file;
80pub mod sizes;
81mod static_assert;
82#[doc(hidden)]
83pub mod std_vendor;
84pub mod str;
85pub mod sync;
86pub mod task;
87pub mod time;
88pub mod tracepoint;
89pub mod transmute;
90pub mod types;
91pub mod uaccess;
92pub mod workqueue;
93
94#[doc(hidden)]
95pub use bindings;
96pub use macros;
97pub use uapi;
98
99/// Prefix to appear before log messages printed from within the `kernel` crate.
100const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
101
102/// The top level entrypoint to implementing a kernel module.
103///
104/// For any teardown or cleanup operations, your type may implement [`Drop`].
105pub trait Module: Sized + Sync + Send {
106    /// Called at module initialization time.
107    ///
108    /// Use this method to perform whatever setup or registration your module
109    /// should do.
110    ///
111    /// Equivalent to the `module_init` macro in the C API.
112    fn init(module: &'static ThisModule) -> error::Result<Self>;
113}
114
115/// A module that is pinned and initialised in-place.
116pub trait InPlaceModule: Sync + Send {
117    /// Creates an initialiser for the module.
118    ///
119    /// It is called when the module is loaded.
120    fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error>;
121}
122
123impl<T: Module> InPlaceModule for T {
124    fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error> {
125        let initer = move |slot: *mut Self| {
126            let m = <Self as Module>::init(module)?;
127
128            // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`.
129            unsafe { slot.write(m) };
130            Ok(())
131        };
132
133        // SAFETY: On success, `initer` always fully initialises an instance of `Self`.
134        unsafe { pin_init::pin_init_from_closure(initer) }
135    }
136}
137
138/// Metadata attached to a [`Module`] or [`InPlaceModule`].
139pub trait ModuleMetadata {
140    /// The name of the module as specified in the `module!` macro.
141    const NAME: &'static crate::str::CStr;
142}
143
144/// Equivalent to `THIS_MODULE` in the C API.
145///
146/// C header: [`include/linux/init.h`](srctree/include/linux/init.h)
147pub struct ThisModule(*mut bindings::module);
148
149// SAFETY: `THIS_MODULE` may be used from all threads within a module.
150unsafe impl Sync for ThisModule {}
151
152impl ThisModule {
153    /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer.
154    ///
155    /// # Safety
156    ///
157    /// The pointer must be equal to the right `THIS_MODULE`.
158    pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> ThisModule {
159        ThisModule(ptr)
160    }
161
162    /// Access the raw pointer for this module.
163    ///
164    /// It is up to the user to use it correctly.
165    pub const fn as_ptr(&self) -> *mut bindings::module {
166        self.0
167    }
168}
169
170#[cfg(not(any(testlib, test)))]
171#[panic_handler]
172fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
173    pr_emerg!("{}\n", info);
174    // SAFETY: FFI call.
175    unsafe { bindings::BUG() };
176}
177
178/// Produces a pointer to an object from a pointer to one of its fields.
179///
180/// # Safety
181///
182/// The pointer passed to this macro, and the pointer returned by this macro, must both be in
183/// bounds of the same allocation.
184///
185/// # Examples
186///
187/// ```
188/// # use kernel::container_of;
189/// struct Test {
190///     a: u64,
191///     b: u32,
192/// }
193///
194/// let test = Test { a: 10, b: 20 };
195/// let b_ptr = &test.b;
196/// // SAFETY: The pointer points at the `b` field of a `Test`, so the resulting pointer will be
197/// // in-bounds of the same allocation as `b_ptr`.
198/// let test_alias = unsafe { container_of!(b_ptr, Test, b) };
199/// assert!(core::ptr::eq(&test, test_alias));
200/// ```
201#[macro_export]
202macro_rules! container_of {
203    ($ptr:expr, $type:ty, $($f:tt)*) => {{
204        let ptr = $ptr as *const _ as *const u8;
205        let offset: usize = ::core::mem::offset_of!($type, $($f)*);
206        ptr.sub(offset) as *const $type
207    }}
208}
209
210/// Helper for `.rs.S` files.
211#[doc(hidden)]
212#[macro_export]
213macro_rules! concat_literals {
214    ($( $asm:literal )* ) => {
215        ::core::concat!($($asm),*)
216    };
217}
218
219/// Wrapper around `asm!` configured for use in the kernel.
220///
221/// Uses a semicolon to avoid parsing ambiguities, even though this does not match native `asm!`
222/// syntax.
223// For x86, `asm!` uses intel syntax by default, but we want to use at&t syntax in the kernel.
224#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
225#[macro_export]
226macro_rules! asm {
227    ($($asm:expr),* ; $($rest:tt)*) => {
228        ::core::arch::asm!( $($asm)*, options(att_syntax), $($rest)* )
229    };
230}
231
232/// Wrapper around `asm!` configured for use in the kernel.
233///
234/// Uses a semicolon to avoid parsing ambiguities, even though this does not match native `asm!`
235/// syntax.
236// For non-x86 arches we just pass through to `asm!`.
237#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
238#[macro_export]
239macro_rules! asm {
240    ($($asm:expr),* ; $($rest:tt)*) => {
241        ::core::arch::asm!( $($asm)*, $($rest)* )
242    };
243}