kvm-bindings
Rust FFI bindings to the Linux KVM API, auto-generated with bindgen for x86_64, arm64, and riscv64
Repository Health
Technical Analysis
kvm-bindings provides raw Rust FFI bindings to the Linux Kernel Virtual Machine (KVM) API, generated directly from kernel header files with bindgen. It is the foundational crate that every rust-vmm hypervisor component — including kvm-ioctls, crosvm, Firecracker, and cloud-hypervisor — builds on to speak KVM’s ioctl-based interface from safe(ish) Rust.
Because the bindings are statically generated against a specific kernel version, the crate also ships optional higher-level conveniences: safe wrappers over KVM’s flexible-array-member (FAM) structs behind the fam-wrappers feature, serde (de)serialization of the raw structs via zerocopy for live-migration and snapshot/restore use cases, and helpers for working with nested virtualization state (VMX/SVM) on x86_64.
What You Get
- Architecture-specific bindgen-generated structs and constants for x86_64, arm64, and riscv64 KVM ioctls
- Optional
fam-wrappersfeature providing safeFamStructWrappertypes over flexible-array-member structs likekvm_cpuid2andkvm_msrs - Optional
serdefeature for serializing raw KVM structs as opaque, ABI-stable binary blobs viazerocopy, enabling live-migration and snapshot workflows - x86_64 nested-virtualization helpers (
KvmNestedStateBuffer) for handling VMX/SVM nested state that varies in shape by CPU vendor - A workspace released in lockstep with the companion
kvm-ioctlssafe-wrapper crate, both versioned and CI-tested together under rust-vmm-ci
Common Use Cases
- Building a custom virtual machine monitor (VMM) or hypervisor userspace in Rust, as Firecracker, crosvm, and cloud-hypervisor do
- Implementing CPUID or MSR configuration for guest VMs using the FAM-struct wrappers instead of manually managing flexible array memory
- Serializing VM/vCPU register and device state for live migration or snapshot/restore between hosts running compatible kernels
- Working with nested virtualization (running a hypervisor inside a KVM guest) and needing typed access to VMX/SVM nested state
Under The Hood
Architecture kvm-bindings is organized as one module per target architecture (src/x86_64, src/arm64, src/riscv64), each re-exported wholesale from lib.rs behind #[cfg(target_arch = "...")] guards, so only the bindings for the compiling architecture are ever built in. Each arch module has a bindgen-generated bindings.rs (the bulk of the crate — nearly 6,000 lines for x86_64 alone) holding raw #[repr(C)] structs and constants mirroring <linux/kvm.h>, plus hand-written companion files layered on top: fam_wrappers.rs wraps flexible-array-member structs like kvm_cpuid2 and kvm_msrs in FamStructWrapper<T> from vmm-sys-util, serialize.rs implements serde (de)serialization as opaque byte blobs via zerocopy, and (on x86_64) nested.rs layers a KvmNestedStateBuffer abstraction over the VMX/SVM union in kvm_nested_state__data. This keeps the auto-generated, unsafe FFI surface strictly separated from the small amount of hand-maintained safe API on top of it.
Tech Stack The crate targets Rust edition 2024 (workspace-inherited) and has no required dependencies — vmm-sys-util, serde, and zerocopy are all optional, gated behind the fam-wrappers and serde Cargo features respectively. It lives in a two-crate Cargo workspace alongside kvm-ioctls (the safe ioctl-wrapper crate built on top of these bindings), with shared CI configuration from the rust-vmm-ci submodule and per-architecture coverage thresholds defined in coverage_config_{aarch64,x86_64}.json. Bindings are regenerated periodically from a pinned upstream Linux kernel version, documented per-release in CHANGELOG.md.
Code Quality Test coverage is concentrated in the hand-written layers (fam_wrappers, serialize, nested) rather than the generated bindings themselves — seven files contain #[test] blocks, and the crate additionally uses bincode/serde_json as dev-dependencies to round-trip serialization in tests. The crate enforces #![deny(clippy::undocumented_unsafe_blocks)] project-wide, requiring every unsafe block (unavoidable given raw FFI structs and unions) to carry a // SAFETY: comment explaining its invariants, which is a notably strict bar for a low-level bindings crate. Generated bindings are explicitly exempted from clippy’s stricter lints via #[allow(clippy::all)] on the bindings module, correctly scoping strictness to only the code humans actually write.
API Design As a bindings crate, the primary API surface is the raw struct/constant set itself, which is inherently low-level and kernel-ABI-shaped rather than ergonomic by design — callers are expected to consult the kernel’s KVM API documentation alongside the crate. The optional fam-wrappers and nested modules meaningfully soften this: FamStructWrapper<T> and KvmNestedStateBuffer give safe, typed handles over structures that would otherwise require manual unsafe pointer arithmetic. Per-item rustdoc is present throughout the hand-written modules (with links to kernel API docs), though the generated bindings.rs itself carries minimal documentation, which is typical for bindgen output and pushes newcomers toward the companion kvm-ioctls crate and Linux KVM API docs for usage context.