kvm-bindings

Rust FFI bindings to the Linux KVM API, auto-generated with bindgen for x86_64, arm64, and riscv64

Library
Cargo
v0.14.1
435stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
65/100Good
Development Activity40
Maintenance52
Community88
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
69/100Good
Architecture74
Code Quality78
Innovation68
Learning Curve55

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-wrappers feature providing safe FamStructWrapper types over flexible-array-member structs like kvm_cpuid2 and kvm_msrs
  • Optional serde feature for serializing raw KVM structs as opaque, ABI-stable binary blobs via zerocopy, 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-ioctls safe-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.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search