Rust fixes for the upcoming 1.89 release
Subsystems (7)
Miguel Ojeda
maintainercover Rust fixes for the upcoming 1.89 release
A couple fixes for the upcoming 1.89.0 release, currently in beta.
With this, current nightly (1.90) gets also clean.
Miguel Ojeda (2):
objtool/rust: add one more noreturn Rust function for Rust 1.89.0
rust: use #[used(compiler)] to fix build and modpost with Rust >=
1.89.0
rust/Makefile | 1 + rust/kernel/firmware.rs | 2 +- rust/kernel/kunit.rs | 2 +- rust/kernel/lib.rs | 3 +++ rust/macros/module.rs | 10 +++++----- scripts/Makefile.build | 3 ++- tools/objtool/check.c | 1 + 7 files changed, 14 insertions(+), 8 deletions(-)
base-commit: fe49aae0fcb348b656bbde2eb1d1c75d8a1a5c3c --
2.50.1
Miguel Ojeda
maintainerPATCH 1/2 objtool/rust: add one more `noreturn` Rust function for Rust 1.89.0
Starting with Rust 1.89.0 (expected 2025-08-07), under CONFIG_RUST_DEBUG_ASSERTIONS=y, objtool may report:
rust/kernel.o: warning: objtool: _R..._6kernel4pageNtB5_4Page8read_raw() falls through to next function _R..._6kernel4pageNtB5_4Page9write_raw()
(and many others) due to calls to the noreturn symbol:
core::panicking::panic_nounwind_fmt
Thus add the mangled one to the list so that objtool knows it is actually noreturn.
See commit 56d680dd23c3 ("objtool/rust: list noreturn Rust functions") for more details.
--- tools/objtool/check.c | 1 + 1 file changed, 1 insertion(+)
tools/objtool/check.c +1 -0
@@ -224,6 +224,7 @@ static bool is_rust_noreturn(const struct symbol *func)str_ends_with (func->name,"_4core9panicking14panic_explicit" ) ||str_ends_with (func->name,"_4core9panicking14panic_nounwind" ) ||str_ends_with (func->name,"_4core9panicking18panic_bounds_check" ) || +str_ends_with (func->name,"_4core9panicking18panic_nounwind_fmt" ) ||str_ends_with (func->name,"_4core9panicking19assert_failed_inner" ) ||str_ends_with (func->name,"_4core9panicking30panic_null_pointer_dereference" ) || str_ends_with(func->name, "_4core9panicking36panic_misaligned_pointer_dereference") ||
Signature · 1 line
2.50.1
Re: [PATCH 1/2] objtool/rust: add one more `noreturn` Rust function for Rust 1.89.0
Quoted 13 lines · Miguel Ojeda
Starting with Rust 1.89.0 (expected 2025-08-07), under
CONFIG_RUST_DEBUG_ASSERTIONS=y,objtoolmay report:
rust/kernel.o: warning: objtool: _R..._6kernel4pageNtB5_4Page8read_raw() falls through to next function _R..._6kernel4pageNtB5_4Page9write_raw()(and many others) due to calls to the
noreturnsymbol:
core::panicking::panic_nounwind_fmtThus add the mangled one to the list so that
objtoolknows it is actuallynoreturn.
Quoted 7 lines
See commit
56d680dd23c3("objtool/rust: listnoreturnRust functions") for more details.Cc [email protected] # Needed in 6.12.y and later (Rust is pinned in older LTSs).Cc Josh Poimboeuf <[email protected]>Cc Peter Zijlstra <[email protected]>Signed-off-by Miguel Ojeda <[email protected]>
Quoted 9 lines
--- tools/objtool/check.c | 1 + 1 file changed, 1 insertion(+)tools/objtool/check.c +0
-0
tools/objtool/check.c static bool is_rust_noreturn(const struct symbol *func) · line 230
Quoted 7 lines
tools/objtool/check.c +1
-0@@ -224,6 +224,7 @@ static bool is_rust_noreturn(const struct symbol *func)str_ends_with (func->name,"_4core9panicking14panic_explicit" ) ||str_ends_with (func->name,"_4core9panicking14panic_nounwind" ) ||str_ends_with (func->name,"_4core9panicking18panic_bounds_check" ) || +str_ends_with (func->name,"_4core9panicking18panic_nounwind_fmt" ) ||str_ends_with (func->name,"_4core9panicking19assert_failed_inner" ) ||str_ends_with (func->name,"_4core9panicking30panic_null_pointer_dereference" ) || str_ends_with(func->name, "_4core9panicking36panic_misaligned_pointer_dereference") ||
Just having "_4core9panicking" substring is not sufficient?
Alice Ryhl
reviewerRe: [PATCH 1/2] objtool/rust: add one more `noreturn` Rust function for Rust 1.89.0
Quoted 29 lines · Peter Zijlstra
Quoted 13 lines · Miguel Ojeda
Starting with Rust 1.89.0 (expected 2025-08-07), under
CONFIG_RUST_DEBUG_ASSERTIONS=y,objtoolmay report:
rust/kernel.o: warning: objtool: _R..._6kernel4pageNtB5_4Page8read_raw() falls through to next function _R..._6kernel4pageNtB5_4Page9write_raw()(and many others) due to calls to the
noreturnsymbol:
core::panicking::panic_nounwind_fmtThus add the mangled one to the list so that
objtoolknows it is actuallynoreturn.Quoted 7 lines
See commit
56d680dd23c3("objtool/rust: listnoreturnRust functions") for more details.Cc [email protected] # Needed in 6.12.y and later (Rust is pinned in older LTSs).Cc Josh Poimboeuf <[email protected]>Cc Peter Zijlstra <[email protected]>Signed-off-by Miguel Ojeda <[email protected]>Quoted 4 lines
--- tools/objtool/check.c | 1 + 1 file changed, 1 insertion(+)
Quoted 14 lines
tools/objtool/check.c static bool is_rust_noreturn(const struct symbol *func) · line 230
Quoted 12 lines
tools/objtool/check.c +1
-0@@ -224,6 +224,7 @@ static bool is_rust_noreturn(const struct symbol *func)str_ends_with (func->name,"_4core9panicking14panic_explicit" ) ||str_ends_with (func->name,"_4core9panicking14panic_nounwind" ) ||str_ends_with (func->name,"_4core9panicking18panic_bounds_check" ) || +str_ends_with (func->name,"_4core9panicking18panic_nounwind_fmt" ) ||str_ends_with (func->name,"_4core9panicking19assert_failed_inner" ) ||str_ends_with (func->name,"_4core9panicking30panic_null_pointer_dereference" ) || str_ends_with(func->name, "_4core9panicking36panic_misaligned_pointer_dereference") ||Just having "
_4core9panicking" substring is not sufficient?
That prefix just means it is defined in the panicking.rs file, which also has a few functions that are not noreturn.
Alice
Peter Zijlstra
maintainerRe: [PATCH 1/2] objtool/rust: add one more `noreturn` Rust function for Rust 1.89.0
Quoted 18 lines · Alice Ryhl
Quoted 17 lines
Quoted 8 lines
tools/objtool/check.c | 1 + 1 file changed, 1 insertion(+)tools/objtool/check.c +0
-0tools/objtool/check.c static bool is_rust_noreturn(const struct symbol *func) · line 230
Quoted 7 lines
tools/objtool/check.c +1
-0@@ -224,6 +224,7 @@ static bool is_rust_noreturn(const struct symbol *func)str_ends_with (func->name,"_4core9panicking14panic_explicit" ) ||str_ends_with (func->name,"_4core9panicking14panic_nounwind" ) ||str_ends_with (func->name,"_4core9panicking18panic_bounds_check" ) || +str_ends_with (func->name,"_4core9panicking18panic_nounwind_fmt" ) ||str_ends_with (func->name,"_4core9panicking19assert_failed_inner" ) ||str_ends_with (func->name,"_4core9panicking30panic_null_pointer_dereference" ) || str_ends_with(func->name, "_4core9panicking36panic_misaligned_pointer_dereference") ||Just having "
_4core9panicking" substring is not sufficient?
Quoted 2 lines
That prefix just means it is defined in the
panicking.rsfile, which also has a few functions that are not noreturn.
Oh well, I figured it was too good to be true anyway. Its just that there was a lot of that around and I had to ask :-)
Miguel Ojeda
maintainerPATCH 2/2 rust: use `#[used(compiler)]` to fix build and `modpost` with Rust >= 1.89.0
In reply to Miguel OjedaStarting 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.
--- rust/Makefile | 1 + rust/kernel/firmware.rs | 2 +- rust/kernel/kunit.rs | 2 +- rust/kernel/lib.rs | 3 +++ rust/macros/module.rs | 10 +++++----- scripts/Makefile.build | 3 ++- 6 files changed, 13 insertions(+), 8 deletions(-)
rust/Makefile +1 -0
@@ -194,6 +194,7 @@ quiet_cmd_rustdoc_test = RUSTDOC T $< RUST_MODFILE=test.rs \ OBJTREE=$(abspath $(objtree)) \ $(RUSTDOC) --test $(rust_common_flags) \ + -Zcrate-attr='feature(used_with_arg)' \ @$(objtree)/include/generated/rustc_cfg \ $(rustc_target_flags) $(rustdoc_test_target_flags) \ $(rustdoc_test_quiet) \
rust/kernel/firmware.rs +1 -1
@@ -202,7 +202,7 @@ macro_rules! module_firmware { };#[link_section = ".modinfo" ] -#[used] +#[used(compiler)] static __MODULE_FIRMWARE: [u8; $($builder)*::create(__MODULE_FIRMWARE_PREFIX) .build_length()] = $($builder)*::create(__MODULE_FIRMWARE_PREFIX).build(); };
rust/kernel/kunit.rs +1 -1
@@ -302,7 +302,7 @@ macro_rules! kunit_unsafe_test_suite { is_init: false, }; -#[used] +#[used(compiler)] #[allow(unused_unsafe)] #[cfg_attr(not(target_os = "macos" ), link_section = ".kunit_test_suites" )] static mut KUNIT_TEST_SUITE_ENTRY: *const ::kernel::bindings::kunit_suite =
rust/kernel/lib.rs +3 -0
@@ -34,6 +34,9 @@// Expected to become stable. #![feature(arbitrary_self_types)] // +// To be determined. +#![feature(used_with_arg)] +// // `feature(derive_coerce_pointee)` is expected to become stable. Before Rust // 1.84.0, it did not exist, so enable the predecessor features. #![cfg_attr( CONFIG_RUSTC_HAS_COERCE_POINTEE , feature(derive_coerce_pointee))]
rust/macros/module.rs +5 -5
@@ -57,7 +57,7 @@ fn emit_base(&mut self, field: &str, content: &str, builtin: bool) { {cfg}#[doc(hidden)] #[cfg_attr(not(target_os = \"macos\"), link_section = \".modinfo\")] - #[used] + #[used(compiler)] pub static __{module}_{counter}: [u8; {length}] = *{string}; ", cfg = if builtin {
@@ -249,7 +249,7 @@ mod __module_init {{// key or a new section. For the moment, keep it simple. #[cfg( MODULE )] #[doc(hidden)] -#[used] +#[used(compiler)] static __IS_RUST_MODULE: () = (); static mut __MOD: ::core::mem::MaybeUninit<{type_}> =
@@ -273,7 +273,7 @@ mod __module_init {{#[cfg( MODULE )] #[doc(hidden)] -#[used] +#[used(compiler)] #[link_section = \".init.data\"] static __UNIQUE_ID___addressable_init_module: unsafe extern \"C\" fn() -> i32 = init_module;
@@ -293,7 +293,7 @@ mod __module_init {{#[cfg( MODULE )] #[doc(hidden)] -#[used] +#[used(compiler)] #[link_section = \".exit.data\"] static __UNIQUE_ID___addressable_cleanup_module: extern \"C\" fn() = cleanup_module;
@@ -303,7 +303,7 @@ mod __module_init {{#[cfg(not( CONFIG_HAVE_ARCH_PREL32_RELOCATIONS ))] #[doc(hidden)] #[link_section = \"{initcall_section}\"] - #[used] + #[used(compiler)] pub static __{ident}_initcall: extern \"C\" fn() -> ::kernel::ffi::c_int = __{ident}_init;
scripts/Makefile.build +2 -1
@@ -312,10 +312,11 @@ $(obj)/%.lst: $(obj)/%.c FORCE # - Stable since Rust 1.82.0: `feature(asm_const)`, `feature(raw_ref_op)`. # - Stable since Rust 1.87.0: `feature(asm_goto)`. # - Expected to become stable: `feature(arbitrary_self_types)`. +# - To be determined: `feature(used_with_arg)`. # # Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on # the unstable features in use. -rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,raw_ref_op +rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,raw_ref_op,used_with_arg # `--out-dir` is required to avoid temporaries being created by `rustc` in the # current working directory, which may be not accessible in the out-of-tree
Signature · 1 line
2.50.1
Re: [PATCH 2/2] rust: use `#[used(compiler)]` to fix build and `modpost` with Rust >= 1.89.0
Quoted 34 lines · Miguel Ojeda
Starting with Rust 1.89.0 (expected 2025-08-07), the Rust compiler fails to build the
rusttesttarget due to undefined references such as:kernel...-cgu.0:(.text....+0x116): undefined reference to `rust_helper_kunit_get_current_test'Moreover, tooling like
modpostgets confused:WARNING: modpost: missing
MODULE_DESCRIPTION()indrivers/gpu/drm/nova/nova.o
ERROR: modpost: missingMODULE_LICENSE()indrivers/gpu/nova-core/nova_core.oThe 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 asuniquetoo, with different IDs. In turn, that means we end up with undefined references that did not get discarded inrusttestand that multiple.modinfosections are generated, which confuse tooling likemodpostbecause 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.
Quoted 9 lines
Cc Björn Roy Baron <[email protected]>Cc David Wood <[email protected]>Cc Wesley Wiser <[email protected]>Cc [email protected] # Needed in 6.12.y and later (Rust is pinned in older LTSs).Link https://godbolt.org/z/sxzWTMfzW [4]Signed-off-by Miguel Ojeda <[email protected]>
Miguel Ojeda
AppliedQuoted 4 lines · Miguel Ojeda
A couple fixes for the upcoming 1.89.0 release, currently in beta.
With this, current nightly (1.90) gets also clean.
Applied to rust-fixes -- thanks everyone!
I am applying these now so that v6.16 is fine by the time the compiler releases, giving how their release weeks will likely line up.
(Added Acked-by from Björn to the second patch he gave me after discussing it in private -- thanks!)
Cheers,
Miguel