QuantaVirt Architecture Guide

QV-ARCH-001 Rev 1.0 — January 2026

Deep technical reference for the QuantaVirt hypervisor internals. Covers the boot sequence, Intel VMX and AMD SVM execution engines, extended/nested page tables, vCPU scheduling, IOMMU, device emulation, interrupt routing, and the PQC subsystem architecture. Intended for developers extending QuantaVirt and engineers evaluating the platform's security properties.

Architecture Overview #

QuantaVirt is a Type 1 (bare-metal) hypervisor that runs directly on physical hardware without a host operating system. The hypervisor kernel manages CPU virtualization, memory, I/O, and the PQC subsystem. Guest VMs execute in hardware-isolated environments provided by Intel VMX or AMD SVM extensions.

LayerComponentResponsibility
Ring -1 (VMX Root / SVM Host)Hypervisor KernelVM management, scheduling, memory management, trap handling, device emulation
Ring 0 (VMX Non-Root / SVM Guest)Guest KernelGuest OS kernel execution within hardware-enforced isolation
Ring 3 (VMX Non-Root)Guest UserspaceGuest applications, completely transparent virtualization
Management PlaneCLI / API / GUIVM lifecycle, configuration, monitoring, PQC operations
PQC PlanePQC Subsystem + QUAC 100Cryptographic operations, key management, QRNG, attestation

Source Tree Layout

quantavirt/
├── boot/                    # Bootloaders (BIOS stage1/stage2, UEFI stub, Multiboot2)
├── hypervisor/
│   ├── arch/x86_64/
│   │   ├── vmx/             # Intel VMX engine (VMCS, VM-entry/exit, posted interrupts)
│   │   ├── svm/             # AMD SVM engine (VMCB, AVIC, decode assists)
│   │   ├── ept/             # Intel Extended Page Tables
│   │   ├── npt/             # AMD Nested Page Tables
│   │   ├── iommu/           # VT-d and AMD-Vi drivers
│   │   └── nested/          # Nested virtualization (L2 guest support)
│   ├── core/
│   │   ├── vm/              # VM and vCPU management (vm.h, vcpu.h)
│   │   ├── sched/           # Scheduler (credit, credit2, RT)
│   │   ├── mm/              # Physical memory manager, hugepages
│   │   └── irq/             # Interrupt controller emulation (LAPIC, IOAPIC, MSI)
│   └── devices/
│       ├── virtio/          # VirtIO devices (blk, net, gpu, console)
│       ├── pci/             # PCI/PCIe bus emulation
│       ├── storage/         # AHCI, NVMe, IDE controllers
│       ├── net/             # e1000/e1000e emulation
│       └── usb/             # XHCI USB 3.0 controller
├── pqc/                     # Post-Quantum Cryptography subsystem
│   ├── include/pqc/
│   │   ├── crypto.h         # Unified PQC API
│   │   └── quac100.h        # QUAC 100 hardware driver
│   ├── src/
│   │   ├── mlkem/           # ML-KEM implementations
│   │   ├── mldsa/           # ML-DSA implementations
│   │   ├── symmetric/       # AES-GCM, ChaCha20-Poly1305
│   │   └── quac100/         # Hardware driver, DMA engine, key storage
│   └── security/            # SEV-SNP, TDX, attestation
├── tools/
│   ├── quantavirt-cli/      # Rust CLI (Cargo workspace)
│   ├── quantavirt-gui/      # Tauri/Svelte GUI
│   └── quantavirt-api/      # REST/gRPC management daemon
└── configs/                 # Example VM configurations, JSON schemas

Boot Sequence #

QuantaVirt supports two boot paths: legacy BIOS via a custom two-stage bootloader, and UEFI via an EFI stub application. Both paths converge at the Multiboot2 entry point where the hypervisor kernel initializes.

BIOS Boot Path

StageFileModePurpose
Stage 1boot/bios/stage1.asmReal Mode (16-bit)MBR bootstrap — loads Stage 2 from disk, sets up A20 gate
Stage 2boot/bios/stage2.asmProtected → Long ModeE820 memory map, GDT setup, transition to 64-bit, load kernel
Kernel Entryhypervisor/entry.asmLong Mode (64-bit)Parse Multiboot2 info, initialize BSP, call kmain()

