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

Reply via email to