Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/rust/kernel/bug.rs
29266 views
1
// SPDX-License-Identifier: GPL-2.0
2
3
// Copyright (C) 2024, 2025 FUJITA Tomonori <[email protected]>
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)]
13
macro_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))]
52
macro_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))]
77
macro_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)))]
95
macro_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))]
105
macro_rules! warn_flags {
106
($flags:expr) => {};
107
}
108
109
#[doc(hidden)]
110
pub 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]
116
macro_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
}
127
128