File Index
Files and directories
Sign in
FILE

bug.rs

File preview with syntax highlighting.

linux-6.19.14/rust/kernel/bug.rs RUST
  1// SPDX-License-Identifier: GPL-2.0
  2
  3// Copyright (C) 2024, 2025 FUJITA Tomonori <fujita.tomonori@gmail.com>
  4
  5//! Support for BUG and WARN functionality.
  6//!
  7//! C header: [`include/asm-generic/bug.h`](srctree/include/asm-generic/bug.h)
  8
  9#[macro_export]
 10#[doc(hidden)]
 11#[cfg(all(CONFIG_BUG, not(CONFIG_UML), not(CONFIG_LOONGARCH), not(CONFIG_ARM)))]
 12#[cfg(CONFIG_DEBUG_BUGVERBOSE)]
 13macro_rules! warn_flags {
 14    ($flags:expr) => {
 15        const FLAGS: u32 = $crate::bindings::BUGFLAG_WARNING | $flags;
 16        const _FILE: &[u8] = file!().as_bytes();
 17        // Plus one for null-terminator.
 18        static FILE: [u8; _FILE.len() + 1] = {
 19            let mut bytes = [0; _FILE.len() + 1];
 20            let mut i = 0;
 21            while i < _FILE.len() {
 22                bytes[i] = _FILE[i];
 23                i += 1;
 24            }
 25            bytes
 26        };
 27
 28        // SAFETY:
 29        // - `file`, `line`, `flags`, and `size` are all compile-time constants or
 30        // symbols, preventing any invalid memory access.
 31        // - The asm block has no side effects and does not modify any registers
 32        // or memory. It is purely for embedding metadata into the ELF section.
 33        unsafe {
 34            $crate::asm!(
 35                concat!(
 36                    "/* {size} */",
 37                    include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_warn_asm.rs")),
 38                    include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_reachable_asm.rs")));
 39                file = sym FILE,
 40                line = const line!(),
 41                flags = const FLAGS,
 42                size = const ::core::mem::size_of::<$crate::bindings::bug_entry>(),
 43            );
 44        }
 45    }
 46}
 47
 48#[macro_export]
 49#[doc(hidden)]
 50#[cfg(all(CONFIG_BUG, not(CONFIG_UML), not(CONFIG_LOONGARCH), not(CONFIG_ARM)))]
 51#[cfg(not(CONFIG_DEBUG_BUGVERBOSE))]
 52macro_rules! warn_flags {
 53    ($flags:expr) => {
 54        const FLAGS: u32 = $crate::bindings::BUGFLAG_WARNING | $flags;
 55
 56        // SAFETY:
 57        // - `flags` and `size` are all compile-time constants, preventing
 58        // any invalid memory access.
 59        // - The asm block has no side effects and does not modify any registers
 60        // or memory. It is purely for embedding metadata into the ELF section.
 61        unsafe {
 62            $crate::asm!(
 63                concat!(
 64                    "/* {size} */",
 65                    include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_warn_asm.rs")),
 66                    include!(concat!(env!("OBJTREE"), "/rust/kernel/generated_arch_reachable_asm.rs")));
 67                flags = const FLAGS,
 68                size = const ::core::mem::size_of::<$crate::bindings::bug_entry>(),
 69            );
 70        }
 71    }
 72}
 73
 74#[macro_export]
 75#[doc(hidden)]
 76#[cfg(all(CONFIG_BUG, CONFIG_UML))]
 77macro_rules! warn_flags {
 78    ($flags:expr) => {
 79        // SAFETY: It is always safe to call `warn_slowpath_fmt()`
 80        // with a valid null-terminated string.
 81        unsafe {
 82            $crate::bindings::warn_slowpath_fmt(
 83                $crate::c_str!(::core::file!()).as_char_ptr(),
 84                line!() as $crate::ffi::c_int,
 85                $flags as $crate::ffi::c_uint,
 86                ::core::ptr::null(),
 87            );
 88        }
 89    };
 90}
 91
 92#[macro_export]
 93#[doc(hidden)]
 94#[cfg(all(CONFIG_BUG, any(CONFIG_LOONGARCH, CONFIG_ARM)))]
 95macro_rules! warn_flags {
 96    ($flags:expr) => {
 97        // SAFETY: It is always safe to call `WARN_ON()`.
 98        unsafe { $crate::bindings::WARN_ON(true) }
 99    };
100}
101
102#[macro_export]
103#[doc(hidden)]
104#[cfg(not(CONFIG_BUG))]
105macro_rules! warn_flags {
106    ($flags:expr) => {};
107}
108
109#[doc(hidden)]
110pub const fn bugflag_taint(value: u32) -> u32 {
111    value << 8
112}
113
114/// Report a warning if `cond` is true and return the condition's evaluation result.
115#[macro_export]
116macro_rules! warn_on {
117    ($cond:expr) => {{
118        let cond = $cond;
119        if cond {
120            const WARN_ON_FLAGS: u32 = $crate::bug::bugflag_taint($crate::bindings::TAINT_WARN);
121
122            $crate::warn_flags!(WARN_ON_FLAGS);
123        }
124        cond
125    }};
126}
~/ Read-only file preview.