Rust for Linux List
 help / color / mirror / Atom feed
From: FUJITA Tomonori <tomo@flapping.org>
To: ojeda@kernel.org
Cc: a.hindborg@kernel.org, acourbot@nvidia.com, aliceryhl@google.com,
	bjorn3_gh@protonmail.com, boqun@kernel.org, dakr@kernel.org,
	daniel.almeida@collabora.com, gary@garyguo.net,
	lossin@kernel.org, tamird@kernel.org, tmgross@umich.edu,
	work@onurozkan.dev, rust-for-linux@vger.kernel.org,
	FUJITA Tomonori <fujita.tomonori@gmail.com>
Subject: [PATCH v3] rust: compiler_builtins: Fix silent trap in prohibited intrinsics
Date: Thu,  8 Oct 2026 20:47:17 +0900	[thread overview]
Message-ID: <20261008114717.992497-1-tomo@flapping.org> (raw)

From: FUJITA Tomonori <fujita.tomonori@gmail.com>

When core calls one of the stubs for builtins that should not be used,
the stub runs a trap instruction that prints no message, and the Oops
shows a wrong name. For example, when __rust__udivti3() is called on
x86_64, the Oops shows:

  Oops: invalid opcode: 0000 [#1] SMP
  RIP: 0010:__rust__adddf3+0x0/0x10

The stubs call panic!(), but since Rust 1.79, rustc does not allow code
in a `#![compiler_builtins]` crate to link to functions in other crates,
and it silently turns such calls that do not return into a trap [1]. In
addition, all the stubs have the same code, so LLVM merges them into one
function.

Move the stubs to the kernel crate, where panic!() works as usual. Add
the name of each stub to the panic message, so the stubs are no longer
merged:

  rust_kernel: panicked at rust/kernel/core_builtins.rs:56:1:
  __udivti3 called: `u128` should not be used
  kernel BUG at rust/helpers/bug.c:7!

compiler_builtins.rs is now empty, but the crate is still needed because
rustc requires a `#![compiler_builtins]` crate.

Link: https://github.com/rust-lang/rust/pull/122580 [1]
Assisted-by: LLM
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
v3:
- Rename rust/kernel/intrinsics.rs to rust/kernel/core_builtins.rs (Gary)
- Reword the doc of compiler_builtins.rs (Gary)
v2: https://lore.kernel.org/rust-for-linux/20261003124828.119912-1-tomo@flapping.org/
- Move the stubs to the kernel crate and use panic!() there (Gary)
v1: https://lore.kernel.org/rust-for-linux/20261002014739.2566289-1-tomo@flapping.org/
---
 rust/compiler_builtins.rs                     | 97 +------------------
 .../core_builtins.rs}                         | 26 ++---
 rust/kernel/lib.rs                            |  2 +
 3 files changed, 13 insertions(+), 112 deletions(-)
 copy rust/{compiler_builtins.rs => kernel/core_builtins.rs} (74%)

diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs
index fc6b54636dd5..65476a7c87ae 100644
--- a/rust/compiler_builtins.rs
+++ b/rust/compiler_builtins.rs
@@ -3,18 +3,10 @@
 //! Our own `compiler_builtins`.
 //!
 //! Rust provides [`compiler_builtins`] as a port of LLVM's [`compiler-rt`].
-//! Since we do not need the vast majority of them, we avoid the dependency
-//! by providing this file.
-//!
-//! At the moment, some builtins are required that should not be. For instance,
-//! [`core`] has 128-bit integers functionality which we should not be compiling
-//! in. We will work with upstream [`core`] to provide feature flags to disable
-//! the parts we do not need. For the moment, we define them to [`panic!`] at
-//! runtime for simplicity to catch mistakes, instead of performing surgery
-//! on `core.o`.
-//!
-//! In any case, all these symbols are weakened to ensure we do not override
-//! those that may be provided by the rest of the kernel.
+//! Since we do not need the vast majority of them, we avoid the dependency.
+//! But `rustc` still needs a `#![compiler_builtins]` crate for every crate it
+//! builds, so this crate is provided and left empty. The few builtins that
+//! `core` needs are in the `kernel` crate (`rust/kernel/core_builtins.rs`).
 //!
 //! [`compiler_builtins`]: https://github.com/rust-lang/compiler-builtins
 //! [`compiler-rt`]: https://compiler-rt.llvm.org/
@@ -24,84 +16,3 @@
 #![compiler_builtins]
 #![no_builtins]
 #![no_std]
