Commit | Line | Data |
---|---|---|
247b365d WAF |
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 | |
374908a1 | 9 | //! modules written in Rust) depends on [`core`] and this crate. |
247b365d WAF |
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] | |
b9b701fc MO |
15 | // |
16 | // Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on | |
17 | // the unstable features in use. | |
18 | // | |
19 | // Stable since Rust 1.79.0. | |
2aac4cd7 | 20 | #![feature(inline_const)] |
b9b701fc MO |
21 | // |
22 | // Stable since Rust 1.81.0. | |
1f9ed172 | 23 | #![feature(lint_reasons)] |
b9b701fc MO |
24 | // |
25 | // Stable since Rust 1.82.0. | |
e1dfaa33 | 26 | #![feature(raw_ref_op)] |
b9b701fc MO |
27 | // |
28 | // Stable since Rust 1.83.0. | |
9b90864b DK |
29 | #![feature(const_maybe_uninit_as_mut_ptr)] |
30 | #![feature(const_mut_refs)] | |
31 | #![feature(const_ptr_write)] | |
32 | #![feature(const_refs_to_cell)] | |
b9b701fc MO |
33 | // |
34 | // Expected to become stable. | |
35 | #![feature(arbitrary_self_types)] | |
36 | // | |
37 | // `feature(derive_coerce_pointee)` is expected to become stable. Before Rust | |
38 | // 1.84.0, it did not exist, so enable the predecessor features. | |
39 | #![cfg_attr(CONFIG_RUSTC_HAS_COERCE_POINTEE, feature(derive_coerce_pointee))] | |
40 | #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(coerce_unsized))] | |
41 | #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(dispatch_from_dyn))] | |
42 | #![cfg_attr(not(CONFIG_RUSTC_HAS_COERCE_POINTEE), feature(unsize))] | |
247b365d WAF |
43 | |
44 | // Ensure conditional compilation based on the kernel configuration works; | |
45 | // otherwise we may silently break things like initcall handling. | |
46 | #[cfg(not(CONFIG_RUST))] | |
47 | compile_error!("Missing kernel configuration for conditional compilation"); | |
48 | ||
90e53c5e BL |
49 | // Allow proc-macros to refer to `::kernel` inside the `kernel` crate (this crate). |
50 | extern crate self as kernel; | |
51 | ||
d072acda GG |
52 | pub use ffi; |
53 | ||
31d94d8f | 54 | pub mod alloc; |
ce735e73 DK |
55 | #[cfg(CONFIG_AUXILIARY_BUS)] |
56 | pub mod auxiliary; | |
3253aba3 AH |
57 | #[cfg(CONFIG_BLOCK)] |
58 | pub mod block; | |
614724e7 MO |
59 | #[doc(hidden)] |
60 | pub mod build_assert; | |
d01d7020 | 61 | pub mod clk; |
446cafc2 AH |
62 | #[cfg(CONFIG_CONFIGFS_FS)] |
63 | pub mod configfs; | |
3accb57d | 64 | pub mod cpu; |
2207856f VK |
65 | #[cfg(CONFIG_CPU_FREQ)] |
66 | pub mod cpufreq; | |
8961b8cb | 67 | pub mod cpumask; |
a3df991d | 68 | pub mod cred; |
a674fefd | 69 | pub mod device; |
9b90864b | 70 | pub mod device_id; |
76c01ded | 71 | pub mod devres; |
ad2907b4 | 72 | pub mod dma; |
ea7e1828 | 73 | pub mod driver; |
9a695706 AL |
74 | #[cfg(CONFIG_DRM = "y")] |
75 | pub mod drm; | |
247b365d | 76 | pub mod error; |
78418f30 | 77 | pub mod faux; |
de658283 DK |
78 | #[cfg(CONFIG_RUST_FW_LOADER_ABSTRACTIONS)] |
79 | pub mod firmware; | |
85184982 | 80 | pub mod fs; |
90e53c5e | 81 | pub mod init; |
9b880189 | 82 | pub mod io; |
ea76e08f | 83 | pub mod ioctl; |
6e59bcc9 | 84 | pub mod jump_label; |
a66d733d MO |
85 | #[cfg(CONFIG_KUNIT)] |
86 | pub mod kunit; | |
6cd34171 | 87 | pub mod list; |
f893691e | 88 | pub mod miscdevice; |
5bb9ed6c | 89 | pub mod mm; |
f20fd544 FT |
90 | #[cfg(CONFIG_NET)] |
91 | pub mod net; | |
bbe3b4d1 | 92 | pub mod of; |
8f835497 VK |
93 | #[cfg(CONFIG_PM_OPP)] |
94 | pub mod opp; | |
fc6e66f4 | 95 | pub mod page; |
7e16820f DK |
96 | #[cfg(CONFIG_PCI)] |
97 | pub mod pci; | |
e0020ba6 | 98 | pub mod pid_namespace; |
683a63be | 99 | pub mod platform; |
247b365d WAF |
100 | pub mod prelude; |
101 | pub mod print; | |
a0d13aac | 102 | pub mod rbtree; |
0494d9c8 | 103 | pub mod revocable; |
94d356c0 | 104 | pub mod security; |
22018a5a | 105 | pub mod seq_file; |
ece207a8 | 106 | pub mod sizes; |
ef9e3797 | 107 | mod static_assert; |
bee16889 NM |
108 | #[doc(hidden)] |
109 | pub mod std_vendor; | |
247b365d | 110 | pub mod str; |
9dc04365 | 111 | pub mod sync; |
313c4281 | 112 | pub mod task; |
82e17087 | 113 | pub mod time; |
ad37bcd9 | 114 | pub mod tracepoint; |
ce1c54fd | 115 | pub mod transmute; |
ba20915b | 116 | pub mod types; |
1b580e7b | 117 | pub mod uaccess; |
d4d791d4 | 118 | pub mod workqueue; |
210b8157 | 119 | pub mod xarray; |
247b365d WAF |
120 | |
121 | #[doc(hidden)] | |
122 | pub use bindings; | |
123 | pub use macros; | |
4e174665 | 124 | pub use uapi; |
247b365d WAF |
125 | |
126 | /// Prefix to appear before log messages printed from within the `kernel` crate. | |
127 | const __LOG_PREFIX: &[u8] = b"rust_kernel\0"; | |
128 | ||
129 | /// The top level entrypoint to implementing a kernel module. | |
130 | /// | |
131 | /// For any teardown or cleanup operations, your type may implement [`Drop`]. | |
323617f6 | 132 | pub trait Module: Sized + Sync + Send { |
247b365d WAF |
133 | /// Called at module initialization time. |
134 | /// | |
135 | /// Use this method to perform whatever setup or registration your module | |
136 | /// should do. | |
137 | /// | |
138 | /// Equivalent to the `module_init` macro in the C API. | |
139 | fn init(module: &'static ThisModule) -> error::Result<Self>; | |
140 | } | |
141 | ||
7f15c46a WAF |
142 | /// A module that is pinned and initialised in-place. |
143 | pub trait InPlaceModule: Sync + Send { | |
144 | /// Creates an initialiser for the module. | |
145 | /// | |
146 | /// It is called when the module is loaded. | |
dbd5058b | 147 | fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error>; |
7f15c46a WAF |
148 | } |
149 | ||
150 | impl<T: Module> InPlaceModule for T { | |
dbd5058b | 151 | fn init(module: &'static ThisModule) -> impl pin_init::PinInit<Self, error::Error> { |
7f15c46a WAF |
152 | let initer = move |slot: *mut Self| { |
153 | let m = <Self as Module>::init(module)?; | |
154 | ||
155 | // SAFETY: `slot` is valid for write per the contract with `pin_init_from_closure`. | |
156 | unsafe { slot.write(m) }; | |
157 | Ok(()) | |
158 | }; | |
159 | ||
160 | // SAFETY: On success, `initer` always fully initialises an instance of `Self`. | |
dbd5058b | 161 | unsafe { pin_init::pin_init_from_closure(initer) } |
7f15c46a WAF |
162 | } |
163 | } | |
164 | ||
a790265c DK |
165 | /// Metadata attached to a [`Module`] or [`InPlaceModule`]. |
166 | pub trait ModuleMetadata { | |
167 | /// The name of the module as specified in the `module!` macro. | |
168 | const NAME: &'static crate::str::CStr; | |
169 | } | |
170 | ||
247b365d WAF |
171 | /// Equivalent to `THIS_MODULE` in the C API. |
172 | /// | |
8b55dc86 | 173 | /// C header: [`include/linux/init.h`](srctree/include/linux/init.h) |
247b365d WAF |
174 | pub struct ThisModule(*mut bindings::module); |
175 | ||
176 | // SAFETY: `THIS_MODULE` may be used from all threads within a module. | |
177 | unsafe impl Sync for ThisModule {} | |
178 | ||
179 | impl ThisModule { | |
180 | /// Creates a [`ThisModule`] given the `THIS_MODULE` pointer. | |
181 | /// | |
182 | /// # Safety | |
183 | /// | |
184 | /// The pointer must be equal to the right `THIS_MODULE`. | |
185 | pub const unsafe fn from_ptr(ptr: *mut bindings::module) -> ThisModule { | |
186 | ThisModule(ptr) | |
187 | } | |
d0f0241d AR |
188 | |
189 | /// Access the raw pointer for this module. | |
190 | /// | |
191 | /// It is up to the user to use it correctly. | |
192 | pub const fn as_ptr(&self) -> *mut bindings::module { | |
193 | self.0 | |
194 | } | |
247b365d WAF |
195 | } |
196 | ||
197 | #[cfg(not(any(testlib, test)))] | |
198 | #[panic_handler] | |
199 | fn panic(info: &core::panic::PanicInfo<'_>) -> ! { | |
200 | pr_emerg!("{}\n", info); | |
201 | // SAFETY: FFI call. | |
202 | unsafe { bindings::BUG() }; | |
247b365d | 203 | } |
e9441710 WAF |
204 | |
205 | /// Produces a pointer to an object from a pointer to one of its fields. | |
206 | /// | |
207 | /// # Safety | |
208 | /// | |
209 | /// The pointer passed to this macro, and the pointer returned by this macro, must both be in | |
210 | /// bounds of the same allocation. | |
211 | /// | |
212 | /// # Examples | |
213 | /// | |
214 | /// ``` | |
215 | /// # use kernel::container_of; | |
216 | /// struct Test { | |
217 | /// a: u64, | |
218 | /// b: u32, | |
219 | /// } | |
220 | /// | |
221 | /// let test = Test { a: 10, b: 20 }; | |
74d6a606 | 222 | /// let b_ptr: *const _ = &test.b; |
e9441710 WAF |
223 | /// // SAFETY: The pointer points at the `b` field of a `Test`, so the resulting pointer will be |
224 | /// // in-bounds of the same allocation as `b_ptr`. | |
225 | /// let test_alias = unsafe { container_of!(b_ptr, Test, b) }; | |
226 | /// assert!(core::ptr::eq(&test, test_alias)); | |
227 | /// ``` | |
228 | #[macro_export] | |
229 | macro_rules! container_of { | |
b20fbbc0 TD |
230 | ($field_ptr:expr, $Container:ty, $($fields:tt)*) => {{ |
231 | let offset: usize = ::core::mem::offset_of!($Container, $($fields)*); | |
232 | let field_ptr = $field_ptr; | |
233 | let container_ptr = field_ptr.byte_sub(offset).cast::<$Container>(); | |
234 | $crate::assert_same_type(field_ptr, (&raw const (*container_ptr).$($fields)*).cast_mut()); | |
235 | container_ptr | |
e9441710 WAF |
236 | }} |
237 | } | |
169484ab | 238 | |
b20fbbc0 TD |
239 | /// Helper for [`container_of!`]. |
240 | #[doc(hidden)] | |
241 | pub fn assert_same_type<T>(_: T, _: T) {} | |
242 | ||
169484ab AR |
243 | /// Helper for `.rs.S` files. |
244 | #[doc(hidden)] | |
245 | #[macro_export] | |
246 | macro_rules! concat_literals { | |
247 | ($( $asm:literal )* ) => { | |
248 | ::core::concat!($($asm),*) | |
249 | }; | |
250 | } | |
251 | ||
252 | /// Wrapper around `asm!` configured for use in the kernel. | |
253 | /// | |
254 | /// Uses a semicolon to avoid parsing ambiguities, even though this does not match native `asm!` | |
255 | /// syntax. | |
256 | // For x86, `asm!` uses intel syntax by default, but we want to use at&t syntax in the kernel. | |
257 | #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] | |
258 | #[macro_export] | |
259 | macro_rules! asm { | |
260 | ($($asm:expr),* ; $($rest:tt)*) => { | |
261 | ::core::arch::asm!( $($asm)*, options(att_syntax), $($rest)* ) | |
262 | }; | |
263 | } | |
264 | ||
265 | /// Wrapper around `asm!` configured for use in the kernel. | |
266 | /// | |
267 | /// Uses a semicolon to avoid parsing ambiguities, even though this does not match native `asm!` | |
268 | /// syntax. | |
269 | // For non-x86 arches we just pass through to `asm!`. | |
270 | #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] | |
271 | #[macro_export] | |
272 | macro_rules! asm { | |
273 | ($($asm:expr),* ; $($rest:tt)*) => { | |
274 | ::core::arch::asm!( $($asm)*, $($rest)* ) | |
275 | }; | |
276 | } |