FAILED: patch "[PATCH] rust: use `#[used(compiler)]` to fix build and `modpost` with" failed to apply to 6.12-stable tree
Subsystems (6)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 7498159226772d66f150dd406be462d75964a366
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025072102-theorize-single-3700@gregkh' --subject-prefix 'PATCH 6.12.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 7498159226772d66f150dd406be462d75964a366 Mon Sep 17 00:00:00 2001
From: Miguel Ojeda <[email protected]>
Date: Sat, 12 Jul 2025 18:01:03 +0200
Subject: [PATCH] rust: use #[used(compiler)] to fix build and modpost with
Rust >= 1.89.0
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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.
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
Miguel Ojeda
maintainerPATCH 1/1 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.
--- rust/Makefile | 1 + rust/kernel/lib.rs | 1 + rust/macros/module.rs | 10 +++++----- scripts/Makefile.build | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-)
rust/Makefile +1 -0
@@ -157,6 +157,7 @@ quiet_cmd_rustdoc_test = RUSTDOC T $< cmd_rustdoc_test = \ 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/lib.rs +1 -0
@@ -18,6 +18,7 @@#![feature(inline_const)] #![feature(lint_reasons)] #![feature(unsize)] +#![feature(used_with_arg)] // Ensure conditional compilation based on the kernel configuration works; // otherwise we may silently break things like initcall handling.
rust/macros/module.rs +5 -5
@@ -57,7 +57,7 @@ fn emit_base(&mut self, field: &str, content: &str, builtin: bool) { {cfg}#[doc(hidden)] #[link_section = \".modinfo\"] - #[used] + #[used(compiler)] pub static __{module}_{counter}: [u8; {length}] = *{string}; ",cfg = if builtin {
@@ -230,7 +230,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:Option <{type_}> =None ;
@@ -253,7 +253,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;
@@ -273,7 +273,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;
@@ -283,7 +283,7 @@ mod __module_init {{#[cfg(not( CONFIG_HAVE_ARCH_PREL32_RELOCATIONS ))] #[doc(hidden)] #[link_section = \"{initcall_section}\"] - #[used] + #[used(compiler)] pub static __{name}_initcall: extern \"C\" fn() -> kernel::ffi::c_int = __{name}_init; #[cfg(not(MODULE))]
scripts/Makefile.build +1 -1
@@ -248,7 +248,7 @@ $(obj)/%.lst: $(obj)/%.c FORCE # Compile Rust sources (.rs) # --------------------------------------------------------------------------- -rust_allowed_features := arbitrary_self_types,lint_reasons +rust_allowed_features := arbitrary_self_types,lint_reasons,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 6.12.y] rust: use `#[used(compiler)]` to fix build and `modpost` with Rust >= 1.89.0
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 7498159226772d66f150dd406be462d75964a366
Status in newer kernel trees:
6.15.y | Not found
Note: The patch differs from the upstream commit:
---
1: 749815922677 ! 1: 9212c12e784b rust: use #[used(compiler)] to fix build and modpost with Rust >= 1.89.0
@@ Commit message
+ (cherry picked from commit 7498159226772d66f150dd406be462d75964a366)
+ Signed-off-by: Miguel Ojeda <[email protected]>
## rust/Makefile ##
@@ rust/Makefile: quiet_cmd_rustdoc_test = RUSTDOC T $<
- RUST_MODFILE=test.rs \
+ cmd_rustdoc_test = \
OBJTREE=$(abspath $(objtree)) \
$(RUSTDOC) --test $(rust_common_flags) \
+ -Zcrate-attr='feature(used_with_arg)' \
@@ rust/Makefile: quiet_cmd_rustdoc_test = RUSTDOC T $<
$(rustc_target_flags) $(rustdoc_test_target_flags) \
$(rustdoc_test_quiet) \
- ## rust/kernel/firmware.rs ##
-@@ rust/kernel/firmware.rs: 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 ##
-@@ rust/kernel/kunit.rs: 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 ##
@@
- // Expected to become stable.
- #![feature(arbitrary_self_types)]
- //
-+// To be determined.
+ #![feature(inline_const)]
+ #![feature(lint_reasons)]
+ #![feature(unsize)]
+#![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))] +
+ // Ensure conditional compilation based on the kernel configuration works;
+ // otherwise we may silently break things like initcall handling.
## rust/macros/module.rs ##
@@ rust/macros/module.rs: fn emit_base(&mut self, field: &str, content: &str, builtin: bool) {
{cfg}
#[doc(hidden)]
- #[cfg_attr(not(target_os = \"macos\"), link_section = \".modinfo\")]
+ #[link_section = \".modinfo\"]
- #[used]
+ #[used(compiler)]
pub static __{module}_{counter}: [u8; {length}] = *{string};
@@ rust/macros/module.rs: mod __module_init {{
+ #[used(compiler)]
static __IS_RUST_MODULE: () = ();
- static mut __MOD: ::core::mem::MaybeUninit<{type_}> =
+ static mut __MOD: Option<{type_}> = None;
@@ rust/macros/module.rs: mod __module_init {{
#[cfg(MODULE)]
@@ rust/macros/module.rs: mod __module_init {{
#[link_section = \"{initcall_section}\"]
- #[used]
+ #[used(compiler)]
- pub static __{ident}_initcall: extern \"C\" fn() ->
- ::kernel::ffi::c_int = __{ident}_init;
+ pub static __{name}_initcall: extern \"C\" fn() -> kernel::ffi::c_int = __{name}_init;
+ #[cfg(not(MODULE))]
## scripts/Makefile.build ##
@@ scripts/Makefile.build: $(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
+ # Compile Rust sources (.rs)
+ # ---------------------------------------------------------------------------
+
+-rust_allowed_features := arbitrary_self_types,lint_reasons
++rust_allowed_features := arbitrary_self_types,lint_reasons,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
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | origin/linux-6.12.y | Success | Success |