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
30// Ensure conditional compilation based on the kernel configuration works;
31// otherwise we may silently break things like initcall handling.
32#[cfg(not(CONFIG_RUST))]
33compile_error!("Missing kernel configuration for conditional compilation");
34
35// Allow proc-macros to refer to `::kernel` inside the `kernel` crate (this crate).
36extern crate self as kernel;
37
38pub use ffi;
39
40pub mod alloc;
41#[cfg(CONFIG_AUXILIARY_BUS)]
42pub mod auxiliary;
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;
66pub mod mm;
67#[cfg(CONFIG_NET)]
68pub mod net;
69pub mod of;
70pub mod page;
71#[cfg(CONFIG_PCI)]
72pub mod pci;
73pub mod pid_namespace;
74pub mod platform;
75pub mod prelude;
76pub mod print;
77pub mod rbtree;
78pub mod revocable;
79pub mod security;
80pub mod seq_file;
81pub mod sizes;
82mod static_assert;
83#[doc(hidden)]
84pub mod std_vendor;
85pub mod str;
86pub mod sync;
87pub mod task;
88pub mod time;
89pub mod tracepoint;
90pub mod transmute;
91pub mod types;
92pub mod uaccess;
93pub mod workqueue;
94
95#[doc(hidden)]
96pub use bindings;
97pub use macros;
98pub use uapi;
99
100/// Prefix to appear before log messages printed from within the `kernel` crate.
101const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
102
103/// The top level entrypoint to implementing a kernel module.
104///
105/// For any teardown or cleanup operations, your type may implement [`Drop`].
106pub trait Module: Sized + Sync + Send {
107    /// Called at module initialization time.
108    ///
109    /// Use this method to perform whatever setup or registration your module
110    /// should do.
111    ///
112    /// Equivalent to the `module_init` macro in the C API.
113    fn init(module: &'static ThisModule) -> error::Result<Self>;
114}
115
116/// A module that is pinned and initialised in-place.
117pub trait InPlaceModule: Sync + Send {
118    /// Creates an initialiser for the module.
119    ///
120    /// It is called when the module is loaded.
121    fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error>;
122}
123
124impl<T: Module> InPlaceModule for T {
125    fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error> {
126        let initer = move |slot: *mut Self| {
127            let m = <Self as Module>::init(module)?;
128
129            // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`.
130            unsafe { slot.write(m) };
131            Ok(())
132        };
133
134        // SAFETY: On success, `initer` always fully initialises an instance of `Self`.
135        unsafe { pin_init::pin_init_from_closure(initer) }
136    }
137}
138
139/// Metadata attached to a [`Module`] or [`InPlaceModule`].
140pub trait ModuleMetadata {
141    /// The name of the module as specified in the `module!` macro.
142    const NAME: &'static crate::str::CStr;
143}
144
145/// Equivalent to `THIS_MODULE` in the C API.
146///
147/// C header: [`include/linux/init.h`](srctree/include/linux/init.h)
148pub struct ThisModule(*mut bindings::module);
149
150// SAFETY: `THIS_MODULE` may be used from all threads within a module.
151unsafe impl Sync for ThisModule {}
152
153impl ThisModule {
154    /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer.
155    ///
156    /// # Safety
157    ///
158    /// The pointer must be equal to the right `THIS_MODULE`.
159    pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> ThisModule {
160        ThisModule(ptr)
161    }
162
163    /// Access the raw pointer for this module.
164    ///
165    /// It is up to the user to use it correctly.
166    pub const fn as_ptr(&self) -> *mut bindings::module {
167        self.0
168    }
169}
170
171#[cfg(not(any(testlib, test)))]
172#[panic_handler]
173fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
174    pr_emerg!("{}\n", info);
175    // SAFETY: FFI call.
176    unsafe { bindings::BUG() };
177}
178
179/// Produces a pointer to an object from a pointer to one of its fields.
180///
181/// # Safety
182///
183/// The pointer passed to this macro, and the pointer returned by this macro, must both be in
184/// bounds of the same allocation.
185///
186/// # Examples
187///
188/// ```
189/// # use kernel::container_of;
190/// struct Test {
191///     a: u64,
192///     b: u32,
193/// }
194///
195/// let test = Test { a: 10, b: 20 };
196/// let b_ptr = &test.b;
197/// // SAFETY: The pointer points at the `b` field of a `Test`, so the resulting pointer will be
198/// // in-bounds of the same allocation as `b_ptr`.
199/// let test_alias = unsafe { container_of!(b_ptr, Test, b) };
200/// assert!(core::ptr::eq(&test, test_alias));
201/// ```
202#[macro_export]
203macro_rules! container_of {
204    ($ptr:expr, $type:ty, $($f:tt)*) => {{
205        let ptr = $ptr as *const _ as *const u8;
206        let offset: usize = ::core::mem::offset_of!($type, $($f)*);
207        ptr.sub(offset) as *const $type
208    }}
209}
210
211/// Helper for `.rs.S` files.
212#[doc(hidden)]
213#[macro_export]
214macro_rules! concat_literals {
215    ($( $asm:literal )* ) => {
216        ::core::concat!($($asm),*)
217    };
218}
219
220/// Wrapper around `asm!` configured for use in the kernel.
221///
222/// Uses a semicolon to avoid parsing ambiguities, even though this does not match native `asm!`
223/// syntax.
224// For x86, `asm!` uses intel syntax by default, but we want to use at&t syntax in the kernel.
225#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
226#[macro_export]
227macro_rules! asm {
228    ($($asm:expr),* ; $($rest:tt)*) => {
229        ::core::arch::asm!( $($asm)*, options(att_syntax), $($rest)* )
230    };
231}
232
233/// Wrapper around `asm!` configured for use in the kernel.
234///
235/// Uses a semicolon to avoid parsing ambiguities, even though this does not match native `asm!`
236/// syntax.
237// For non-x86 arches we just pass through to `asm!`.
238#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
239#[macro_export]
240macro_rules! asm {
241    ($($asm:expr),* ; $($rest:tt)*) => {
242        ::core::arch::asm!( $($asm)*, $($rest)* )
243    };
244}