[PATCH v5 4/4] rust: Add warn_on macro
Alice Ryhl
aliceryhl at google.com
Thu Apr 10 00:39:48 PDT 2025
On Wed, Apr 09, 2025 at 03:58:01PM +0900, FUJITA Tomonori wrote:
> Add warn_on macro, uses the BUG/WARN feature (lib/bug.c) via assembly
> for x86_64/arm64/riscv.
>
> The current Rust code simply wraps BUG() macro but doesn't provide the
> proper debug information. The BUG/WARN feature can only be used from
> assembly.
>
> This uses the assembly code exported by the C side via ARCH_WARN_ASM
> macro. To avoid duplicating the assembly code, this approach follows
> the same strategy as the static branch code: it generates the assembly
> code for Rust using the C preprocessor at compile time.
>
> Similarly, ARCH_WARN_REACHABLE is also used at compile time to
> generate the assembly code; objtool's reachable anotation code. It's
> used for only architectures that use objtool.
>
> For now, Loongarch and arm32 just use a wrapper for WARN macro.
>
> UML doesn't use the assembly BUG/WARN feature; just wrapping generic
> BUG/WARN functions implemented in C works.
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
> ---
> rust/Makefile | 8 ++
> rust/helpers/bug.c | 5 +
> rust/kernel/.gitignore | 2 +
> rust/kernel/bug.rs | 114 ++++++++++++++++++
> rust/kernel/generated_arch_reachable_asm.rs.S | 7 ++
> rust/kernel/generated_arch_warn_asm.rs.S | 7 ++
> rust/kernel/lib.rs | 1 +
> 7 files changed, 144 insertions(+)
> create mode 100644 rust/kernel/bug.rs
> create mode 100644 rust/kernel/generated_arch_reachable_asm.rs.S
> create mode 100644 rust/kernel/generated_arch_warn_asm.rs.S
>
> diff --git a/rust/Makefile b/rust/Makefile
> index fa0eea8a9eca..25f498607d1b 100644
> --- a/rust/Makefile
> +++ b/rust/Makefile
> @@ -34,6 +34,9 @@ obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.o
> obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.o
>
> always-$(subst y,$(CONFIG_RUST),$(CONFIG_JUMP_LABEL)) += kernel/generated_arch_static_branch_asm.rs
> +ifndef CONFIG_UML
> +always-$(subst y,$(CONFIG_RUST),$(CONFIG_BUG)) += kernel/generated_arch_warn_asm.rs kernel/generated_arch_reachable_asm.rs
> +endif
>
> # Avoids running `$(RUSTC)` when it may not be available.
> ifdef CONFIG_RUST
> @@ -536,5 +539,10 @@ $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.o $(obj)/pin_init.o \
> ifdef CONFIG_JUMP_LABEL
> $(obj)/kernel.o: $(obj)/kernel/generated_arch_static_branch_asm.rs
> endif
> +ifndef CONFIG_UML
> +ifdef CONFIG_BUG
> +$(obj)/kernel.o: $(obj)/kernel/generated_arch_warn_asm.rs $(obj)/kernel/generated_arch_reachable_asm.rs
> +endif
> +endif
>
> endif # CONFIG_RUST
> diff --git a/rust/helpers/bug.c b/rust/helpers/bug.c
> index e2d13babc737..a62c96f507d1 100644
> --- a/rust/helpers/bug.c
> +++ b/rust/helpers/bug.c
> @@ -6,3 +6,8 @@ __noreturn void rust_helper_BUG(void)
> {
> BUG();
> }
> +
> +bool rust_helper_WARN_ON(bool cond)
> +{
> + return WARN_ON(cond);
> +}
> diff --git a/rust/kernel/.gitignore b/rust/kernel/.gitignore
> index 6ba39a178f30..f636ad95aaf3 100644
> --- a/rust/kernel/.gitignore
> +++ b/rust/kernel/.gitignore
> @@ -1,3 +1,5 @@
> # SPDX-License-Identifier: GPL-2.0
>
> /generated_arch_static_branch_asm.rs
> +/generated_arch_warn_asm.rs
> +/generated_arch_reachable_asm.rs
> diff --git a/rust/kernel/bug.rs b/rust/kernel/bug.rs
> new file mode 100644
> index 000000000000..761f0c49ae04
> --- /dev/null
> +++ b/rust/kernel/bug.rs
> @@ -0,0 +1,114 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +// Copyright (C) 2024, 2025 FUJITA Tomonori <fujita.tomonori at gmail.com>
> +
> +//! Support for BUG and WARN functionality.
> +//!
> +//! C header: [`include/asm-generic/bug.h`](srctree/include/asm-generic/bug.h)
> +
> +#[macro_export]
> +#[doc(hidden)]
> +#[cfg(all(CONFIG_BUG, not(CONFIG_UML), not(CONFIG_LOONGARCH), not(CONFIG_ARM)))]
> +#[cfg(CONFIG_DEBUG_BUGVERBOSE)]
> +macro_rules! warn_flags {
> + ($flags:expr) => {
> + const FLAGS: u32 = $crate::bindings::BUGFLAG_WARNING | $flags;
> + const _FILE: &[u8] = file!().as_bytes();
> + // Plus one for null-terminator.
> + static FILE: [u8; _FILE.len() + 1] = {
> + let mut bytes = [0; _FILE.len() + 1];
> + let mut i = 0;
> + while i < _FILE.len() {
> + bytes[i] = _FILE[i];
> + i += 1;
> + }
> + bytes
> + };
> + // SAFETY: Just an FFI call.
Safety comments could be improved. This being an FFI call is not the
reason why it's okay. Furthermore, it's not an FFI call.
Otherwise, this series LGTM.
Alice
More information about the linux-arm-kernel
mailing list