[PATCH v3 5/5] rust: Add warn_on and warn_on_once
Alice Ryhl
aliceryhl at google.com
Mon Mar 3 05:33:39 PST 2025
On Thu, Feb 13, 2025 at 3:01 PM FUJITA Tomonori
<fujita.tomonori at gmail.com> wrote:
>
> Add warn_on and warn_on_once macros. Wrapping the C's WARN_* and BUG_*
> macros doesn't work so this uses the assembly code exported by the C
> side via ARCH_WARN_ASM macro. Like the static branch code, this
> generates the assembly code for rust at compile time by using the C
> preprocessor.
>
> file()! macro doesn't work for the Rust inline assembly in the same
> way as __FILE__ for the C inline assembly. So the code to handle a
> file name is different from the C assembly code (similar to the
> arm64/loongarch assembly).
>
> Similarly, ARCH_WARN_REACHABLE is also used at compile time to
> generate the assembly code; objtool's reachable anotation code. Only
> architectures that use objtool (x86 and loongarch) need it.
>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori at gmail.com>
> ---
> rust/Makefile | 8 ++
> rust/kernel/.gitignore | 2 +
> rust/kernel/bug.rs | 100 ++++++++++++++++++
> rust/kernel/generated_arch_reachable_asm.rs.S | 7 ++
> rust/kernel/generated_arch_warn_asm.rs.S | 7 ++
> rust/kernel/lib.rs | 1 +
> 6 files changed, 125 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 8fcfd60447bc..a295b65c43f3 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
> @@ -481,5 +484,10 @@ $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/build_error.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/kernel/.gitignore b/rust/kernel/.gitignore
> index 6ba39a178f30..f1d7f4225332 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
> \ No newline at end of file
> diff --git a/rust/kernel/bug.rs b/rust/kernel/bug.rs
> new file mode 100644
> index 000000000000..7ffd9cb1ad75
> --- /dev/null
> +++ b/rust/kernel/bug.rs
> @@ -0,0 +1,100 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +// Copyright (C) 2024 FUJITA Tomonori
> +
> +//! 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)))]
> +macro_rules! warn_flags {
> + ($flags:expr) => {
> + const FLAGS: u32 = $crate::bindings::BUGFLAG_WARNING | $flags;
> + // SAFETY: Just an FFI call.
> + #[cfg(CONFIG_DEBUG_BUGVERBOSE)]
> + unsafe {
> + $crate::asm!(concat!(
> + "/* {size} */",
> + ".pushsection .rodata.str1.1, \"aMS\", at progbits, 1\n",
> + "111:\t .string ", "\"", file!(), "\"\n",
> + ".popsection\n",
It looks like you're doing this so that you can reference the filename
with "111b", but could you do this instead:
const _FILE: &[u8] = file!().as_bytes();
// Plus one for nul-terminator.
static FILE: [u8; 1 + _FILE.len()] = {
let mut bytes = [0; 1 + _FILE.len()];
let mut i = 0;
while i < _FILE.len() {
bytes[i] = _FILE[i];
i += 1;
}
bytes
};
and then use
asm!(
concat!(
"/* {size} */",
include!(concat!(env!("OBJTREE"),
"/rust/kernel/generated_arch_warn_asm.rs")),
include!(concat!(env!("OBJTREE"),
"/rust/kernel/generated_arch_reachable_asm.rs")));
file = sym FILE,
line = const line!(),
...
);
with
::kernel::concat_literals!(ARCH_WARN_ASM("{file}", "{line}",
"{flags}", "{size}")),
That would be a lot simpler to understand than what you are doing.
Alice
More information about the linux-arm-kernel
mailing list