UEFI Boot Path

StageFileModePurpose
UEFI Appboot/uefi/main.cLong Mode (64-bit)EFI application — get memory map, GOP framebuffer, exit boot services
Kernel Entryhypervisor/entry.asmLong Mode (64-bit)Same entry point as BIOS path, Multiboot2 info structure

Kernel Initialization Sequence

OrderSubsystemFunctionDescription
1Consoleconsole_init()Early serial + VGA console for boot messages
2Memorymm_init()Physical page allocator from E820/UEFI memory map, hugepage pool
3CPU Detectioncpu_detect()CPUID enumeration, VMX/SVM capability check, feature detection
4Interruptsidt_init()IDT setup, exception handlers, LAPIC initialization
5IOMMUiommu_init()VT-d/AMD-Vi discovery from ACPI DMAR/IVRS tables
6PCIpci_enumerate()PCIe bus scan, BAR assignment, QUAC 100 detection
7VMX/SVMvmx_init() / svm_init()Enable virtualization extensions, allocate per-CPU VMXON regions / host save areas
8PQCpqc_init()Initialize PQC subsystem, detect QUAC 100, setup command rings
9Schedulersched_init()Initialize vCPU scheduler (Credit2 default)
10APIapi_init()Start management API listener (Unix socket or TCP)

Intel VMX Execution Engine #

The VMX engine manages VM execution on Intel processors using Virtual Machine Control Structures (VMCS). Each vCPU has a dedicated 4 KB VMCS region that controls VM-entry and VM-exit behavior, guest/host state, and execution controls.

VMCS Layout

VMCS RegionKey FieldsPurpose
Guest State AreaCR0, CR3, CR4, RSP, RIP, RFLAGS, segment registers, GDTR, IDTR, MSRsComplete guest CPU state loaded on VM-entry, saved on VM-exit
Host State AreaCR0, CR3, CR4, RSP, RIP, segment selectors, GDTR, IDTR, MSRsHypervisor CPU state loaded on VM-exit
VM-Execution ControlsPin-based, Processor-based (Primary + Secondary), VM-entry, VM-exitControl which operations cause VM-exits
VM-Exit InformationExit reason, exit qualification, guest-linear/physical address, interruption infoDescribes why a VM-exit occurred
EPTPEPT pointer (PML4 base), memory type, page-walk lengthRoot of extended page table hierarchy
VPIDVirtual Processor Identifier (16-bit)TLB tagging to avoid flushes on VM transitions

VM-Execution Control Bits

ControlBitQuantaVirt DefaultEffect
External-interrupt exitingPin[0]SetExternal interrupts cause VM-exit (routed to hypervisor)
NMI exitingPin[3]SetNMIs handled by hypervisor
Virtual NMIsPin[5]SetNMI window tracking via virtual-NMI blocking
Posted interruptsPin[7]Set (if available)Inject interrupts without VM-exit via posted interrupt descriptor
HLT exitingProc[7]SetGuest HLT traps to scheduler (yields vCPU time)
RDTSC exitingProc[12]ClearGuest RDTSC executes natively (TSC offsetting used instead)
CR3-load exitingProc[15]Clear (EPT)Not needed with EPT — guest manages own CR3 freely
Use MSR bitmapsProc[28]SetSelective MSR exit control via 4 KB bitmaps
Enable EPTProc2[1]SetExtended Page Tables for guest-physical → host-physical translation
Enable VPIDProc2[5]SetTLB tagging avoids full flush on VM-entry/exit
Unrestricted guestProc2[7]SetGuest can run in real mode and unpaged protected mode
APIC register virt.Proc2[8]Set (if available)LAPIC register accesses handled without VM-exit
Virtual-interrupt deliveryProc2[9]Set (if available)Interrupt injection without VM-exit

VM-Entry / VM-Exit Flow

/* Simplified VMX lifecycle — see hypervisor/arch/x86_64/vmx/ for full implementation */

