On Mon Oct 19, 2026 at 10:24 PM BST, Danilo Krummrich wrote:
> 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 {

The plain "Lockdep" is too confusing I think. I think sticking to the C enum
name `LockdepOk` would better.

Alternatively, we can consider just calling it `TaintFlags`?

    struct TaintFlags { ... }

    TaintFlags::lockdep_still_okay()
    TaintFlags::lockdep_now_unreliable()

Best,
Gary

> +    /// 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()) };
> +}


Reply via email to