Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2024, 2025 FUJITA Tomonori <fujita.tomonori@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 { ($file:expr, $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: // - `file`, `line`, `flags`, and `size` are all compile-time constants or // symbols, preventing any invalid memory access. // - The asm block has no side effects and does not modify any registers // or memory. It is purely for embedding metadata into the ELF section. unsafe { $crate::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!(), flags = const FLAGS, size = const ::core::mem::size_of::<$crate::bindings::bug_entry>(), ); } }}
#[macro_export]#[doc(hidden)]#[cfg(all(CONFIG_BUG, not(CONFIG_UML), not(CONFIG_LOONGARCH), not(CONFIG_ARM)))]#[cfg(not(CONFIG_DEBUG_BUGVERBOSE))]macro_rules! warn_flags { ($file:expr, $flags:expr) => { const FLAGS: u32 = $crate::bindings::BUGFLAG_WARNING | $flags;
// SAFETY: // - `flags` and `size` are all compile-time constants, preventing // any invalid memory access. // - The asm block has no side effects and does not modify any registers // or memory. It is purely for embedding metadata into the ELF section. unsafe { $crate::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"))); flags = const FLAGS, size = const ::core::mem::size_of::<$crate::bindings::bug_entry>(), ); } }}
#[macro_export]#[doc(hidden)]#[cfg(all(CONFIG_BUG, CONFIG_UML))]macro_rules! warn_flags { ($file:expr, $flags:expr) => { // SAFETY: It is always safe to call `warn_slowpath_fmt()` // with a valid null-terminated string. unsafe { $crate::bindings::warn_slowpath_fmt( $crate::c_str!(::core::file!()).as_char_ptr(), line!() as $crate::ffi::c_int, $flags as $crate::ffi::c_uint, ::core::ptr::null(), ); } };}
#[macro_export]#[doc(hidden)]#[cfg(all(CONFIG_BUG, any(CONFIG_LOONGARCH, CONFIG_ARM)))]macro_rules! warn_flags { ($file:expr, $flags:expr) => { // SAFETY: It is always safe to call `WARN_ON()`. unsafe { $crate::bindings::WARN_ON(true) } };}
#[macro_export]#[doc(hidden)]#[cfg(not(CONFIG_BUG))]macro_rules! warn_flags { ($file:expr, $flags:expr) => {};}
#[doc(hidden)]pub const fn bugflag_taint(value: u32) -> u32 { value << 8}
/// Report a warning if `cond` is true and return the condition's evaluation result.#[macro_export]macro_rules! warn_on { ($cond:expr) => {{ let cond = $cond;
#[cfg(CONFIG_DEBUG_BUGVERBOSE_DETAILED)] const _COND_STR: &str = concat!("[", stringify!($cond), "] ", file!()); #[cfg(not(CONFIG_DEBUG_BUGVERBOSE_DETAILED))] const _COND_STR: &str = file!();
if cond { const WARN_ON_FLAGS: u32 = $crate::bug::bugflag_taint($crate::bindings::TAINT_WARN);
$crate::warn_flags!(_COND_STR, WARN_ON_FLAGS); } cond }};}