-
-macro_rules! define_panicking_intrinsics(
-    ($reason: tt, { $($ident: ident, )* }) => {
-        $(
-            #[doc(hidden)]
-            #[export_name = concat!("__rust", stringify!($ident))]
-            pub extern "C" fn $ident() {
-                panic!($reason);
-            }
-        )*
-    }
-);
-
-define_panicking_intrinsics!("`f32` should not be used", {
-    __addsf3,
-    __eqsf2,
-    __extendsfdf2,
-    __gesf2,
-    __lesf2,
-    __ltsf2,
-    __mulsf3,
-    __nesf2,
-    __truncdfsf2,
-    __unordsf2,
-});
-
-define_panicking_intrinsics!("`f64` should not be used", {
-    __adddf3,
-    __eqdf2,
-    __ledf2,
-    __ltdf2,
-    __muldf3,
-    __unorddf2,
-});
-
-define_panicking_intrinsics!("`i128` should not be used", {
-    __ashrti3,
-    __muloti4,
-    __multi3,
-});
-
-define_panicking_intrinsics!("`u128` should not be used", {
-    __ashlti3,
-    __lshrti3,
-    __udivmodti4,
-    __udivti3,
-    __umodti3,
-});
-
-#[cfg(target_arch = "arm")]
-define_panicking_intrinsics!("`f32` should not be used", {
-    __aeabi_fadd,
-    __aeabi_fmul,
-    __aeabi_fcmpeq,
-    __aeabi_fcmple,
-    __aeabi_fcmplt,
-    __aeabi_fcmpun,
-});
-
-#[cfg(target_arch = "arm")]
-define_panicking_intrinsics!("`f64` should not be used", {
-    __aeabi_dadd,
-    __aeabi_dmul,
-    __aeabi_dcmple,
-    __aeabi_dcmplt,
-    __aeabi_dcmpun,
-});
-
-#[cfg(target_arch = "arm")]
-define_panicking_intrinsics!("`u64` division/modulo should not be used", {
-    __aeabi_uldivmod,
-});
-
-#[cfg(target_arch = "powerpc")]
-define_panicking_intrinsics!("`u64` division/modulo should not be used", {
-    __udivdi3,
-    __umoddi3,
-});
-
-// NOTE: if you are adding a new intrinsic here, you should also add it to
-// `redirect-intrinsics` in `rust/Makefile`.
diff --git a/rust/compiler_builtins.rs b/rust/kernel/core_builtins.rs
similarity index 74%
copy from rust/compiler_builtins.rs
copy to rust/kernel/core_builtins.rs
index fc6b54636dd5..b147475156b4 100644
--- a/rust/compiler_builtins.rs
+++ b/rust/kernel/core_builtins.rs
@@ -1,10 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 
-//! Our own `compiler_builtins`.
-//!
-//! Rust provides [`compiler_builtins`] as a port of LLVM's [`compiler-rt`].
-//! Since we do not need the vast majority of them, we avoid the dependency
-//! by providing this file.
+//! Builtins that `core` needs.
 //!
 //! At the moment, some builtins are required that should not be. For instance,
 //! [`core`] has 128-bit integers functionality which we should not be compiling
@@ -13,25 +9,17 @@
 //! runtime for simplicity to catch mistakes, instead of performing surgery
 //! on `core.o`.
 //!
-//! In any case, all these symbols are weakened to ensure we do not override
-//! those that may be provided by the rest of the kernel.
-//!
-//! [`compiler_builtins`]: https://github.com/rust-lang/compiler-builtins
-//! [`compiler-rt`]: https://compiler-rt.llvm.org/
-
-#![allow(internal_features)]
-#![feature(compiler_builtins)]
-#![compiler_builtins]
-#![no_builtins]
-#![no_std]
+//! The stubs are here and not in `compiler_builtins`, because code in a
+//! `#![compiler_builtins]` crate cannot link to functions in other crates.
+//! There, `rustc` turns a call to [`panic!`] into a trap that prints no
+//! message.
 
 macro_rules! define_panicking_intrinsics(
     ($reason: tt, { $($ident: ident, )* }) => {
         $(
-            #[doc(hidden)]
             #[export_name = concat!("__rust", stringify!($ident))]
-            pub extern "C" fn $ident() {
-                panic!($reason);
+            extern "C" fn $ident() {
+                panic!(concat!(stringify!($ident), " called: ", $reason));
             }
         )*
     }
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 7225abc64084..b4fdba2a3eb0 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -57,6 +57,8 @@
 pub mod clk;
 #[cfg(CONFIG_CONFIGFS_FS)]
 pub mod configfs;
+#[cfg(not(testlib))]
+mod core_builtins;
 pub mod cpu;
 #[cfg(CONFIG_CPU_FREQ)]
 pub mod cpufreq;

base-commit: 2dee3d3adcadcc57d62ba6608cd02f50b0c10264
-- 
2.43.0


             reply	other threads:[~2026-10-08 11:48 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-08 11:47 FUJITA Tomonori [this message]
2026-10-09 16:20 ` [PATCH v3] rust: compiler_builtins: Fix silent trap in prohibited intrinsics kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261008114717.992497-1-tomo@flapping.org \
    --to=tomo@flapping.org \
    --cc=a.hindborg@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=aliceryhl@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun@kernel.org \
    --cc=dakr@kernel.org \
    --cc=daniel.almeida@collabora.com \
    --cc=fujita.tomonori@gmail.com \
    --cc=gary@garyguo.net \
    --cc=lossin@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tamird@kernel.org \
    --cc=tmgross@umich.edu \
    --cc=work@onurozkan.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox