Skip to content

Hypervisor Decisions ​

Three decisions that define RumKV's minimal design philosophy.

See also: Rumpk vs. RumKV for a detailed comparison of the kernel and hypervisor.

H1: Type-1 Hypervisor ​

Status: Accepted

Context ​

Type-1 hypervisors run directly on hardware (Xen, VMware ESXi). Type-2 hypervisors run inside a host OS (VirtualBox, KVM on Linux). Nexus claims sovereignty — no hidden host OS underneath. If the system runs on Linux, it's a Linux system with Nexus characteristics, not a sovereign system.

Decision ​

RumKV is a bare-metal Type-1 hypervisor:

  • Boots before any guest OS
  • Holds highest hardware privilege (EL2 / Ring -1 / M-Mode)
  • Assigns CPU cores, memory ranges, and devices to cells via page tables
  • < 5 KB active code — minimal by any standard
  • Then delegates and mostly sleeps

Alternatives Rejected ​

OptionWhy Not
Type-2 on Linux (KVM)Requires Linux kernel as host; surrenders sovereignty to Linux security model
Bare-metal single OS (no hypervisor)No isolation between services; one fault cascades to entire system
seL4 as hypervisorDesigned for Type-1 but heavier than RumKV's spatial-only model
XenFeature-rich but 1M+ LOC; too complex for formal reasoning

Consequences ​

  • Complete hardware control (no hidden host OS surface)
  • Cells are truly isolated (no shared kernel state between guests)
  • Can run air-gapped systems (no Internet-connected host needed)
  • Must port RumKV to each hardware platform (RISC-V, ARM64, x86_64)
  • Device sharing requires explicit passthrough configuration

H2: Dual-Pledge Enforcement ​

Status: Accepted

Context ​

Single-layer security enforcement creates a single point of failure. If the kernel is compromised, all bets are off. Defense-in-depth is a well-established principle, but most systems implement it as "multiple software checks" — which all fail if the software is compromised. Hardware-backed enforcement survives software compromise.

Decision ​

Two independent enforcement layers operating simultaneously:

Layer 1: Hard Pledges (RumKV — hardware) ​

  • Mechanism: Stage-2 page tables + SMMU/IOMMU
  • Enforcement: Immediate cell termination on violation
  • Example: Cell pledges "compute only" → RumKV unmaps all network and disk controllers from Stage-2 tables. Even a compromised kernel inside that cell cannot address the network card.

Layer 2: Soft Pledges (Rumpk — software) ​

  • Mechanism: Capability tokens, energy budgets, pledge declarations
  • Enforcement: Fiber termination, resource throttling
  • Example: Fiber pledges "stdio rw" → kernel denies network capability requests

The One-Way Ratchet ​

Both layers enforce a monotonic narrowing rule: a cell/fiber can only tighten its pledges via hypercall/syscall. It can never loosen them. A compromised workload that tries to re-enable network access gets terminated.

Alternatives Rejected ​

OptionWhy Not
Hypervisor-only enforcementKernel can circumvent software policies within the cell
Kernel-only enforcementNo protection if kernel is compromised
Single trusted layerNo defense-in-depth; one exploit = full access

Consequences ​

  • Kernel compromise doesn't enable cell breakout (hypervisor still enforces hardware boundaries)
  • Individual cell compromise can't reach other cells
  • Root-equivalent privilege inside a cell is still insufficient for cell escape
  • Hypervisor debugging is harder (no kernel symbols, minimal logging at EL2)
  • Pledge design must be careful to avoid false positives that terminate legitimate workloads

H3: Spatial-Only Partitioning ​

Status: Accepted

Context ​

Most hypervisors time-share CPU cores between guests (KVM, Xen). This maximizes utilization but introduces scheduling jitter — a guest may be preempted mid-operation, causing unpredictable latency. For deterministic systems (aerospace, industrial control, financial), jitter is unacceptable.

Decision ​

RumKV assigns cores statically at boot. No time-sharing at the hypervisor level.

Boot time assignment (example: 8-core system):
  Cell A (Rumpk primary): Cores 0-3
  Cell B (NetBSD guest):  Cores 4-5
  Cell C (Compute cell):  Cores 6-7
  • Assignments are permanent for the system's lifetime
  • Each cell's kernel schedules its own fibers on assigned cores
  • RumKV never preempts a cell to give time to another
  • Hypervisor is idle except for faults, interrupts, and hypercalls

Alternatives Rejected ​

OptionWhy Not
Oversubscription (KVM-style)Flexible but nondeterministic; context switch latency at hypervisor level
Dynamic load balancingRequires hypervisor involvement every few ms; violates Silence Doctrine
Asymmetric (some shared, some static)Hard to reason about; partial determinism is worse than none