// 1. VM-Entry: transition from hypervisor to guest
vmcs_load(vcpu->vmcs);                     // VMPTRLD — activate this vCPU's VMCS
vmcs_write(GUEST_RSP, vcpu->regs.rsp);     // Load guest registers into VMCS
vmcs_write(GUEST_RIP, vcpu->regs.rip);
vmlaunch() / vmresume();                    // Enter VMX non-root mode
// ... guest executes natively on hardware ...

// 2. VM-Exit: hardware transitions back to hypervisor
uint32_t exit_reason = vmcs_read(VM_EXIT_REASON);
uint64_t exit_qual   = vmcs_read(EXIT_QUALIFICATION);

switch (exit_reason) {
    case EXIT_REASON_EPT_VIOLATION:     handle_ept_violation(exit_qual); break;
    case EXIT_REASON_IO_INSTRUCTION:    handle_pio(exit_qual);          break;
    case EXIT_REASON_MSR_READ:          handle_rdmsr(vcpu);             break;
    case EXIT_REASON_MSR_WRITE:         handle_wrmsr(vcpu);             break;
    case EXIT_REASON_CPUID:             handle_cpuid(vcpu);             break;
    case EXIT_REASON_HLT:              sched_yield(vcpu);               break;
    case EXIT_REASON_EXTERNAL_INT:      handle_interrupt();              break;
    case EXIT_REASON_VMCALL:            handle_hypercall(vcpu);          break;
    // ... ~70 exit reasons total ...
}

// 3. Re-enter guest (loop back to VM-Entry)

AMD SVM Execution Engine #

The SVM engine manages VM execution on AMD processors using Virtual Machine Control Blocks (VMCB). The VMCB is a 4 KB page-aligned structure containing the control area (offsets 0x000–0x3FF) and the state save area (offsets 0x400–0xFFF).

VMCB Structure

AreaOffset RangeKey FieldsPurpose
Control Area0x000 – 0x3FFIntercept vectors, IOPM/MSRPM base, ASID, TLB control, event injection, N_CR3, AVICConfigures which guest operations trap to hypervisor
State Save Area0x400 – 0xFFFES–GS selectors/bases/limits, GDTR, IDTR, CR0–CR4, RSP, RIP, RFLAGS, DR6/7, all MSRsComplete guest state saved/restored on VMRUN/VMEXIT

SVM Intercept Controls

InterceptOffsetQuantaVirt DefaultEffect
CR0 write0x000[0]Set (selective)Trap guest CR0 writes for mode change tracking
IOIO0x004[0]Set + IO BitmapPort I/O intercepted selectively via IO Permission Map
MSR0x004[1]Set + MSR BitmapSelective MSR interception via MSR Permission Map
HLT0x004[8]SetGuest HLT yields to scheduler
CPUID0x004[10]SetCPUID interception for feature masking
VMRUN0x004[16]SetRequired — trap nested VMRUN for nested virt support
VMMCALL0x004[17]SetHypercall interface for PV guests
NPT fault—AutomaticNested page fault generates #VMEXIT with nested fault info

AVIC (Advanced Virtual Interrupt Controller)

On AMD EPYC 7002+ (Rome) and later, QuantaVirt enables AVIC for interrupt virtualization. AVIC provides hardware-accelerated virtual LAPIC access and interrupt injection, reducing VM-exit frequency for interrupt-heavy workloads. The AVIC backing page is a 4 KB page containing the virtual APIC state, mapped into the VMCB control area at offset 0x070.

Memory Virtualization #

QuantaVirt uses hardware-assisted two-dimensional paging — Intel EPT and AMD NPT — to translate guest-physical addresses (GPA) to host-physical addresses (HPA) without shadow page tables. This provides isolation between VMs and between VMs and the hypervisor.

EPT / NPT Page Table Structure

LevelIntel NameAMD NameBits IndexedPage Size
4 (PML4)EPT PML4NPT PML4GPA[47:39]—
3 (PDPT)EPT PDPTNPT PDPGPA[38:30]1 GB (huge page)
2 (PD)EPT PDNPT PDGPA[29:21]2 MB (large page)
1 (PT)EPT PTNPT PTGPA[20:12]4 KB (standard)

