Back to Blog
Linux3 February 2025Michael Hettwer9 min read

Integration of Rust into the Linux Kernel

Rust is now an official second language of the Linux kernel. We look at what this means in practice — how Rust modules are written, compiled, and merged, and where the language is already showing up in production kernel code.

When Linus Torvalds merged the initial Rust infrastructure into Linux 6.1 in late 2022, many observers wrote it off as an experiment. Two years later, Rust drivers are landing in mainline, the toolchain is maturing rapidly, and the kernel's own documentation officially treats Rust as a supported language. This is no longer a curiosity — it is a structural change to how the Linux kernel will be written going forward.

Why Rust?

The majority of CVEs in the Linux kernel trace back to memory-safety bugs: use-after-free, buffer overflows, null-pointer dereferences, data races. C gives programmers complete control but no compiler-level safety net. Rust's ownership and borrow-checker model makes an entire class of these bugs impossible at compile time — without a garbage collector and without sacrificing performance.

Note:

Microsoft, Google, and the NSA have all independently concluded that 70% or more of security vulnerabilities in large C/C++ codebases are memory-safety issues. Rust directly addresses this at the language level.

How Rust Code Enters the Kernel

Rust kernel code lives in the rust/ directory at the top of the source tree and in driver subdirectories alongside C code. The build system (Kbuild) handles mixed C/Rust compilation. Rust modules are compiled to object files with rustc and linked against the C kernel the same way any other object would be.

bash
# Build the kernel with Rust support enabled
# Requires: rustc (nightly), bindgen, libclang

# Check if your kernel build supports Rust
make LLVM=1 rustavailable

# Enable Rust in Kconfig
make LLVM=1 menuconfig
# Navigate to: General setup → Rust support

# Build
make LLVM=1 -j$(nproc)

A Minimal Rust Kernel Module

Rust kernel modules use the kernel crate, which provides safe wrappers around kernel internals. The module! macro registers the module metadata, and struct/impl blocks define the driver logic. Here is a minimal example that prints to the kernel log:

rust
// samples/rust/rust_minimal.rs
use kernel::prelude::*;

module! {
    type: RustMinimal,
    name: "rust_minimal",
    author: "Example Author",
    description: "A minimal Rust kernel module",
    license: "GPL",
}

struct RustMinimal;

impl kernel::Module for RustMinimal {
    fn init(_module: &'static ThisModule) -> Result<Self> {
        pr_info!("Rust minimal module loaded\n");
        Ok(RustMinimal)
    }
}

impl Drop for RustMinimal {
    fn drop(&mut self) {
        pr_info!("Rust minimal module unloaded\n");
    }
}
Tip:

The kernel crate's safe abstractions are intentionally thin. Where safety cannot be guaranteed statically, you use unsafe blocks — just as in C, but now the unsafe surface is explicit and auditable rather than implicit everywhere.

Where Rust Is Already in the Kernel

  • Apple AGX GPU driver (Asahi Linux) — one of the most complex Rust drivers merged, enabling GPU acceleration on Apple Silicon
  • Nova — a new open-source Nvidia GPU driver started entirely in Rust, targeting the GSP firmware interface
  • PHY abstractions in the networking subsystem — safe wrappers around network PHY operations
  • NVMe driver abstractions — early Rust bindings for the NVMe block device layer
  • rust/kernel crate — the core safe abstraction layer, continuously expanded with each release

Toolchain Requirements

Building a Rust-enabled kernel requires a specific nightly rustc version pinned in the rust-toolchain.toml at the root of the kernel tree. The kernel does not track stable Rust yet — it uses unstable compiler features (primarily for const generics and inline assembly). This is expected to stabilise as the required features land in stable Rust.

bash
# Install the pinned Rust toolchain for kernel development
rustup override set $(cat rust-toolchain.toml | grep channel | cut -d'"' -f2)
rustup component add rust-src rustfmt clippy
cargo install --locked bindgen-cli

# Verify everything is in order
make LLVM=1 rustavailable
# Should print: Rust is available!

Implications for Sysadmins

For most Linux system administrators, the day-to-day impact is currently minimal — Rust kernel code is opt-in and not required for standard distributions. However, distribution kernels will increasingly ship with Rust-compiled components as the ecosystem matures. Understanding the change matters for:

  • Custom kernel builds: you will encounter Rust toolchain requirements sooner or later
  • Security posture: Rust drivers will have structurally fewer memory-safety CVEs — factor this into your patch cadence expectations
  • Driver development: if your team writes out-of-tree drivers, Rust is becoming a viable (and in some cases preferred) option
  • Long-term hiring: kernel contributors with Rust skills are increasingly in demand

The Linux kernel's adoption of Rust is one of the most significant architectural decisions in the project's 30-year history. It will not happen overnight — millions of lines of C are not going anywhere soon — but the trajectory is clear. New subsystems and drivers will increasingly be written in Rust, making the kernel measurably safer with each release.