Allow Rust code to taint the kernel to record conditions that may be relevant when diagnosing subsequent kernel failures.
Signed-off-by: Danilo Krummrich <[email protected]> --- rust/bindings/bindings_helper.h | 1 + rust/kernel/lib.rs | 1 + rust/kernel/panic.rs | 50 +++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 rust/kernel/panic.rs diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index 930e63290cdd..bc248918c99b 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -74,6 +74,7 @@ #include <linux/mm.h> #include <linux/miscdevice.h> #include <linux/of_device.h> +#include <linux/panic.h> #include <linux/pci.h> #include <linux/phy.h> #include <linux/pid_namespace.h> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index f9ef36217bb5..fd8fe9373401 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -112,6 +112,7 @@ #[cfg(CONFIG_PM_OPP)] pub mod opp; pub mod page; +pub mod panic; #[cfg(CONFIG_PCI)] pub mod pci; pub mod pid_namespace; diff --git a/rust/kernel/panic.rs b/rust/kernel/panic.rs new file mode 100644 index 000000000000..8a78591dfb8a --- /dev/null +++ b/rust/kernel/panic.rs @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Kernel taint tracking. +//! +//! C header: [`include/linux/panic.h`](srctree/include/linux/panic.h) +//! +//! See the [tainted-kernels documentation] for the meaning of each taint. +//! +//! [tainted-kernels documentation]: srctree/Documentation/admin-guide/tainted-kernels.rst + +/// A reason for tainting the kernel. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum Taint { + /// Tainting was explicitly requested by the user. + User = bindings::TAINT_USER, +} + +impl Taint { + #[inline] + const fn as_raw(self) -> u32 { + self as u32 + } +} + +/// Whether lock debugging remains reliable after a tainting event. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum Lockdep { + /// Keep lock debugging enabled. + StillOk = bindings::lockdep_ok_LOCKDEP_STILL_OK, +} + +impl Lockdep { + #[inline] + const fn as_raw(self) -> bindings::lockdep_ok { + self as u32 + } +} + +/// Adds a kernel taint flag. +/// +/// Taint flags persist until reboot, even if the module that set them is unloaded. +/// Use [`Lockdep::StillOk`] when the tainting event does not compromise lock debugging. +/// This may panic if the kernel's `panic_on_taint` setting matches a set taint flag. +#[inline] +pub fn add_taint(flag: Taint, lockdep: Lockdep) { + // SAFETY: `Taint` and `Lockdep` restrict both arguments to valid C API values. + unsafe { bindings::add_taint(flag.as_raw(), lockdep.as_raw()) }; +} -- 2.56.0
