From 0bff7711c19ba05ff3b686554c5a2d503c3e9797 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sun, 16 Aug 2026 15:32:32 +0200 Subject: [PATCH] kbuild: rust: preserve unreachable traps with inline helpers When `CONFIG_RUST_INLINE_HELPERS` is enabled, it is possible to hit `objtool` warnings like: vmlinux.o: warning: objtool: _R..._4cmdq12CommandToGsp4init() falls through to next function _R..._4core5array4iter8IntoIterRShKj3_EEEBa_() `rustc` normally emits traps for unreachable paths. However, under `CONFIG_RUST_INLINE_HELPERS=y`, `rustc` emits LLVM bitcode and Clang performs final code generation after the helper bitcode is linked, but Clang does not trap unreachable IR by default. In turn, this means `objtool` follows compiler-generated impossible Rust `enum` paths through alignment padding into the next function, resulting in fallthrough warnings. Thus pass the LLVM `trap-unreachable` option to the final Clang invocation and suppress traps immediately after `noreturn` calls, which `objtool` already recognizes as dead ends. The combination of both flags makes it match `rustc`'s behavior. Rust 1.85.0 (the minimum supported one) supports LLVM >= 18, and both flags are available in LLVM 18. Assisted-by: LLM Cc: Gary Guo Cc: Boqun Feng Cc: Alice Ryhl Cc: Matthew Maurer Cc: Josh Poimboeuf Cc: Peter Zijlstra Cc: stable@vger.kernel.org Fixes: 3a2486cc1da5 ("kbuild: rust: provide an option to inline C helpers into Rust") Acked-by: Gary Guo Link: https://patch.msgid.link/20260816133233.197500-1-ojeda@kernel.org Signed-off-by: Miguel Ojeda --- Makefile | 10 ++++++++++ rust/Makefile | 3 ++- scripts/Makefile.build | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index c2344755a1bb..960f296e4a4d 100644 --- a/Makefile +++ b/Makefile @@ -1083,6 +1083,16 @@ endif export CC_FLAGS_SCS endif +ifdef CONFIG_RUST_INLINE_HELPERS +# `rustc` normally emits traps for unreachable paths during code generation. +# With inline helpers, Clang performs code generation from the linked bitcode +# instead, so request the same behavior explicitly. Otherwise `objtool` may +# follow an impossible Rust path into the next function. +CC_FLAGS_RUST_INLINE_HELPERS := -mllvm -trap-unreachable \ + -mllvm -no-trap-after-noreturn +export CC_FLAGS_RUST_INLINE_HELPERS +endif + ifdef CONFIG_LTO_CLANG ifdef CONFIG_LTO_CLANG_FULL CC_FLAGS_LTO := -flto diff --git a/rust/Makefile b/rust/Makefile index fbe0accc51a3..f871d94f6af2 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -644,7 +644,8 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L -Zunstable-options \ $(if $(link_helper),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \ $(obj)/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \ - $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ + $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) \ + $(CC_FLAGS_RUST_INLINE_HELPERS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ $(cmd_ld_single)) \ $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \ $(cmd_objtool) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a48209591dee..0ac326e43fea 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -347,7 +347,8 @@ quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ cmd_rustc_o_rs = $(rust_common_cmd) --emit=$(if $(CONFIG_RUST_INLINE_HELPERS),llvm-bc=$(patsubst %.o,%.bc,$@),obj=$@) $< \ $(if $(CONFIG_RUST_INLINE_HELPERS),;$(LLVM_LINK) --internalize --suppress-warnings $(patsubst %.o,%.bc,$@) \ $(objtree)/rust/helpers/helpers$(if $(part-of-module),_module).bc -o $(patsubst %.o,%.m.bc,$@); \ - $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ + $(CC) $(CLANG_FLAGS) $(KBUILD_CFLAGS) \ + $(CC_FLAGS_RUST_INLINE_HELPERS) -Wno-override-module -c $(patsubst %.o,%.m.bc,$@) -o $@ \ $(cmd_ld_single)) \ $(cmd_objtool)