From 3a2486cc1da5cf637fe5da4540929d67c4540022 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Tue, 3 Feb 2026 11:34:10 +0000 Subject: kbuild: rust: provide an option to inline C helpers into Rust A new experimental Kconfig option, `RUST_INLINE_HELPERS` is added to allow C helpers (which were created to allow Rust to call into inline/macro C functions without having to re-implement the logic in Rust) to be inlined into Rust crates without performing global LTO. If the option is enabled, the following is performed: * For helpers, instead of compiling them to an object file to be linked into vmlinux, they're compiled to LLVM IR bitcode. Two versions are generated: one for built-in code (`helpers.bc`) and one for modules (`helpers_module.bc`, with -DMODULE defined). This ensures that C macros/inlines that behave differently for modules (e.g. static calls) function correctly when inlined. * When a Rust crate or object is compiled, instead of generating an object file, LLVM bitcode is generated. * llvm-link is invoked with --internalize to combine the helper bitcode with the crate bitcode. This step is similar to LTO, but this is much faster since it only needs to inline the helpers. * clang is invoked to turn the combined bitcode into a final object file. * Since clang may produce LLVM bitcode when LTO is enabled, and objtool requires ELF input, $(cmd_ld_single) is invoked to ensure the object is converted to ELF before objtool runs. The --internalize flag tells llvm-link to treat all symbols in helpers.bc using `internal` linkage [1]. This matches the behavior of `clang` on `static inline` functions, and avoids exporting the symbol from the object file. To ensure that RUST_INLINE_HELPERS is not incompatible with BTF, we pass the -g0 flag when building helpers. See commit 5daa0c35a1f0 ("rust: Disallow BTF generation with Rust + LTO") for details. We have an intended triple mismatch of `aarch64-unknown-none` vs `aarch64-unknown-linux-gnu`, so we pass --suppress-warnings to llvm-link to suppress it. I considered adding some sort of check that KBUILD_MODNAME is not present in helpers_module.bc, but this is actually not so easy to carry out because .bc files store strings in a weird binary format, so you cannot just grep it for a string to check whether it ended up using KBUILD_MODNAME anywhere. [ Andreas writes: For the rnull driver, enabling helper inlining with this patch gives an average speedup of 2% over the set of 120 workloads that we publish on [2]. Link: https://rust-for-linux.com/null-block-driver [2] This series also uncovered a pre-existing UB instance thanks to an `objtool` warning which I noticed while testing the series (details in the mailing list). - Miguel ] Link: https://github.com/llvm/llvm-project/pull/170397 [1] Co-developed-by: Boqun Feng Signed-off-by: Boqun Feng Co-developed-by: Matthew Maurer Signed-off-by: Matthew Maurer Signed-off-by: Gary Guo Co-developed-by: Alice Ryhl Signed-off-by: Alice Ryhl Reviewed-by: Nathan Chancellor Tested-by: Nathan Chancellor Tested-by: Andreas Hindborg Reviewed-by: Andreas Hindborg Link: https://patch.msgid.link/20260203-inline-helpers-v2-3-beb8547a03c9@google.com [ Some changes, apart from the rebase: - Added "(EXPERIMENTAL)" to Kconfig as the commit mentions. - Added `depends on ARM64 || X86_64` and `!UML` for now, since this is experimental, other architectures may require other changes (e.g. the issues I mentioned in the mailing list for ARM and UML) and they are not really tested so far. So let arch maintainers pick this up if they think it is worth it. - Gated the `cmd_ld_single` step also into the new mode, which also means that any possible future `objcopy` step is done after the translation, as expected. - Added `.gitignore` for `.bc` with exception for existing script. - Added `part-of-*` for helpers bitcode files as discussed, and dropped `$(if $(filter %_module.bc,$@),-DMODULE)` since `-DMODULE` is already there (would be duplicated otherwise). - Moved `LLVM_LINK` to keep binutils list alphabetized. - Fixed typo in title. - Dropped second `cmd_ld_single` commit message paragraph. - Miguel ] Signed-off-by: Miguel Ojeda --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 2b15f0b4a0cb..1a219bf1c771 100644 --- a/Makefile +++ b/Makefile @@ -515,6 +515,7 @@ ifneq ($(LLVM),) CC = $(LLVM_PREFIX)clang$(LLVM_SUFFIX) LD = $(LLVM_PREFIX)ld.lld$(LLVM_SUFFIX) AR = $(LLVM_PREFIX)llvm-ar$(LLVM_SUFFIX) +LLVM_LINK = $(LLVM_PREFIX)llvm-link$(LLVM_SUFFIX) NM = $(LLVM_PREFIX)llvm-nm$(LLVM_SUFFIX) OBJCOPY = $(LLVM_PREFIX)llvm-objcopy$(LLVM_SUFFIX) OBJDUMP = $(LLVM_PREFIX)llvm-objdump$(LLVM_SUFFIX) @@ -628,7 +629,7 @@ export RUSTC_BOOTSTRAP := 1 export CLIPPY_CONF_DIR := $(srctree) export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG -export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN +export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN LLVM_LINK export HOSTRUSTC KBUILD_HOSTRUSTFLAGS export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX -- cgit From 10eea3c147141c90cf409b8df56d245c9d7f88d9 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 31 Mar 2026 22:58:48 +0200 Subject: kbuild: rust: allow `clippy::uninlined_format_args` Clippy in Rust 1.88.0 (only) reports [1]: warning: variables can be used directly in the `format!` string --> rust/macros/module.rs:112:23 | 112 | let content = format!("{param}:{content}", param = param, content = content); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args = note: `-W clippy::uninlined-format-args` implied by `-W clippy::all` = help: to override `-W clippy::all` add `#[allow(clippy::uninlined_format_args)]` help: change this to | 112 - let content = format!("{param}:{content}", param = param, content = content); 112 + let content = format!("{param}:{content}"); warning: variables can be used directly in the `format!` string --> rust/macros/module.rs:198:14 | 198 | t => panic!("Unsupported parameter type {}", t), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args = note: `-W clippy::uninlined-format-args` implied by `-W clippy::all` = help: to override `-W clippy::all` add `#[allow(clippy::uninlined_format_args)]` help: change this to | 198 - t => panic!("Unsupported parameter type {}", t), 198 + t => panic!("Unsupported parameter type {t}"), | The reason it only triggers in that version is that the lint was moved from `pedantic` to `style` in Rust 1.88.0 and then back to `pedantic` in Rust 1.89.0 [2][3]. In the first case, the suggestion is fair and a pure simplification, thus we will clean it up separately. To keep the behavior the same across all versions, and since the lint does not work for all macros (e.g. custom ones like `pr_info!`), disable it globally. Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs). Link: https://lore.kernel.org/rust-for-linux/CANiq72=drAtf3y_DZ-2o4jb6Az9J3Yj4QYwWnbRui4sm4AJD3Q@mail.gmail.com/ [1] Link: https://github.com/rust-lang/rust-clippy/pull/15287 [2] Link: https://github.com/rust-lang/rust-clippy/issues/15151 [3] Link: https://patch.msgid.link/20260331205849.498295-1-ojeda@kernel.org Signed-off-by: Miguel Ojeda --- Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 1a219bf1c771..a63684c36d60 100644 --- a/Makefile +++ b/Makefile @@ -494,6 +494,7 @@ export rust_common_flags := --edition=2021 \ -Wclippy::ptr_cast_constness \ -Wclippy::ref_as_ptr \ -Wclippy::undocumented_unsafe_blocks \ + -Aclippy::uninlined_format_args \ -Wclippy::unnecessary_safety_comment \ -Wclippy::unnecessary_safety_doc \ -Wrustdoc::missing_crate_level_docs \ -- cgit From 7ed188605e1d30e8b45d78846e3bc2bbb6394948 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 6 Apr 2026 01:52:43 +0200 Subject: rust: allow globally `clippy::incompatible_msrv` `clippy::incompatible_msrv` is not buying us much, and we discussed allowing it several times in the past. For instance, there was recently another patch sent to `allow` it where needed [1]. While that particular case would not be needed after the minimum version bump to 1.85.0, it is simpler to just allow it to prevent future instances. [ In addition, the lint fired without taking into account the features that have been enabled in a crate [2]. While this was improved in Rust 1.90.0 [3], it would still fire in a case like this patch. ] Thus do so, and remove the last instance of locally allowing it we have in the tree (except the one in the vendored `proc_macro2` crate). Note that we still keep the `msrv` config option in `clippy.toml` since that affects other lints as well. Link: https://lore.kernel.org/rust-for-linux/20260404212831.78971-4-jhubbard@nvidia.com/ [1] Link: https://github.com/rust-lang/rust-clippy/issues/14425 [2] Link: https://github.com/rust-lang/rust-clippy/pull/14433 [3] Link: https://patch.msgid.link/20260405235309.418950-8-ojeda@kernel.org Reviewed-by: Gary Guo Reviewed-by: Tamir Duberstein Signed-off-by: Miguel Ojeda --- Makefile | 1 + rust/macros/helpers.rs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index a63684c36d60..78f5ee173eda 100644 --- a/Makefile +++ b/Makefile @@ -486,6 +486,7 @@ export rust_common_flags := --edition=2021 \ -Wclippy::as_underscore \ -Wclippy::cast_lossless \ -Wclippy::ignored_unit_patterns \ + -Aclippy::incompatible_msrv \ -Wclippy::mut_mut \ -Wclippy::needless_bitwise_bool \ -Aclippy::needless_lifetimes \ diff --git a/rust/macros/helpers.rs b/rust/macros/helpers.rs index 37ef6a6f2c85..d18fbf4daa0a 100644 --- a/rust/macros/helpers.rs +++ b/rust/macros/helpers.rs @@ -49,7 +49,6 @@ pub(crate) fn file() -> String { } #[cfg(CONFIG_RUSTC_HAS_SPAN_FILE)] - #[allow(clippy::incompatible_msrv)] { proc_macro::Span::call_site().file() } -- cgit From b2aa1535ecdd10514daabe5e8eb7cea49aa5b5ec Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 6 Apr 2026 01:53:08 +0200 Subject: rust: kbuild: support global per-version flags Sometimes it is useful to gate global Rust flags per compiler version. For instance, we may want to disable a lint that has false positives in a single version [1]. We already had helpers like `rustc-min-version` for that, which we use elsewhere, but we cannot currently use them for `rust_common_flags`, which contains the global flags for all Rust code (kernel and host), because `rustc-min-version` depends on `CONFIG_RUSTC_VERSION`, which does not exist when `rust_common_flags` is defined. Thus, to support that, introduce `rust_common_flags_per_version`, defined after the `include/config/auto.conf` inclusion (where `CONFIG_RUSTC_VERSION` becomes available), and append it to `rust_common_flags`, `KBUILD_HOSTRUSTFLAGS` and `KBUILD_RUSTFLAGS`. In addition, move the expansion of `HOSTRUSTFLAGS` to the same place, so that users can also override per-version flags [2]. Link: https://lore.kernel.org/rust-for-linux/CANiq72mWdFU11GcCZRchzhy0Gi1QZShvZtyRkHV2O+WA2uTdVQ@mail.gmail.com/ [1] Link: https://lore.kernel.org/rust-for-linux/CANiq72mTaA2tjhkLKf0-2hrrrt9rxWPgy6SfNSbponbGOegQvA@mail.gmail.com/ [2] Link: https://patch.msgid.link/20260307170929.153892-1-ojeda@kernel.org Link: https://patch.msgid.link/20260405235309.418950-33-ojeda@kernel.org Reviewed-by: Tamir Duberstein Signed-off-by: Miguel Ojeda --- Makefile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 78f5ee173eda..a305ae4be522 100644 --- a/Makefile +++ b/Makefile @@ -506,7 +506,7 @@ KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \ KBUILD_HOSTCXXFLAGS := -Wall -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS) \ -I $(srctree)/scripts/include KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \ - -Zallow-features= $(HOSTRUSTFLAGS) + -Zallow-features= KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS) KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS) KBUILD_PROCMACROLDFLAGS := $(or $(PROCMACROLDFLAGS),$(KBUILD_HOSTLDFLAGS)) @@ -836,6 +836,14 @@ endif # CONFIG_TRACEPOINTS export WARN_ON_UNUSED_TRACEPOINTS +# Per-version Rust flags. These are like `rust_common_flags`, but may +# depend on the Rust compiler version (e.g. using `rustc-min-version`). +rust_common_flags_per_version := + +rust_common_flags += $(rust_common_flags_per_version) +KBUILD_HOSTRUSTFLAGS += $(rust_common_flags_per_version) $(HOSTRUSTFLAGS) +KBUILD_RUSTFLAGS += $(rust_common_flags_per_version) + include $(srctree)/arch/$(SRCARCH)/Makefile ifdef need-config -- cgit From 2e2f8b5a065683f4530ee71363875da1a20f5a7f Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 6 Apr 2026 01:53:09 +0200 Subject: rust: kbuild: allow `clippy::precedence` for Rust < 1.86.0 The Clippy `precedence` lint was extended in Rust 1.85.0 to include bitmasking and shift operations [1]. However, because it generated many hits, in Rust 1.86.0 it was split into a new `precedence_bits` lint which is not enabled by default [2]. In other words, only Rust 1.85 has a different behavior. For instance, it reports: warning: operator precedence can trip the unwary --> drivers/gpu/nova-core/fb/hal/ga100.rs:16:5 | 16 | / u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::read(bar).adr_39_08()) << FLUSH_SYSMEM_ADDR_SHIFT 17 | | | u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI::read(bar).adr_63_40()) 18 | | << FLUSH_SYSMEM_ADDR_SHIFT_HI | |_________________________________________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#precedence = note: `-W clippy::precedence` implied by `-W clippy::all` = help: to override `-W clippy::all` add `#[allow(clippy::precedence)]` help: consider parenthesizing your expression | 16 ~ (u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR::read(bar).adr_39_08()) << FLUSH_SYSMEM_ADDR_SHIFT) | (u64::from(regs::NV_PFB_NISO_FLUSH_SYSMEM_ADDR_HI::read(bar).adr_63_40()) 17 + << FLUSH_SYSMEM_ADDR_SHIFT_HI) | While so far we try our best to keep all versions Clippy-clean, the minimum (which is now Rust 1.85.0 after the bump) and the latest stable are the most important ones; and this may be considered a "false positive" with respect to the behavior in other versions. Thus allow this lint for this version using the per-version flags mechanism introduced in the previous commit. Link: https://github.com/rust-lang/rust-clippy/issues/14097 [1] Link: https://github.com/rust-lang/rust-clippy/pull/14115 [2] Link: https://lore.kernel.org/rust-for-linux/DFVDKMMA7KPC.2DN0951H3H55Y@kernel.org/ Reviewed-by: Tamir Duberstein Reviewed-by: Gary Guo Link: https://patch.msgid.link/20260405235309.418950-34-ojeda@kernel.org [ Added paragraph from commit message to comment. - Miguel ] Signed-off-by: Miguel Ojeda --- Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index a305ae4be522..a497dba9301c 100644 --- a/Makefile +++ b/Makefile @@ -838,7 +838,13 @@ export WARN_ON_UNUSED_TRACEPOINTS # Per-version Rust flags. These are like `rust_common_flags`, but may # depend on the Rust compiler version (e.g. using `rustc-min-version`). -rust_common_flags_per_version := +# +# `-Aclippy::precedence`: the lint was extended in Rust 1.85.0 to +# include bitmasking and shift operations. However, because it generated +# many hits, in Rust 1.86.0 it was split into a new `precedence_bits` +# lint which is not enabled by default. +rust_common_flags_per_version := \ + $(if $(call rustc-min-version,108600),,-Aclippy::precedence) rust_common_flags += $(rust_common_flags_per_version) KBUILD_HOSTRUSTFLAGS += $(rust_common_flags_per_version) $(HOSTRUSTFLAGS) -- cgit