EPT Entry Format (64-bit)

BitsFieldDescription
0ReadAllow read access to this page
1WriteAllow write access to this page
2ExecuteAllow instruction fetch from this page
5:3Memory Type0=UC, 1=WC, 4=WT, 5=WP, 6=WB
6Ignore PATIgnore guest PAT for memory type selection
7Large Page1 = this entry maps a large page (2 MB at PD level, 1 GB at PDPT)
8AccessedHardware sets on access (if enabled)
9DirtyHardware sets on write (if enabled)
10Execute (user)Allow execute for user-mode pages (mode-based execute)
N:12Physical AddressHPA of next-level table or mapped physical page (4 KB aligned)
63Suppress #VESuppress virtualization exceptions for this page

Memory Management APIs

/* From hypervisor/core/vm/vm.h */

/* Add a memory region to a VM (backed by host physical pages) */
int vm_add_memory_region(struct vm *vm,
                         uint64_t gpa_base,    /* Guest physical address start */
                         uint64_t size,         /* Region size in bytes */
                         uint32_t flags);       /* VM_MEM_READ | VM_MEM_WRITE | VM_MEM_EXEC */

/* Translate guest-physical to host-virtual address */
void *vm_gpa_to_hva(struct vm *vm, uint64_t gpa);

/* Read/write guest memory from hypervisor context */
int vm_read_memory(struct vm *vm, uint64_t gpa, void *buf, size_t len);
int vm_write_memory(struct vm *vm, uint64_t gpa, const void *buf, size_t len);

vCPU Scheduler #

QuantaVirt includes three vCPU scheduling algorithms. The scheduler maps virtual CPUs to physical CPUs, handles preemption, and manages NUMA-aware placement. The default scheduler is Credit2.

SchedulerTypeBest ForKey Properties
CreditProportional fair-shareServer consolidation, mixed workloadsWeight-based CPU allocation, soft affinity, automatic load balancing across pCPUs
Credit2Proportional fair-share (v2)General purpose (default)Improved fairness, runqueue-per-pCPU, NUMA-aware migration, better latency characteristics
RTReal-time priorityLatency-critical workloadsFixed-priority scheduling, budget enforcement, dedicated pCPU reservation

Scheduler Configuration

# Set scheduler at boot via kernel parameter
sched=credit2

# Per-VM scheduler weight (higher = more CPU time)
quantavirt vm set ubuntu-server --cpu-weight 256    # Default: 256, range: 1–65535

# Per-VM CPU cap (maximum % of one pCPU)
quantavirt vm set ubuntu-server --cpu-cap 0         # 0 = no cap, 100 = one full pCPU

# CPU pinning (bind vCPUs to specific pCPUs)
quantavirt vm set ubuntu-server --cpu-pin 0:2,1:3   # vCPU0→pCPU2, vCPU1→pCPU3

# NUMA node affinity
quantavirt vm set ubuntu-server --numa-node 0       # Prefer NUMA node 0

IOMMU Subsystem #

The IOMMU subsystem provides DMA remapping for device isolation and PCI passthrough. QuantaVirt discovers IOMMU hardware via ACPI tables: DMAR (DMA Remapping) for Intel VT-d and IVRS (I/O Virtualization Reporting Structure) for AMD-Vi.

FeatureIntel VT-dAMD-Vi
DMA Remapping✅ Per-device page tables✅ Per-device page tables
Interrupt Remapping✅ Interrupt Remapping Table✅ Interrupt Virtualization Table
ATS (Address Translation Services)✅ PCIe ATS support✅ PRI + PPR support
Pass-through GranularityPer-functionPer-function
DiscoveryACPI DMAR tableACPI IVRS table

Device Model #

QuantaVirt's device model provides emulated and paravirtualized hardware to guest VMs. Devices connect to the guest via an emulated PCI Express topology with MMIO and PIO BAR access trapped through EPT/NPT violations and I/O exit handling.

VirtIO Architecture