Consequences ​

  • Deterministic scheduling: No hypervisor preemption jitter. Period.
  • Cell A can't steal cores from Cell B (spatial isolation = temporal isolation)
  • Hypervisor is mostly idle (minimal power drain, minimal attack surface)
  • Unused cores in idle cells are wasted (cannot help overloaded cells)
  • Core allocation must be planned at deployment time (no runtime adjustment)
  • Total core count limits the number of cells (no overcommit)

When Spatial-Only Is Not Enough ​

For dynamic cloud workloads where utilization matters more than determinism, Nexus Fleet profiles use a different strategy: multiple Rumpk cells with RumKV spatial partitioning, but with the Kinetic Economy providing soft resource sharing within each cell's core allocation. This gives deterministic inter-cell boundaries with flexible intra-cell scheduling.


H4: Anti-God-Structure Doctrine for MMU-Adjacent Code ​

Status: Accepted Date: 2026-07-28 Origin: Linux 7.3 "KVM Chainsaw" — Paolo Bonzini's split of kvm_mmu into kvm_pagewalk / kvm_mmu / kvm_page_format. Canonical source: Nexus/.agents/specs/SPEC-709-H4-ANTI-GOD-STRUCTURE-MMU-DOCTRINE.md (internal SPEC; this ADR is the public rendering).

Context ​

KVM's kvm_mmu accreted three distinct responsibilities over 15 years:

  1. Format description — what bits mean in a PTE.
  2. Page-table walking — traversing guest page tables (root_mmu, nested_mmu).
  3. Page-table building — constructing shadow PTEs.

The same struct also had to describe L1 and L2 guests (nested virt), reused sub-fields across guest/host tables in some cases and replaced them in others, and physically moved the walker between contexts mid-flight. The "nested_mmu" name predates guest_mmu and now produces comments like "Exempt nested MMUs" that actually exempt guest_mmu. The Chainsaw series retires the debt by splitting into three structs, merges the permission-mask machinery with the existing reserved-bits validator, and uses the new shape to enable memory-attribute features (XS≠XU SPTE support) that the god structure blocked.

Audit of RumKV Today ​

RumKV does not have this debt. The x86_64 VMX stack is already split by responsibility: primitives, Stage-2 tables, orchestration, exit dispatch, hypercalls, allocator, host paging. No nested_mmu analogue, no per-vCPU walker farm (spatial-only partitioning means one guest per static core), and no software shadow-PTE builder (the CPU hardware-walks EPT). The closest fused implementation is the EPT stage-2 table code; for a single-purpose Stage-2 table with no L2 nesting, this is the right granularity today.

Decision ​

Three rules apply to all current and future MMU-adjacent RumKV code. They lock in the clean shape and prevent KVM-style debt.

H4.1 — Three concerns stay separate (or stay small). When adding new MMU-adjacent code (memory attributes, EPT-violation PTE inspection, dirty-bit tracking, A/D-bit management, nested virt if ever introduced), the three concerns stay in three structs: a *_format for bit meanings and reserved-bit validators, a *_walker for traversal, and a *_builder for table construction. A file may fuse them only if it has no nested-virt concern and no per-vCPU state.

H4.2 — Verbs over roles. Name walkers by what they walk, not by which context they currently belong to. gva_walk over nested_walker. ept_format over mmu_format. build_shadow over mmu_builder. Role names (nested_*, root_*, mmu_*) are poison pills.

H4.3 — One walker per vCPU, static lifetime. If nested virt is ever added, each vCPU owns its walkers for the guest's lifetime. The walker never moves between contexts; it reads the current VMCS to decide what to walk.

When H4 Becomes Active ​

H4 is inert doctrine today — RumKV has no MMU-adjacent code that needs the split. The day any of the following lands, the doctrine becomes active and the SPEC reserves the right to split the current fused implementation:

  1. Memory attributes / NX-bit granularity / XS≠XU semantics are added.
  2. EPT-violation handlers inspect the offending guest PTE.
  3. Nested virt is added (a guest that itself runs guests) — even a research prototype.
  4. A second walker type appears for the same vCPU.
  5. The current fused implementation grows beyond a soft size threshold (per SPEC-709).

Alternatives Rejected ​

OptionWhy not
Refactor now into three structsYAGNI — there is no feature today that needs the split. Pre-emptive splits are speculative architecture.
Reuse KVM's kvm_page_format / kvm_pagewalk / kvm_mmu namesDifferent ontology. We use domain-native names; KVM's shadow-PTE semantics don't transfer.
Wait until a refactor is forcedKVM waited 15 years and had to retrofit. We don't have the debt yet — adopt the doctrine now so we don't acquire it.

Cross-references ​

  • H1 (Type-1 hypervisor), H3 (spatial-only partitioning) — together define why RumKV doesn't have KVM's MMU god struct today.
  • KVM Chainsaw patch series, Linux 7.3 merge window (2026-08 back half) — origin of the doctrine.
  • SPEC-709 (internal) — full audit checklist, reserved names, trigger conditions, MR-checkbox audit procedure.