2021-07-03 14:56:17 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
|
|
|
|
use crate::helpers::*;
|
2023-03-23 12:35:10 +00:00
|
|
|
use proc_macro::{token_stream, Delimiter, Literal, TokenStream, TokenTree};
|
2021-07-03 14:56:17 +00:00
|
|
|
use std::fmt::Write;
|
|
|
|
|
2023-03-23 12:35:10 +00:00
|
|
|
fn expect_string_array(it: &mut token_stream::IntoIter) -> Vec<String> {
|
|
|
|
let group = expect_group(it);
|
|
|
|
assert_eq!(group.delimiter(), Delimiter::Bracket);
|
|
|
|
let mut values = Vec::new();
|
|
|
|
let mut it = group.stream().into_iter();
|
|
|
|
|
|
|
|
while let Some(val) = try_string(&mut it) {
|
|
|
|
assert!(val.is_ascii(), "Expected ASCII string");
|
|
|
|
values.push(val);
|
|
|
|
match it.next() {
|
|
|
|
Some(TokenTree::Punct(punct)) => assert_eq!(punct.as_char(), ','),
|
|
|
|
None => break,
|
|
|
|
_ => panic!("Expected ',' or end of array"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
values
|
|
|
|
}
|
|
|
|
|
2021-07-03 14:56:17 +00:00
|
|
|
struct ModInfoBuilder<'a> {
|
|
|
|
module: &'a str,
|
|
|
|
counter: usize,
|
|
|
|
buffer: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> ModInfoBuilder<'a> {
|
|
|
|
fn new(module: &'a str) -> Self {
|
|
|
|
ModInfoBuilder {
|
|
|
|
module,
|
|
|
|
counter: 0,
|
|
|
|
buffer: String::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn emit_base(&mut self, field: &str, content: &str, builtin: bool) {
|
|
|
|
let string = if builtin {
|
|
|
|
// Built-in modules prefix their modinfo strings by `module.`.
|
|
|
|
format!(
|
|
|
|
"{module}.{field}={content}\0",
|
|
|
|
module = self.module,
|
|
|
|
field = field,
|
|
|
|
content = content
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
// Loadable modules' modinfo strings go as-is.
|
2025-05-02 14:02:37 +00:00
|
|
|
format!("{field}={content}\0")
|
2021-07-03 14:56:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
write!(
|
|
|
|
&mut self.buffer,
|
|
|
|
"
|
|
|
|
{cfg}
|
|
|
|
#[doc(hidden)]
|
2025-02-10 14:51:07 +00:00
|
|
|
#[cfg_attr(not(target_os = \"macos\"), link_section = \".modinfo\")]
|
rust: use `#[used(compiler)]` to fix build and `modpost` with Rust >= 1.89.0
Starting with Rust 1.89.0 (expected 2025-08-07), the Rust compiler fails
to build the `rusttest` target due to undefined references such as:
kernel...-cgu.0:(.text....+0x116): undefined reference to
`rust_helper_kunit_get_current_test'
Moreover, tooling like `modpost` gets confused:
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/nova/nova.o
ERROR: modpost: missing MODULE_LICENSE() in drivers/gpu/nova-core/nova_core.o
The reason behind both issues is that the Rust compiler will now [1]
treat `#[used]` as `#[used(linker)]` instead of `#[used(compiler)]`
for our targets. This means that the retain section flag (`R`,
`SHF_GNU_RETAIN`) will be used and that they will be marked as `unique`
too, with different IDs. In turn, that means we end up with undefined
references that did not get discarded in `rusttest` and that multiple
`.modinfo` sections are generated, which confuse tooling like `modpost`
because they only expect one.
Thus start using `#[used(compiler)]` to keep the previous behavior
and to be explicit about what we want. Sadly, it is an unstable feature
(`used_with_arg`) [2] -- we will talk to upstream Rust about it. The good
news is that it has been available for a long time (Rust >= 1.60) [3].
The changes should also be fine for previous Rust versions, since they
behave the same way as before [4].
Alternatively, we could use `#[no_mangle]` or `#[export_name = ...]`
since those still behave like `#[used(compiler)]`, but of course it is
not really what we want to express, and it requires other changes to
avoid symbol conflicts.
Cc: David Wood <david@davidtw.co>
Cc: Wesley Wiser <wwiser@gmail.com>
Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs).
Link: https://github.com/rust-lang/rust/pull/140872 [1]
Link: https://github.com/rust-lang/rust/issues/93798 [2]
Link: https://github.com/rust-lang/rust/pull/91504 [3]
Link: https://godbolt.org/z/sxzWTMfzW [4]
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Acked-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Link: https://lore.kernel.org/r/20250712160103.1244945-3-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-12 16:01:03 +00:00
|
|
|
#[used(compiler)]
|
2021-07-03 14:56:17 +00:00
|
|
|
pub static __{module}_{counter}: [u8; {length}] = *{string};
|
|
|
|
",
|
|
|
|
cfg = if builtin {
|
|
|
|
"#[cfg(not(MODULE))]"
|
|
|
|
} else {
|
|
|
|
"#[cfg(MODULE)]"
|
|
|
|
},
|
|
|
|
module = self.module.to_uppercase(),
|
|
|
|
counter = self.counter,
|
|
|
|
length = string.len(),
|
|
|
|
string = Literal::byte_string(string.as_bytes()),
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
self.counter += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn emit_only_builtin(&mut self, field: &str, content: &str) {
|
|
|
|
self.emit_base(field, content, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn emit_only_loadable(&mut self, field: &str, content: &str) {
|
|
|
|
self.emit_base(field, content, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn emit(&mut self, field: &str, content: &str) {
|
|
|
|
self.emit_only_builtin(field, content);
|
|
|
|
self.emit_only_loadable(field, content);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
struct ModuleInfo {
|
|
|
|
type_: String,
|
|
|
|
license: String,
|
|
|
|
name: String,
|
2025-03-09 17:57:11 +00:00
|
|
|
authors: Option<Vec<String>>,
|
2021-07-03 14:56:17 +00:00
|
|
|
description: Option<String>,
|
2023-03-23 12:35:10 +00:00
|
|
|
alias: Option<Vec<String>>,
|
2024-05-01 12:35:48 +00:00
|
|
|
firmware: Option<Vec<String>>,
|
2021-07-03 14:56:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ModuleInfo {
|
|
|
|
fn parse(it: &mut token_stream::IntoIter) -> Self {
|
|
|
|
let mut info = ModuleInfo::default();
|
|
|
|
|
2024-05-01 12:35:48 +00:00
|
|
|
const EXPECTED_KEYS: &[&str] = &[
|
|
|
|
"type",
|
|
|
|
"name",
|
2025-03-09 17:57:11 +00:00
|
|
|
"authors",
|
2024-05-01 12:35:48 +00:00
|
|
|
"description",
|
|
|
|
"license",
|
|
|
|
"alias",
|
|
|
|
"firmware",
|
|
|
|
];
|
2021-07-03 14:56:17 +00:00
|
|
|
const REQUIRED_KEYS: &[&str] = &["type", "name", "license"];
|
|
|
|
let mut seen_keys = Vec::new();
|
|
|
|
|
|
|
|
loop {
|
|
|
|
let key = match it.next() {
|
|
|
|
Some(TokenTree::Ident(ident)) => ident.to_string(),
|
|
|
|
Some(_) => panic!("Expected Ident or end"),
|
|
|
|
None => break,
|
|
|
|
};
|
|
|
|
|
|
|
|
if seen_keys.contains(&key) {
|
2025-05-02 14:02:37 +00:00
|
|
|
panic!("Duplicated key \"{key}\". Keys can only be specified once.");
|
2021-07-03 14:56:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(expect_punct(it), ':');
|
|
|
|
|
|
|
|
match key.as_str() {
|
|
|
|
"type" => info.type_ = expect_ident(it),
|
2022-11-10 16:41:19 +00:00
|
|
|
"name" => info.name = expect_string_ascii(it),
|
2025-03-09 17:57:11 +00:00
|
|
|
"authors" => info.authors = Some(expect_string_array(it)),
|
2022-11-10 16:41:19 +00:00
|
|
|
"description" => info.description = Some(expect_string(it)),
|
|
|
|
"license" => info.license = expect_string_ascii(it),
|
2023-03-23 12:35:10 +00:00
|
|
|
"alias" => info.alias = Some(expect_string_array(it)),
|
2024-05-01 12:35:48 +00:00
|
|
|
"firmware" => info.firmware = Some(expect_string_array(it)),
|
2025-05-02 14:02:37 +00:00
|
|
|
_ => panic!("Unknown key \"{key}\". Valid keys are: {EXPECTED_KEYS:?}."),
|
2021-07-03 14:56:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(expect_punct(it), ',');
|
|
|
|
|
|
|
|
seen_keys.push(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
expect_end(it);
|
|
|
|
|
|
|
|
for key in REQUIRED_KEYS {
|
|
|
|
if !seen_keys.iter().any(|e| e == key) {
|
2025-05-02 14:02:37 +00:00
|
|
|
panic!("Missing required key \"{key}\".");
|
2021-07-03 14:56:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut ordered_keys: Vec<&str> = Vec::new();
|
|
|
|
for key in EXPECTED_KEYS {
|
|
|
|
if seen_keys.iter().any(|e| e == key) {
|
|
|
|
ordered_keys.push(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if seen_keys != ordered_keys {
|
2025-05-02 14:02:37 +00:00
|
|
|
panic!("Keys are not ordered as expected. Order them like: {ordered_keys:?}.");
|
2021-07-03 14:56:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
info
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn module(ts: TokenStream) -> TokenStream {
|
|
|
|
let mut it = ts.into_iter();
|
|
|
|
|
|
|
|
let info = ModuleInfo::parse(&mut it);
|
|
|
|
|
2025-01-22 13:39:52 +00:00
|
|
|
// Rust does not allow hyphens in identifiers, use underscore instead.
|
|
|
|
let ident = info.name.replace('-', "_");
|
|
|
|
let mut modinfo = ModInfoBuilder::new(ident.as_ref());
|
2025-03-09 17:57:11 +00:00
|
|
|
if let Some(authors) = info.authors {
|
|
|
|
for author in authors {
|
|
|
|
modinfo.emit("author", &author);
|
|
|
|
}
|
|
|
|
}
|
2021-07-03 14:56:17 +00:00
|
|
|
if let Some(description) = info.description {
|
|
|
|
modinfo.emit("description", &description);
|
|
|
|
}
|
|
|
|
modinfo.emit("license", &info.license);
|
2023-03-23 12:35:10 +00:00
|
|
|
if let Some(aliases) = info.alias {
|
|
|
|
for alias in aliases {
|
|
|
|
modinfo.emit("alias", &alias);
|
|
|
|
}
|
2021-07-03 14:56:17 +00:00
|
|
|
}
|
2024-05-01 12:35:48 +00:00
|
|
|
if let Some(firmware) = info.firmware {
|
|
|
|
for fw in firmware {
|
|
|
|
modinfo.emit("firmware", &fw);
|
|
|
|
}
|
|
|
|
}
|
2021-07-03 14:56:17 +00:00
|
|
|
|
|
|
|
// Built-in modules also export the `file` modinfo string.
|
|
|
|
let file =
|
|
|
|
std::env::var("RUST_MODFILE").expect("Unable to fetch RUST_MODFILE environmental variable");
|
|
|
|
modinfo.emit_only_builtin("file", &file);
|
|
|
|
|
|
|
|
format!(
|
|
|
|
"
|
|
|
|
/// The module name.
|
|
|
|
///
|
|
|
|
/// Used by the printing macros, e.g. [`info!`].
|
|
|
|
const __LOG_PREFIX: &[u8] = b\"{name}\\0\";
|
|
|
|
|
|
|
|
// SAFETY: `__this_module` is constructed by the kernel at load time and will not be
|
|
|
|
// freed until the module is unloaded.
|
|
|
|
#[cfg(MODULE)]
|
2025-05-19 16:45:53 +00:00
|
|
|
static THIS_MODULE: ::kernel::ThisModule = unsafe {{
|
2024-08-28 18:01:29 +00:00
|
|
|
extern \"C\" {{
|
2025-05-19 16:45:53 +00:00
|
|
|
static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
|
2024-08-28 18:01:29 +00:00
|
|
|
}}
|
|
|
|
|
2025-05-19 16:45:53 +00:00
|
|
|
::kernel::ThisModule::from_ptr(__this_module.get())
|
2021-07-03 14:56:17 +00:00
|
|
|
}};
|
|
|
|
#[cfg(not(MODULE))]
|
2025-05-19 16:45:53 +00:00
|
|
|
static THIS_MODULE: ::kernel::ThisModule = unsafe {{
|
|
|
|
::kernel::ThisModule::from_ptr(::core::ptr::null_mut())
|
2021-07-03 14:56:17 +00:00
|
|
|
}};
|
|
|
|
|
2025-03-06 22:23:27 +00:00
|
|
|
/// The `LocalModule` type is the type of the module created by `module!`,
|
|
|
|
/// `module_pci_driver!`, `module_platform_driver!`, etc.
|
|
|
|
type LocalModule = {type_};
|
|
|
|
|
2025-05-19 16:45:53 +00:00
|
|
|
impl ::kernel::ModuleMetadata for {type_} {{
|
|
|
|
const NAME: &'static ::kernel::str::CStr = ::kernel::c_str!(\"{name}\");
|
2024-12-19 17:04:03 +00:00
|
|
|
}}
|
|
|
|
|
2024-04-01 18:52:50 +00:00
|
|
|
// Double nested modules, since then nobody can access the public items inside.
|
|
|
|
mod __module_init {{
|
|
|
|
mod __module_init {{
|
|
|
|
use super::super::{type_};
|
2025-03-08 11:05:09 +00:00
|
|
|
use pin_init::PinInit;
|
2024-04-01 18:52:50 +00:00
|
|
|
|
|
|
|
/// The \"Rust loadable module\" mark.
|
|
|
|
//
|
|
|
|
// This may be best done another way later on, e.g. as a new modinfo
|
|
|
|
// key or a new section. For the moment, keep it simple.
|
|
|
|
#[cfg(MODULE)]
|
|
|
|
#[doc(hidden)]
|
rust: use `#[used(compiler)]` to fix build and `modpost` with Rust >= 1.89.0
Starting with Rust 1.89.0 (expected 2025-08-07), the Rust compiler fails
to build the `rusttest` target due to undefined references such as:
kernel...-cgu.0:(.text....+0x116): undefined reference to
`rust_helper_kunit_get_current_test'
Moreover, tooling like `modpost` gets confused:
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/nova/nova.o
ERROR: modpost: missing MODULE_LICENSE() in drivers/gpu/nova-core/nova_core.o
The reason behind both issues is that the Rust compiler will now [1]
treat `#[used]` as `#[used(linker)]` instead of `#[used(compiler)]`
for our targets. This means that the retain section flag (`R`,
`SHF_GNU_RETAIN`) will be used and that they will be marked as `unique`
too, with different IDs. In turn, that means we end up with undefined
references that did not get discarded in `rusttest` and that multiple
`.modinfo` sections are generated, which confuse tooling like `modpost`
because they only expect one.
Thus start using `#[used(compiler)]` to keep the previous behavior
and to be explicit about what we want. Sadly, it is an unstable feature
(`used_with_arg`) [2] -- we will talk to upstream Rust about it. The good
news is that it has been available for a long time (Rust >= 1.60) [3].
The changes should also be fine for previous Rust versions, since they
behave the same way as before [4].
Alternatively, we could use `#[no_mangle]` or `#[export_name = ...]`
since those still behave like `#[used(compiler)]`, but of course it is
not really what we want to express, and it requires other changes to
avoid symbol conflicts.
Cc: David Wood <david@davidtw.co>
Cc: Wesley Wiser <wwiser@gmail.com>
Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs).
Link: https://github.com/rust-lang/rust/pull/140872 [1]
Link: https://github.com/rust-lang/rust/issues/93798 [2]
Link: https://github.com/rust-lang/rust/pull/91504 [3]
Link: https://godbolt.org/z/sxzWTMfzW [4]
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Acked-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Link: https://lore.kernel.org/r/20250712160103.1244945-3-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-12 16:01:03 +00:00
|
|
|
#[used(compiler)]
|
2024-04-01 18:52:50 +00:00
|
|
|
static __IS_RUST_MODULE: () = ();
|
|
|
|
|
2025-05-19 16:45:53 +00:00
|
|
|
static mut __MOD: ::core::mem::MaybeUninit<{type_}> =
|
|
|
|
::core::mem::MaybeUninit::uninit();
|
2024-04-01 18:52:50 +00:00
|
|
|
|
|
|
|
// Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
|
|
|
|
/// # Safety
|
|
|
|
///
|
|
|
|
/// This function must not be called after module initialization, because it may be
|
|
|
|
/// freed after that completes.
|
|
|
|
#[cfg(MODULE)]
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[no_mangle]
|
|
|
|
#[link_section = \".init.text\"]
|
2025-05-19 16:45:53 +00:00
|
|
|
pub unsafe extern \"C\" fn init_module() -> ::kernel::ffi::c_int {{
|
2024-04-01 18:52:50 +00:00
|
|
|
// SAFETY: This function is inaccessible to the outside due to the double
|
|
|
|
// module wrapping it. It is called exactly once by the C side via its
|
|
|
|
// unique name.
|
|
|
|
unsafe {{ __init() }}
|
|
|
|
}}
|
2021-07-03 14:56:17 +00:00
|
|
|
|
2024-07-25 18:33:18 +00:00
|
|
|
#[cfg(MODULE)]
|
|
|
|
#[doc(hidden)]
|
rust: use `#[used(compiler)]` to fix build and `modpost` with Rust >= 1.89.0
Starting with Rust 1.89.0 (expected 2025-08-07), the Rust compiler fails
to build the `rusttest` target due to undefined references such as:
kernel...-cgu.0:(.text....+0x116): undefined reference to
`rust_helper_kunit_get_current_test'
Moreover, tooling like `modpost` gets confused:
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/nova/nova.o
ERROR: modpost: missing MODULE_LICENSE() in drivers/gpu/nova-core/nova_core.o
The reason behind both issues is that the Rust compiler will now [1]
treat `#[used]` as `#[used(linker)]` instead of `#[used(compiler)]`
for our targets. This means that the retain section flag (`R`,
`SHF_GNU_RETAIN`) will be used and that they will be marked as `unique`
too, with different IDs. In turn, that means we end up with undefined
references that did not get discarded in `rusttest` and that multiple
`.modinfo` sections are generated, which confuse tooling like `modpost`
because they only expect one.
Thus start using `#[used(compiler)]` to keep the previous behavior
and to be explicit about what we want. Sadly, it is an unstable feature
(`used_with_arg`) [2] -- we will talk to upstream Rust about it. The good
news is that it has been available for a long time (Rust >= 1.60) [3].
The changes should also be fine for previous Rust versions, since they
behave the same way as before [4].
Alternatively, we could use `#[no_mangle]` or `#[export_name = ...]`
since those still behave like `#[used(compiler)]`, but of course it is
not really what we want to express, and it requires other changes to
avoid symbol conflicts.
Cc: David Wood <david@davidtw.co>
Cc: Wesley Wiser <wwiser@gmail.com>
Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs).
Link: https://github.com/rust-lang/rust/pull/140872 [1]
Link: https://github.com/rust-lang/rust/issues/93798 [2]
Link: https://github.com/rust-lang/rust/pull/91504 [3]
Link: https://godbolt.org/z/sxzWTMfzW [4]
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Acked-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Link: https://lore.kernel.org/r/20250712160103.1244945-3-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-12 16:01:03 +00:00
|
|
|
#[used(compiler)]
|
2024-07-25 18:33:18 +00:00
|
|
|
#[link_section = \".init.data\"]
|
|
|
|
static __UNIQUE_ID___addressable_init_module: unsafe extern \"C\" fn() -> i32 = init_module;
|
|
|
|
|
2024-04-01 18:52:50 +00:00
|
|
|
#[cfg(MODULE)]
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[no_mangle]
|
2025-03-08 04:45:06 +00:00
|
|
|
#[link_section = \".exit.text\"]
|
2024-04-01 18:52:50 +00:00
|
|
|
pub extern \"C\" fn cleanup_module() {{
|
|
|
|
// SAFETY:
|
|
|
|
// - This function is inaccessible to the outside due to the double
|
|
|
|
// module wrapping it. It is called exactly once by the C side via its
|
|
|
|
// unique name,
|
|
|
|
// - furthermore it is only called after `init_module` has returned `0`
|
|
|
|
// (which delegates to `__init`).
|
|
|
|
unsafe {{ __exit() }}
|
|
|
|
}}
|
2021-07-03 14:56:17 +00:00
|
|
|
|
2024-07-25 18:33:18 +00:00
|
|
|
#[cfg(MODULE)]
|
|
|
|
#[doc(hidden)]
|
rust: use `#[used(compiler)]` to fix build and `modpost` with Rust >= 1.89.0
Starting with Rust 1.89.0 (expected 2025-08-07), the Rust compiler fails
to build the `rusttest` target due to undefined references such as:
kernel...-cgu.0:(.text....+0x116): undefined reference to
`rust_helper_kunit_get_current_test'
Moreover, tooling like `modpost` gets confused:
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/nova/nova.o
ERROR: modpost: missing MODULE_LICENSE() in drivers/gpu/nova-core/nova_core.o
The reason behind both issues is that the Rust compiler will now [1]
treat `#[used]` as `#[used(linker)]` instead of `#[used(compiler)]`
for our targets. This means that the retain section flag (`R`,
`SHF_GNU_RETAIN`) will be used and that they will be marked as `unique`
too, with different IDs. In turn, that means we end up with undefined
references that did not get discarded in `rusttest` and that multiple
`.modinfo` sections are generated, which confuse tooling like `modpost`
because they only expect one.
Thus start using `#[used(compiler)]` to keep the previous behavior
and to be explicit about what we want. Sadly, it is an unstable feature
(`used_with_arg`) [2] -- we will talk to upstream Rust about it. The good
news is that it has been available for a long time (Rust >= 1.60) [3].
The changes should also be fine for previous Rust versions, since they
behave the same way as before [4].
Alternatively, we could use `#[no_mangle]` or `#[export_name = ...]`
since those still behave like `#[used(compiler)]`, but of course it is
not really what we want to express, and it requires other changes to
avoid symbol conflicts.
Cc: David Wood <david@davidtw.co>
Cc: Wesley Wiser <wwiser@gmail.com>
Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs).
Link: https://github.com/rust-lang/rust/pull/140872 [1]
Link: https://github.com/rust-lang/rust/issues/93798 [2]
Link: https://github.com/rust-lang/rust/pull/91504 [3]
Link: https://godbolt.org/z/sxzWTMfzW [4]
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Acked-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Link: https://lore.kernel.org/r/20250712160103.1244945-3-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-12 16:01:03 +00:00
|
|
|
#[used(compiler)]
|
2024-07-25 18:33:18 +00:00
|
|
|
#[link_section = \".exit.data\"]
|
|
|
|
static __UNIQUE_ID___addressable_cleanup_module: extern \"C\" fn() = cleanup_module;
|
|
|
|
|
2024-04-01 18:52:50 +00:00
|
|
|
// Built-in modules are initialized through an initcall pointer
|
|
|
|
// and the identifiers need to be unique.
|
|
|
|
#[cfg(not(MODULE))]
|
|
|
|
#[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[link_section = \"{initcall_section}\"]
|
rust: use `#[used(compiler)]` to fix build and `modpost` with Rust >= 1.89.0
Starting with Rust 1.89.0 (expected 2025-08-07), the Rust compiler fails
to build the `rusttest` target due to undefined references such as:
kernel...-cgu.0:(.text....+0x116): undefined reference to
`rust_helper_kunit_get_current_test'
Moreover, tooling like `modpost` gets confused:
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/gpu/drm/nova/nova.o
ERROR: modpost: missing MODULE_LICENSE() in drivers/gpu/nova-core/nova_core.o
The reason behind both issues is that the Rust compiler will now [1]
treat `#[used]` as `#[used(linker)]` instead of `#[used(compiler)]`
for our targets. This means that the retain section flag (`R`,
`SHF_GNU_RETAIN`) will be used and that they will be marked as `unique`
too, with different IDs. In turn, that means we end up with undefined
references that did not get discarded in `rusttest` and that multiple
`.modinfo` sections are generated, which confuse tooling like `modpost`
because they only expect one.
Thus start using `#[used(compiler)]` to keep the previous behavior
and to be explicit about what we want. Sadly, it is an unstable feature
(`used_with_arg`) [2] -- we will talk to upstream Rust about it. The good
news is that it has been available for a long time (Rust >= 1.60) [3].
The changes should also be fine for previous Rust versions, since they
behave the same way as before [4].
Alternatively, we could use `#[no_mangle]` or `#[export_name = ...]`
since those still behave like `#[used(compiler)]`, but of course it is
not really what we want to express, and it requires other changes to
avoid symbol conflicts.
Cc: David Wood <david@davidtw.co>
Cc: Wesley Wiser <wwiser@gmail.com>
Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs).
Link: https://github.com/rust-lang/rust/pull/140872 [1]
Link: https://github.com/rust-lang/rust/issues/93798 [2]
Link: https://github.com/rust-lang/rust/pull/91504 [3]
Link: https://godbolt.org/z/sxzWTMfzW [4]
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Acked-by: Björn Roy Baron <bjorn3_gh@protonmail.com>
Link: https://lore.kernel.org/r/20250712160103.1244945-3-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2025-07-12 16:01:03 +00:00
|
|
|
#[used(compiler)]
|
2025-01-22 13:39:52 +00:00
|
|
|
pub static __{ident}_initcall: extern \"C\" fn() ->
|
Rust changes for v6.16
Toolchain and infrastructure:
- KUnit '#[test]'s:
- Support KUnit-mapped 'assert!' macros.
The support that landed last cycle was very basic, and the
'assert!' macros panicked since they were the standard library
ones. Now, they are mapped to the KUnit ones in a similar way to
how is done for doctests, reusing the infrastructure there.
With this, a failing test like:
#[test]
fn my_first_test() {
assert_eq!(42, 43);
}
will report:
# my_first_test: ASSERTION FAILED at rust/kernel/lib.rs:251
Expected 42 == 43 to be true, but is false
# my_first_test.speed: normal
not ok 1 my_first_test
- Support tests with checked 'Result' return types.
The return value of test functions that return a 'Result' will be
checked, thus one can now easily catch errors when e.g. using the
'?' operator in tests.
With this, a failing test like:
#[test]
fn my_test() -> Result {
f()?;
Ok(())
}
will report:
# my_test: ASSERTION FAILED at rust/kernel/lib.rs:321
Expected is_test_result_ok(my_test()) to be true, but is false
# my_test.speed: normal
not ok 1 my_test
- Add 'kunit_tests' to the prelude.
- Clarify the remaining language unstable features in use.
- Compile 'core' with edition 2024 for Rust >= 1.87.
- Workaround 'bindgen' issue with forward references to 'enum' types.
- objtool: relax slice condition to cover more 'noreturn' functions.
- Use absolute paths in macros referencing 'core' and 'kernel' crates.
- Skip '-mno-fdpic' flag for bindgen in GCC 32-bit arm builds.
- Clean some 'doc_markdown' lint hits -- we may enable it later on.
'kernel' crate:
- 'alloc' module:
- 'Box': support for type coercion, e.g. 'Box<T>' to 'Box<dyn U>' if
'T' implements 'U'.
- 'Vec': implement new methods (prerequisites for nova-core and
binder): 'truncate', 'resize', 'clear', 'pop',
'push_within_capacity' (with new error type 'PushError'),
'drain_all', 'retain', 'remove' (with new error type
'RemoveError'), insert_within_capacity' (with new error type
'InsertError').
In addition, simplify 'push' using 'spare_capacity_mut', split
'set_len' into 'inc_len' and 'dec_len', add type invariant
'len <= capacity' and simplify 'truncate' using 'dec_len'.
- 'time' module:
- Morph the Rust hrtimer subsystem into the Rust timekeeping
subsystem, covering delay, sleep, timekeeping, timers. This new
subsystem has all the relevant timekeeping C maintainers listed in
the entry.
- Replace 'Ktime' with 'Delta' and 'Instant' types to represent a
duration of time and a point in time.
- Temporarily add 'Ktime' to 'hrtimer' module to allow 'hrtimer' to
delay converting to 'Instant' and 'Delta'.
- 'xarray' module:
- Add a Rust abstraction for the 'xarray' data structure. This
abstraction allows Rust code to leverage the 'xarray' to store
types that implement 'ForeignOwnable'. This support is a dependency
for memory backing feature of the Rust null block driver, which is
waiting to be merged.
- Set up an entry in 'MAINTAINERS' for the XArray Rust support.
Patches will go to the new Rust XArray tree and then via the Rust
subsystem tree for now.
- Allow 'ForeignOwnable' to carry information about the pointed-to
type. This helps asserting alignment requirements for the pointer
passed to the foreign language.
- 'container_of!': retain pointer mut-ness and add a compile-time check
of the type of the first parameter ('$field_ptr').
- Support optional message in 'static_assert!'.
- Add C FFI types (e.g. 'c_int') to the prelude.
- 'str' module: simplify KUnit tests 'format!' macro, convert
'rusttest' tests into KUnit, take advantage of the '-> Result'
support in KUnit '#[test]'s.
- 'list' module: add examples for 'List', fix path of 'assert_pinned!'
(so far unused macro rule).
- 'workqueue' module: remove 'HasWork::OFFSET'.
- 'page' module: add 'inline' attribute.
'macros' crate:
- 'module' macro: place 'cleanup_module()' in '.exit.text' section.
'pin-init' crate:
- Add 'Wrapper<T>' trait for creating pin-initializers for wrapper
structs with a structurally pinned value such as 'UnsafeCell<T>' or
'MaybeUninit<T>'.
- Add 'MaybeZeroable' derive macro to try to derive 'Zeroable', but
not error if not all fields implement it. This is needed to derive
'Zeroable' for all bindgen-generated structs.
- Add 'unsafe fn cast_[pin_]init()' functions to unsafely change the
initialized type of an initializer. These are utilized by the
'Wrapper<T>' implementations.
- Add support for visibility in 'Zeroable' derive macro.
- Add support for 'union's in 'Zeroable' derive macro.
- Upstream dev news: streamline CI, fix some bugs. Add new workflows
to check if the user-space version and the one in the kernel tree
have diverged. Use the issues tab [1] to track them, which should
help folks report and diagnose issues w.r.t. 'pin-init' better.
[1] https://github.com/rust-for-linux/pin-init/issues
Documentation:
- Testing: add docs on the new KUnit '#[test]' tests.
- Coding guidelines: explain that '///' vs. '//' applies to private
items too. Add section on C FFI types.
- Quick Start guide: update Ubuntu instructions and split them into
"25.04" and "24.04 LTS and older".
And a few other cleanups and improvements.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEPjU5OPd5QIZ9jqqOGXyLc2htIW0FAmhBAvYACgkQGXyLc2ht
IW3qvA/+KRTCYKcI6JyUT9TdhRmaaMsQ0/5j6Kx4CfRQPZTSWsXyBEU75yEIZUQD
SUGQFwmMAYeAKQD1SumFCRy973VzUO45DyKM+7vuVhKN1ZjnAtv63+31C3UFATlA
8Tm3GCqQEGKl4IER7xI3D/vpZA5FOv+GotjNieF3O9FpHDCvV/JQScq9I2oXQPCt
17kRLww/DTfpf4qiLmxmxHn6nCsbecdfEce1kfjk3nNuE6B2tPf+ddYOwunLEvkB
LA4Cr6T1Cy1ovRQgxg9Pdkl/0Rta0tFcsKt1LqPgjR+n95stsHgAzbyMGuUKoeZx
u2R2pwlrJt6Xe4CEZgTIRfYWgF81qUzdcPuflcSMDCpH0nTep74A2lIiWUHWZSh4
LbPh7r90Q8YwGKVJiWqLfHUmQBnmTEm3D2gydSExPKJXSzB4Rbv4w4fPF3dhzMtC
4+KvmHKIojFkAdTLt+5rkKipJGo/rghvQvaQr9JOu+QO4vfhkesB4pUWC4sZd9A9
GJBP97ynWAsXGGaeaaSli0b851X+VE/WIDOmPMselbA3rVADChE6HsJnY/wVVeWK
jupvAhUExSczDPCluGv8T9EVXvv6+fg3bB5pD6R01NNJe6iE/LIDQ5Gj5rg4qahM
EFzMgPj6hMt5McvWI8q1/ym0bzdeC2/cmaV6E14hvphAZoORUKI=
=JRqL
-----END PGP SIGNATURE-----
Merge tag 'rust-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull Rust updates from Miguel Ojeda:
"Toolchain and infrastructure:
- KUnit '#[test]'s:
- Support KUnit-mapped 'assert!' macros.
The support that landed last cycle was very basic, and the
'assert!' macros panicked since they were the standard library
ones. Now, they are mapped to the KUnit ones in a similar way to
how is done for doctests, reusing the infrastructure there.
With this, a failing test like:
#[test]
fn my_first_test() {
assert_eq!(42, 43);
}
will report:
# my_first_test: ASSERTION FAILED at rust/kernel/lib.rs:251
Expected 42 == 43 to be true, but is false
# my_first_test.speed: normal
not ok 1 my_first_test
- Support tests with checked 'Result' return types.
The return value of test functions that return a 'Result' will
be checked, thus one can now easily catch errors when e.g. using
the '?' operator in tests.
With this, a failing test like:
#[test]
fn my_test() -> Result {
f()?;
Ok(())
}
will report:
# my_test: ASSERTION FAILED at rust/kernel/lib.rs:321
Expected is_test_result_ok(my_test()) to be true, but is false
# my_test.speed: normal
not ok 1 my_test
- Add 'kunit_tests' to the prelude.
- Clarify the remaining language unstable features in use.
- Compile 'core' with edition 2024 for Rust >= 1.87.
- Workaround 'bindgen' issue with forward references to 'enum' types.
- objtool: relax slice condition to cover more 'noreturn' functions.
- Use absolute paths in macros referencing 'core' and 'kernel'
crates.
- Skip '-mno-fdpic' flag for bindgen in GCC 32-bit arm builds.
- Clean some 'doc_markdown' lint hits -- we may enable it later on.
'kernel' crate:
- 'alloc' module:
- 'Box': support for type coercion, e.g. 'Box<T>' to 'Box<dyn U>'
if 'T' implements 'U'.
- 'Vec': implement new methods (prerequisites for nova-core and
binder): 'truncate', 'resize', 'clear', 'pop',
'push_within_capacity' (with new error type 'PushError'),
'drain_all', 'retain', 'remove' (with new error type
'RemoveError'), insert_within_capacity' (with new error type
'InsertError').
In addition, simplify 'push' using 'spare_capacity_mut', split
'set_len' into 'inc_len' and 'dec_len', add type invariant 'len
<= capacity' and simplify 'truncate' using 'dec_len'.
- 'time' module:
- Morph the Rust hrtimer subsystem into the Rust timekeeping
subsystem, covering delay, sleep, timekeeping, timers. This new
subsystem has all the relevant timekeeping C maintainers listed
in the entry.
- Replace 'Ktime' with 'Delta' and 'Instant' types to represent a
duration of time and a point in time.
- Temporarily add 'Ktime' to 'hrtimer' module to allow 'hrtimer'
to delay converting to 'Instant' and 'Delta'.
- 'xarray' module:
- Add a Rust abstraction for the 'xarray' data structure. This
abstraction allows Rust code to leverage the 'xarray' to store
types that implement 'ForeignOwnable'. This support is a
dependency for memory backing feature of the Rust null block
driver, which is waiting to be merged.
- Set up an entry in 'MAINTAINERS' for the XArray Rust support.
Patches will go to the new Rust XArray tree and then via the
Rust subsystem tree for now.
- Allow 'ForeignOwnable' to carry information about the pointed-to
type. This helps asserting alignment requirements for the
pointer passed to the foreign language.
- 'container_of!': retain pointer mut-ness and add a compile-time
check of the type of the first parameter ('$field_ptr').
- Support optional message in 'static_assert!'.
- Add C FFI types (e.g. 'c_int') to the prelude.
- 'str' module: simplify KUnit tests 'format!' macro, convert
'rusttest' tests into KUnit, take advantage of the '-> Result'
support in KUnit '#[test]'s.
- 'list' module: add examples for 'List', fix path of
'assert_pinned!' (so far unused macro rule).
- 'workqueue' module: remove 'HasWork::OFFSET'.
- 'page' module: add 'inline' attribute.
'macros' crate:
- 'module' macro: place 'cleanup_module()' in '.exit.text' section.
'pin-init' crate:
- Add 'Wrapper<T>' trait for creating pin-initializers for wrapper
structs with a structurally pinned value such as 'UnsafeCell<T>' or
'MaybeUninit<T>'.
- Add 'MaybeZeroable' derive macro to try to derive 'Zeroable', but
not error if not all fields implement it. This is needed to derive
'Zeroable' for all bindgen-generated structs.
- Add 'unsafe fn cast_[pin_]init()' functions to unsafely change the
initialized type of an initializer. These are utilized by the
'Wrapper<T>' implementations.
- Add support for visibility in 'Zeroable' derive macro.
- Add support for 'union's in 'Zeroable' derive macro.
- Upstream dev news: streamline CI, fix some bugs. Add new workflows
to check if the user-space version and the one in the kernel tree
have diverged. Use the issues tab [1] to track them, which should
help folks report and diagnose issues w.r.t. 'pin-init' better.
[1] https://github.com/rust-for-linux/pin-init/issues
Documentation:
- Testing: add docs on the new KUnit '#[test]' tests.
- Coding guidelines: explain that '///' vs. '//' applies to private
items too. Add section on C FFI types.
- Quick Start guide: update Ubuntu instructions and split them into
"25.04" and "24.04 LTS and older".
And a few other cleanups and improvements"
* tag 'rust-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (78 commits)
rust: list: Fix typo `much` in arc.rs
rust: check type of `$ptr` in `container_of!`
rust: workqueue: remove HasWork::OFFSET
rust: retain pointer mut-ness in `container_of!`
Documentation: rust: testing: add docs on the new KUnit `#[test]` tests
Documentation: rust: rename `#[test]`s to "`rusttest` host tests"
rust: str: take advantage of the `-> Result` support in KUnit `#[test]`'s
rust: str: simplify KUnit tests `format!` macro
rust: str: convert `rusttest` tests into KUnit
rust: add `kunit_tests` to the prelude
rust: kunit: support checked `-> Result`s in KUnit `#[test]`s
rust: kunit: support KUnit-mapped `assert!` macros in `#[test]`s
rust: make section names plural
rust: list: fix path of `assert_pinned!`
rust: compile libcore with edition 2024 for 1.87+
rust: dma: add missing Markdown code span
rust: task: add missing Markdown code spans and intra-doc links
rust: pci: fix docs related to missing Markdown code spans
rust: alloc: add missing Markdown code span
rust: alloc: add missing Markdown code spans
...
2025-06-05 04:18:37 +00:00
|
|
|
::kernel::ffi::c_int = __{ident}_init;
|
2024-04-01 18:52:50 +00:00
|
|
|
|
|
|
|
#[cfg(not(MODULE))]
|
|
|
|
#[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
|
2025-05-19 16:45:53 +00:00
|
|
|
::core::arch::global_asm!(
|
2024-04-01 18:52:50 +00:00
|
|
|
r#\".section \"{initcall_section}\", \"a\"
|
2025-01-22 13:39:52 +00:00
|
|
|
__{ident}_initcall:
|
|
|
|
.long __{ident}_init - .
|
2024-04-01 18:52:50 +00:00
|
|
|
.previous
|
|
|
|
\"#
|
|
|
|
);
|
|
|
|
|
|
|
|
#[cfg(not(MODULE))]
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[no_mangle]
|
Rust changes for v6.16
Toolchain and infrastructure:
- KUnit '#[test]'s:
- Support KUnit-mapped 'assert!' macros.
The support that landed last cycle was very basic, and the
'assert!' macros panicked since they were the standard library
ones. Now, they are mapped to the KUnit ones in a similar way to
how is done for doctests, reusing the infrastructure there.
With this, a failing test like:
#[test]
fn my_first_test() {
assert_eq!(42, 43);
}
will report:
# my_first_test: ASSERTION FAILED at rust/kernel/lib.rs:251
Expected 42 == 43 to be true, but is false
# my_first_test.speed: normal
not ok 1 my_first_test
- Support tests with checked 'Result' return types.
The return value of test functions that return a 'Result' will be
checked, thus one can now easily catch errors when e.g. using the
'?' operator in tests.
With this, a failing test like:
#[test]
fn my_test() -> Result {
f()?;
Ok(())
}
will report:
# my_test: ASSERTION FAILED at rust/kernel/lib.rs:321
Expected is_test_result_ok(my_test()) to be true, but is false
# my_test.speed: normal
not ok 1 my_test
- Add 'kunit_tests' to the prelude.
- Clarify the remaining language unstable features in use.
- Compile 'core' with edition 2024 for Rust >= 1.87.
- Workaround 'bindgen' issue with forward references to 'enum' types.
- objtool: relax slice condition to cover more 'noreturn' functions.
- Use absolute paths in macros referencing 'core' and 'kernel' crates.
- Skip '-mno-fdpic' flag for bindgen in GCC 32-bit arm builds.
- Clean some 'doc_markdown' lint hits -- we may enable it later on.
'kernel' crate:
- 'alloc' module:
- 'Box': support for type coercion, e.g. 'Box<T>' to 'Box<dyn U>' if
'T' implements 'U'.
- 'Vec': implement new methods (prerequisites for nova-core and
binder): 'truncate', 'resize', 'clear', 'pop',
'push_within_capacity' (with new error type 'PushError'),
'drain_all', 'retain', 'remove' (with new error type
'RemoveError'), insert_within_capacity' (with new error type
'InsertError').
In addition, simplify 'push' using 'spare_capacity_mut', split
'set_len' into 'inc_len' and 'dec_len', add type invariant
'len <= capacity' and simplify 'truncate' using 'dec_len'.
- 'time' module:
- Morph the Rust hrtimer subsystem into the Rust timekeeping
subsystem, covering delay, sleep, timekeeping, timers. This new
subsystem has all the relevant timekeeping C maintainers listed in
the entry.
- Replace 'Ktime' with 'Delta' and 'Instant' types to represent a
duration of time and a point in time.
- Temporarily add 'Ktime' to 'hrtimer' module to allow 'hrtimer' to
delay converting to 'Instant' and 'Delta'.
- 'xarray' module:
- Add a Rust abstraction for the 'xarray' data structure. This
abstraction allows Rust code to leverage the 'xarray' to store
types that implement 'ForeignOwnable'. This support is a dependency
for memory backing feature of the Rust null block driver, which is
waiting to be merged.
- Set up an entry in 'MAINTAINERS' for the XArray Rust support.
Patches will go to the new Rust XArray tree and then via the Rust
subsystem tree for now.
- Allow 'ForeignOwnable' to carry information about the pointed-to
type. This helps asserting alignment requirements for the pointer
passed to the foreign language.
- 'container_of!': retain pointer mut-ness and add a compile-time check
of the type of the first parameter ('$field_ptr').
- Support optional message in 'static_assert!'.
- Add C FFI types (e.g. 'c_int') to the prelude.
- 'str' module: simplify KUnit tests 'format!' macro, convert
'rusttest' tests into KUnit, take advantage of the '-> Result'
support in KUnit '#[test]'s.
- 'list' module: add examples for 'List', fix path of 'assert_pinned!'
(so far unused macro rule).
- 'workqueue' module: remove 'HasWork::OFFSET'.
- 'page' module: add 'inline' attribute.
'macros' crate:
- 'module' macro: place 'cleanup_module()' in '.exit.text' section.
'pin-init' crate:
- Add 'Wrapper<T>' trait for creating pin-initializers for wrapper
structs with a structurally pinned value such as 'UnsafeCell<T>' or
'MaybeUninit<T>'.
- Add 'MaybeZeroable' derive macro to try to derive 'Zeroable', but
not error if not all fields implement it. This is needed to derive
'Zeroable' for all bindgen-generated structs.
- Add 'unsafe fn cast_[pin_]init()' functions to unsafely change the
initialized type of an initializer. These are utilized by the
'Wrapper<T>' implementations.
- Add support for visibility in 'Zeroable' derive macro.
- Add support for 'union's in 'Zeroable' derive macro.
- Upstream dev news: streamline CI, fix some bugs. Add new workflows
to check if the user-space version and the one in the kernel tree
have diverged. Use the issues tab [1] to track them, which should
help folks report and diagnose issues w.r.t. 'pin-init' better.
[1] https://github.com/rust-for-linux/pin-init/issues
Documentation:
- Testing: add docs on the new KUnit '#[test]' tests.
- Coding guidelines: explain that '///' vs. '//' applies to private
items too. Add section on C FFI types.
- Quick Start guide: update Ubuntu instructions and split them into
"25.04" and "24.04 LTS and older".
And a few other cleanups and improvements.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEPjU5OPd5QIZ9jqqOGXyLc2htIW0FAmhBAvYACgkQGXyLc2ht
IW3qvA/+KRTCYKcI6JyUT9TdhRmaaMsQ0/5j6Kx4CfRQPZTSWsXyBEU75yEIZUQD
SUGQFwmMAYeAKQD1SumFCRy973VzUO45DyKM+7vuVhKN1ZjnAtv63+31C3UFATlA
8Tm3GCqQEGKl4IER7xI3D/vpZA5FOv+GotjNieF3O9FpHDCvV/JQScq9I2oXQPCt
17kRLww/DTfpf4qiLmxmxHn6nCsbecdfEce1kfjk3nNuE6B2tPf+ddYOwunLEvkB
LA4Cr6T1Cy1ovRQgxg9Pdkl/0Rta0tFcsKt1LqPgjR+n95stsHgAzbyMGuUKoeZx
u2R2pwlrJt6Xe4CEZgTIRfYWgF81qUzdcPuflcSMDCpH0nTep74A2lIiWUHWZSh4
LbPh7r90Q8YwGKVJiWqLfHUmQBnmTEm3D2gydSExPKJXSzB4Rbv4w4fPF3dhzMtC
4+KvmHKIojFkAdTLt+5rkKipJGo/rghvQvaQr9JOu+QO4vfhkesB4pUWC4sZd9A9
GJBP97ynWAsXGGaeaaSli0b851X+VE/WIDOmPMselbA3rVADChE6HsJnY/wVVeWK
jupvAhUExSczDPCluGv8T9EVXvv6+fg3bB5pD6R01NNJe6iE/LIDQ5Gj5rg4qahM
EFzMgPj6hMt5McvWI8q1/ym0bzdeC2/cmaV6E14hvphAZoORUKI=
=JRqL
-----END PGP SIGNATURE-----
Merge tag 'rust-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull Rust updates from Miguel Ojeda:
"Toolchain and infrastructure:
- KUnit '#[test]'s:
- Support KUnit-mapped 'assert!' macros.
The support that landed last cycle was very basic, and the
'assert!' macros panicked since they were the standard library
ones. Now, they are mapped to the KUnit ones in a similar way to
how is done for doctests, reusing the infrastructure there.
With this, a failing test like:
#[test]
fn my_first_test() {
assert_eq!(42, 43);
}
will report:
# my_first_test: ASSERTION FAILED at rust/kernel/lib.rs:251
Expected 42 == 43 to be true, but is false
# my_first_test.speed: normal
not ok 1 my_first_test
- Support tests with checked 'Result' return types.
The return value of test functions that return a 'Result' will
be checked, thus one can now easily catch errors when e.g. using
the '?' operator in tests.
With this, a failing test like:
#[test]
fn my_test() -> Result {
f()?;
Ok(())
}
will report:
# my_test: ASSERTION FAILED at rust/kernel/lib.rs:321
Expected is_test_result_ok(my_test()) to be true, but is false
# my_test.speed: normal
not ok 1 my_test
- Add 'kunit_tests' to the prelude.
- Clarify the remaining language unstable features in use.
- Compile 'core' with edition 2024 for Rust >= 1.87.
- Workaround 'bindgen' issue with forward references to 'enum' types.
- objtool: relax slice condition to cover more 'noreturn' functions.
- Use absolute paths in macros referencing 'core' and 'kernel'
crates.
- Skip '-mno-fdpic' flag for bindgen in GCC 32-bit arm builds.
- Clean some 'doc_markdown' lint hits -- we may enable it later on.
'kernel' crate:
- 'alloc' module:
- 'Box': support for type coercion, e.g. 'Box<T>' to 'Box<dyn U>'
if 'T' implements 'U'.
- 'Vec': implement new methods (prerequisites for nova-core and
binder): 'truncate', 'resize', 'clear', 'pop',
'push_within_capacity' (with new error type 'PushError'),
'drain_all', 'retain', 'remove' (with new error type
'RemoveError'), insert_within_capacity' (with new error type
'InsertError').
In addition, simplify 'push' using 'spare_capacity_mut', split
'set_len' into 'inc_len' and 'dec_len', add type invariant 'len
<= capacity' and simplify 'truncate' using 'dec_len'.
- 'time' module:
- Morph the Rust hrtimer subsystem into the Rust timekeeping
subsystem, covering delay, sleep, timekeeping, timers. This new
subsystem has all the relevant timekeeping C maintainers listed
in the entry.
- Replace 'Ktime' with 'Delta' and 'Instant' types to represent a
duration of time and a point in time.
- Temporarily add 'Ktime' to 'hrtimer' module to allow 'hrtimer'
to delay converting to 'Instant' and 'Delta'.
- 'xarray' module:
- Add a Rust abstraction for the 'xarray' data structure. This
abstraction allows Rust code to leverage the 'xarray' to store
types that implement 'ForeignOwnable'. This support is a
dependency for memory backing feature of the Rust null block
driver, which is waiting to be merged.
- Set up an entry in 'MAINTAINERS' for the XArray Rust support.
Patches will go to the new Rust XArray tree and then via the
Rust subsystem tree for now.
- Allow 'ForeignOwnable' to carry information about the pointed-to
type. This helps asserting alignment requirements for the
pointer passed to the foreign language.
- 'container_of!': retain pointer mut-ness and add a compile-time
check of the type of the first parameter ('$field_ptr').
- Support optional message in 'static_assert!'.
- Add C FFI types (e.g. 'c_int') to the prelude.
- 'str' module: simplify KUnit tests 'format!' macro, convert
'rusttest' tests into KUnit, take advantage of the '-> Result'
support in KUnit '#[test]'s.
- 'list' module: add examples for 'List', fix path of
'assert_pinned!' (so far unused macro rule).
- 'workqueue' module: remove 'HasWork::OFFSET'.
- 'page' module: add 'inline' attribute.
'macros' crate:
- 'module' macro: place 'cleanup_module()' in '.exit.text' section.
'pin-init' crate:
- Add 'Wrapper<T>' trait for creating pin-initializers for wrapper
structs with a structurally pinned value such as 'UnsafeCell<T>' or
'MaybeUninit<T>'.
- Add 'MaybeZeroable' derive macro to try to derive 'Zeroable', but
not error if not all fields implement it. This is needed to derive
'Zeroable' for all bindgen-generated structs.
- Add 'unsafe fn cast_[pin_]init()' functions to unsafely change the
initialized type of an initializer. These are utilized by the
'Wrapper<T>' implementations.
- Add support for visibility in 'Zeroable' derive macro.
- Add support for 'union's in 'Zeroable' derive macro.
- Upstream dev news: streamline CI, fix some bugs. Add new workflows
to check if the user-space version and the one in the kernel tree
have diverged. Use the issues tab [1] to track them, which should
help folks report and diagnose issues w.r.t. 'pin-init' better.
[1] https://github.com/rust-for-linux/pin-init/issues
Documentation:
- Testing: add docs on the new KUnit '#[test]' tests.
- Coding guidelines: explain that '///' vs. '//' applies to private
items too. Add section on C FFI types.
- Quick Start guide: update Ubuntu instructions and split them into
"25.04" and "24.04 LTS and older".
And a few other cleanups and improvements"
* tag 'rust-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (78 commits)
rust: list: Fix typo `much` in arc.rs
rust: check type of `$ptr` in `container_of!`
rust: workqueue: remove HasWork::OFFSET
rust: retain pointer mut-ness in `container_of!`
Documentation: rust: testing: add docs on the new KUnit `#[test]` tests
Documentation: rust: rename `#[test]`s to "`rusttest` host tests"
rust: str: take advantage of the `-> Result` support in KUnit `#[test]`'s
rust: str: simplify KUnit tests `format!` macro
rust: str: convert `rusttest` tests into KUnit
rust: add `kunit_tests` to the prelude
rust: kunit: support checked `-> Result`s in KUnit `#[test]`s
rust: kunit: support KUnit-mapped `assert!` macros in `#[test]`s
rust: make section names plural
rust: list: fix path of `assert_pinned!`
rust: compile libcore with edition 2024 for 1.87+
rust: dma: add missing Markdown code span
rust: task: add missing Markdown code spans and intra-doc links
rust: pci: fix docs related to missing Markdown code spans
rust: alloc: add missing Markdown code span
rust: alloc: add missing Markdown code spans
...
2025-06-05 04:18:37 +00:00
|
|
|
pub extern \"C\" fn __{ident}_init() -> ::kernel::ffi::c_int {{
|
2024-04-01 18:52:50 +00:00
|
|
|
// SAFETY: This function is inaccessible to the outside due to the double
|
|
|
|
// module wrapping it. It is called exactly once by the C side via its
|
|
|
|
// placement above in the initcall section.
|
|
|
|
unsafe {{ __init() }}
|
|
|
|
}}
|
2021-07-03 14:56:17 +00:00
|
|
|
|
2024-04-01 18:52:50 +00:00
|
|
|
#[cfg(not(MODULE))]
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[no_mangle]
|
2025-01-22 13:39:52 +00:00
|
|
|
pub extern \"C\" fn __{ident}_exit() {{
|
2024-04-01 18:52:50 +00:00
|
|
|
// SAFETY:
|
|
|
|
// - This function is inaccessible to the outside due to the double
|
|
|
|
// module wrapping it. It is called exactly once by the C side via its
|
|
|
|
// unique name,
|
2025-01-22 13:39:52 +00:00
|
|
|
// - furthermore it is only called after `__{ident}_init` has
|
|
|
|
// returned `0` (which delegates to `__init`).
|
2024-04-01 18:52:50 +00:00
|
|
|
unsafe {{ __exit() }}
|
|
|
|
}}
|
2021-07-03 14:56:17 +00:00
|
|
|
|
2024-04-01 18:52:50 +00:00
|
|
|
/// # Safety
|
|
|
|
///
|
|
|
|
/// This function must only be called once.
|
2025-05-19 16:45:53 +00:00
|
|
|
unsafe fn __init() -> ::kernel::ffi::c_int {{
|
2024-10-22 21:31:39 +00:00
|
|
|
let initer =
|
2025-05-19 16:45:53 +00:00
|
|
|
<{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE);
|
2024-10-22 21:31:39 +00:00
|
|
|
// SAFETY: No data race, since `__MOD` can only be accessed by this module
|
|
|
|
// and there only `__init` and `__exit` access it. These functions are only
|
|
|
|
// called once and `__exit` cannot be called before or during `__init`.
|
|
|
|
match unsafe {{ initer.__pinned_init(__MOD.as_mut_ptr()) }} {{
|
|
|
|
Ok(m) => 0,
|
|
|
|
Err(e) => e.to_errno(),
|
2024-04-01 18:52:50 +00:00
|
|
|
}}
|
|
|
|
}}
|
2021-07-03 14:56:17 +00:00
|
|
|
|
2024-04-01 18:52:50 +00:00
|
|
|
/// # Safety
|
|
|
|
///
|
|
|
|
/// This function must
|
|
|
|
/// - only be called once,
|
|
|
|
/// - be called after `__init` has been called and returned `0`.
|
|
|
|
unsafe fn __exit() {{
|
|
|
|
// SAFETY: No data race, since `__MOD` can only be accessed by this module
|
|
|
|
// and there only `__init` and `__exit` access it. These functions are only
|
|
|
|
// called once and `__init` was already called.
|
2021-07-03 14:56:17 +00:00
|
|
|
unsafe {{
|
2024-04-01 18:52:50 +00:00
|
|
|
// Invokes `drop()` on `__MOD`, which should be used for cleanup.
|
2024-10-22 21:31:39 +00:00
|
|
|
__MOD.assume_init_drop();
|
2021-07-03 14:56:17 +00:00
|
|
|
}}
|
|
|
|
}}
|
|
|
|
|
2024-04-01 18:52:50 +00:00
|
|
|
{modinfo}
|
2021-07-03 14:56:17 +00:00
|
|
|
}}
|
|
|
|
}}
|
|
|
|
",
|
|
|
|
type_ = info.type_,
|
|
|
|
name = info.name,
|
2025-01-22 13:39:52 +00:00
|
|
|
ident = ident,
|
2021-07-03 14:56:17 +00:00
|
|
|
modinfo = modinfo.buffer,
|
|
|
|
initcall_section = ".initcall6.init"
|
|
|
|
)
|
|
|
|
.parse()
|
|
|
|
.expect("Error parsing formatted string into token stream.")
|
|
|
|
}
|