VirtIO devices follow the VirtIO 1.1 specification using the modern MMIO transport. Each VirtIO device consists of a device-specific configuration space, one or more virtqueues (split or packed), and a notification mechanism. The guest driver and hypervisor device backend communicate through shared memory rings (virtqueues) with doorbell notifications.

DeviceVirtIO IDQueuesBackendMax Throughput
VirtIO-blk2Multi-queue (1 per vCPU)AIO on raw/qcow2/encrypted~1M IOPS (raw, multi-queue)
VirtIO-net1Multi-queue (RX+TX per vCPU)vhost-user / vhost-net / userspace~40 Gbps (vhost-user)
VirtIO-GPU16controlq, cursorq, 3D queuesVirgl (3D) / Software (2D)60 fps @ 1080p (Virgl)
VirtIO-console3RX+TX per portPTY / stdio / socket~100 MB/s

Interrupt Routing #

QuantaVirt emulates the x86 interrupt architecture: dual 8259A PIC (legacy), IOAPIC, and per-vCPU LAPIC. Modern guests use MSI/MSI-X for device interrupts, which bypass the IOAPIC entirely and are delivered directly to the target vCPU's LAPIC.

MechanismSourcePathPerformance
Legacy IRQ (PIC)Emulated legacy devicesDevice → PIC → LAPIC → Guest IDTLowest (VM-exit per interrupt)
IOAPICEmulated PCI devicesDevice → IOAPIC → LAPIC → Guest IDTMedium (VM-exit per interrupt)
MSI/MSI-XVirtIO / PCIe devicesDevice → write to LAPIC MMIO → Guest IDTHigh (may avoid VM-exit with APICv/AVIC)
Posted Interrupts (Intel)External / IPIPosted Interrupt Descriptor → Guest IDTHighest (no VM-exit)
AVIC (AMD)External / IPIAVIC backing page → Guest IDTHighest (no VM-exit)

PQC Subsystem Architecture #

The PQC subsystem is integrated at the hypervisor kernel level, providing cryptographic services to all other subsystems: migration, storage, attestation, and secure boot. The subsystem abstracts over two backends: software (portable, always available) and QUAC 100 hardware (high-performance, requires PCIe card).

PQC API (crypto.h)

/* Backend selection */
typedef enum {
    CRYPTO_BACKEND_SOFTWARE = 0,   /* Validated software implementation */
    CRYPTO_BACKEND_QUAC100  = 1,   /* QUAC 100 hardware acceleration */
    CRYPTO_BACKEND_AUTO     = 2    /* Auto-detect: QUAC 100 if present, else software */
} crypto_backend_t;

/* ML-KEM Key Encapsulation */
int mlkem512_keygen(uint8_t *pk, uint8_t *sk);      /* pk=800B, sk=1632B */
int mlkem512_encaps(const uint8_t *pk, uint8_t *ct, uint8_t *ss);  /* ct=768B, ss=32B */
int mlkem512_decaps(const uint8_t *sk, const uint8_t *ct, uint8_t *ss);

int mlkem768_keygen(uint8_t *pk, uint8_t *sk);      /* pk=1184B, sk=2400B */
int mlkem768_encaps(const uint8_t *pk, uint8_t *ct, uint8_t *ss);  /* ct=1088B, ss=32B */
int mlkem768_decaps(const uint8_t *sk, const uint8_t *ct, uint8_t *ss);

int mlkem1024_keygen(uint8_t *pk, uint8_t *sk);     /* pk=1568B, sk=3168B */
int mlkem1024_encaps(const uint8_t *pk, uint8_t *ct, uint8_t *ss); /* ct=1568B, ss=32B */
int mlkem1024_decaps(const uint8_t *sk, const uint8_t *ct, uint8_t *ss);

/* ML-DSA Digital Signatures */
int mldsa44_keygen(uint8_t *pk, uint8_t *sk);       /* pk=1312B, sk=2560B */
int mldsa44_sign(const uint8_t *sk, const uint8_t *msg, size_t mlen, uint8_t *sig); /* sig=2420B */
int mldsa44_verify(const uint8_t *pk, const uint8_t *msg, size_t mlen, const uint8_t *sig);

int mldsa65_keygen(uint8_t *pk, uint8_t *sk);       /* pk=1952B, sk=4032B */
int mldsa65_sign(const uint8_t *sk, const uint8_t *msg, size_t mlen, uint8_t *sig); /* sig=3293B */
int mldsa65_verify(const uint8_t *pk, const uint8_t *msg, size_t mlen, const uint8_t *sig);

int mldsa87_keygen(uint8_t *pk, uint8_t *sk);       /* pk=2592B, sk=4896B */
int mldsa87_sign(const uint8_t *sk, const uint8_t *msg, size_t mlen, uint8_t *sig); /* sig=4595B */
int mldsa87_verify(const uint8_t *pk, const uint8_t *msg, size_t mlen, const uint8_t *sig);

/* Symmetric / Hash / KDF */
int crypto_aead_encrypt(int alg, const uint8_t *key, ...);  /* AES-256-GCM or ChaCha20-Poly1305 */
int crypto_aead_decrypt(int alg, const uint8_t *key, ...);
int crypto_sha3_256(const uint8_t *in, size_t inlen, uint8_t *out);
int crypto_sha3_512(const uint8_t *in, size_t inlen, uint8_t *out);
int crypto_hkdf(const uint8_t *ikm, size_t ikmlen, ...);
int crypto_random_bytes(uint8_t *buf, size_t len);  /* QRNG if available */

For QUAC 100 hardware details including the register map, command/response ring protocol, and DMA engine, see PQC & Security — QUAC 100 Register Map.

Confidential Computing #

QuantaVirt supports hardware-based confidential computing to protect VM memory from the hypervisor itself. This provides defense-in-depth where even a compromised hypervisor cannot read guest secrets.

TechnologyVendorProtectionMinimum CPUQuantaVirt Status
SEV (Secure Encrypted Virtualization)AMDAES-128 memory encryption per VMEPYC 7001 (Naples)✅ GA
SEV-ES (Encrypted State)AMDSEV + encrypted register state on VM-exitEPYC 7002 (Rome)✅ GA
SEV-SNP (Secure Nested Paging)AMDSEV-ES + integrity protection, attestationEPYC 7003 (Milan)⚠️ Beta
TDX (Trust Domain Extensions)IntelEncrypted memory + attestation for Trust DomainsXeon 4th Gen (Sapphire Rapids)⚠️ Beta

Error Codes #

Hypervisor Error Codes

CodeNameDescription
0QV_SUCCESSOperation completed successfully
-1QV_ERR_NOMEMInsufficient memory for allocation
-2QV_ERR_INVALInvalid argument or parameter
-3QV_ERR_NODEVDevice not found or not available
-4QV_ERR_BUSYResource is busy or locked
-5QV_ERR_PERMPermission denied
-6QV_ERR_EXISTResource already exists
-7QV_ERR_NOENTResource not found (VM, device, etc.)
-8QV_ERR_IOI/O error during device or storage operation
-9QV_ERR_VMENTRYVM-entry failed (check VMCS/VMCB consistency)
-10QV_ERR_VMEXITUnhandled VM-exit reason

PQC Error Codes

CodeNameDescription
0PQC_SUCCESSCryptographic operation completed successfully
-100PQC_ERR_INVALID_KEYInvalid key material (wrong size, corrupt)
-101PQC_ERR_VERIFY_FAILSignature verification failed
-102PQC_ERR_DECAPS_FAILKEM decapsulation failed
-103PQC_ERR_AEAD_FAILAEAD decryption/authentication failed
-104PQC_ERR_RNG_FAILRandom number generation failed (QRNG health check)
-105PQC_ERR_NO_BACKENDNo PQC backend available
-200QUAC100_ERR_TIMEOUTQUAC 100 command timed out
-201QUAC100_ERR_RING_FULLCommand ring full — too many pending operations
-202QUAC100_ERR_DMADMA transfer error
-203QUAC100_ERR_KEY_SLOTKey slot operation failed (full, locked, not found)
-204QUAC100_ERR_FWFirmware error on QUAC 100