Implementation Details

Relevant source files

This document covers the core implementation systems that enable VCPU functionality in the axvcpu crate, focusing on the supporting infrastructure for virtualization state management and hardware abstraction. This includes the per-CPU virtualization state management system and the hardware abstraction layer that interfaces with the underlying host system.

For detailed information about VCPU lifecycle management and architecture abstraction, see Core VCPU Management. For specific exit handling mechanisms, see Exit Handling System.

Implementation Architecture Overview

The axvcpu implementation is built on two primary supporting systems that work together to provide a foundation for virtualization:

flowchart TD
subgraph subGraph2["Host System Integration"]
    ADDRSPACE["axaddrspaceAddress Space Management"]
    ERRNO["axerrnoError Handling"]
    PERCPU_LIB["percpuPer-CPU Variables"]
end
subgraph subGraph1["Implementation Infrastructure"]
    PERCPU["AxPerCpuPer-CPU State Manager"]
    HAL["AxVCpuHalHardware Abstraction"]
    ARCH_PERCPU["AxArchPerCpuArchitecture Per-CPU Trait"]
end
subgraph subGraph0["VCPU Management Layer"]
    VCPU["AxVCpuVCPU Manager"]
    EXIT["AxVCpuExitReasonExit Handler"]
end

HAL --> ADDRSPACE
PERCPU --> ARCH_PERCPU
PERCPU --> ERRNO
PERCPU --> PERCPU_LIB
VCPU --> HAL
VCPU --> PERCPU

Implementation Infrastructure Architecture

The implementation consists of two main abstraction layers:

ComponentPurposeKey Functions
AxPerCpuManages per-CPU virtualization stateinit(),hardware_enable(),hardware_disable()
AxVCpuHalHardware abstraction for memory and interruptsalloc_frame(),phys_to_virt(),irq_fetch()
AxArchPerCpuArchitecture-specific per-CPU operationsnew(),is_enabled(), hardware control

Sources: src/percpu.rs(L1 - L104)  src/hal.rs(L1 - L55) 

Per-CPU State Management System

The per-CPU state management system provides a generic wrapper around architecture-specific virtualization state, ensuring proper initialization and cleanup across different CPU architectures:

flowchart TD
subgraph subGraph1["Architecture Implementation"]
    ARCH_NEW["A::new(cpu_id)"]
    ARCH_ENABLE["A::hardware_enable()"]
    ARCH_DISABLE["A::hardware_disable()"]
    ARCH_CHECK["A::is_enabled()"]
end
subgraph subGraph0["Per-CPU State Lifecycle"]
    UNINIT["AxPerCpu::new_uninit()Uninitialized State"]
    INIT["init(cpu_id)Initialize Architecture State"]
    ENABLED["hardware_enable()Virtualization Active"]
    DISABLED["hardware_disable()Cleanup on Drop"]
end

DISABLED --> ARCH_DISABLE
ENABLED --> ARCH_CHECK
ENABLED --> ARCH_ENABLE
ENABLED --> DISABLED
INIT --> ARCH_NEW
INIT --> ENABLED
UNINIT --> INIT

Per-CPU State Management Flow

The AxPerCpu<A> struct provides a type-safe wrapper that:

Sources: src/percpu.rs(L40 - L95) 

Hardware Abstraction Layer

The AxVCpuHal trait defines the interface between the VCPU system and the underlying host system, abstracting memory management and interrupt handling:

flowchart TD
subgraph subGraph1["Host System Services"]
    FRAME_ALLOC["Frame Allocator"]
    ADDR_TRANS["Address Translation"]
    IRQ_SYSTEM["Interrupt Controller"]
end
subgraph subGraph0["AxVCpuHal Interface"]
    ALLOC["alloc_frame()→ Option"]
    DEALLOC["dealloc_frame(paddr)Frame Cleanup"]
    P2V["phys_to_virt(paddr)→ HostVirtAddr"]
    V2P["virt_to_phys(vaddr)→ HostPhysAddr"]
    IRQ_FETCH["irq_fetch()→ usize"]
    IRQ_HANDLER["irq_handler()Dispatch to Host"]
end

ALLOC --> FRAME_ALLOC
DEALLOC --> FRAME_ALLOC
IRQ_FETCH --> IRQ_SYSTEM
IRQ_HANDLER --> IRQ_SYSTEM
P2V --> ADDR_TRANS
V2P --> ADDR_TRANS

Hardware Abstraction Layer Interface

The HAL provides essential services for VCPU operation:

FunctionReturn TypePurpose
alloc_frame()OptionAllocate physical memory frame
dealloc_frame(paddr)()Release physical memory frame
phys_to_virt(paddr)HostVirtAddrConvert physical to virtual address
virt_to_phys(vaddr)HostPhysAddrConvert virtual to physical address
irq_fetch()usizeGet current interrupt number
irq_handler()()Dispatch interrupt to host

Sources: src/hal.rs(L4 - L54) 

Integration and Usage Patterns

The implementation components work together through well-defined integration patterns:

sequenceDiagram
    participant Hypervisor as "Hypervisor"
    participant AxPerCpuA as "AxPerCpu<A>"
    participant AxArchPerCpuImpl as "AxArchPerCpu Impl"
    participant AxVCpuHal as "AxVCpuHal"
    participant HostSystem as "Host System"

    Note over Hypervisor,HostSystem: Initialization Phase
    Hypervisor ->> AxPerCpuA: new_uninit()
    Hypervisor ->> AxPerCpuA: init(cpu_id)
    AxPerCpuA ->> AxArchPerCpuImpl: new(cpu_id)
    AxArchPerCpuImpl ->> AxVCpuHal: alloc_frame() (if needed)
    AxVCpuHal ->> HostSystem: allocate memory
    AxPerCpuA ->> AxArchPerCpuImpl: hardware_enable()
    Note over Hypervisor,HostSystem: Runtime Phase
    Hypervisor ->> AxPerCpuA: is_enabled()
    AxPerCpuA ->> AxArchPerCpuImpl: is_enabled()
    Hypervisor ->> AxVCpuHal: phys_to_virt(addr)
    AxVCpuHal ->> HostSystem: address translation
    Note over Hypervisor,HostSystem: Cleanup Phase
    Hypervisor ->> AxPerCpuA: Drop
    AxPerCpuA ->> AxArchPerCpuImpl: hardware_disable()
    AxArchPerCpuImpl ->> AxVCpuHal: dealloc_frame() (if needed)
    AxVCpuHal ->> HostSystem: release memory

Implementation Integration Sequence

The recommended usage pattern involves:

  1. Static Definition: Using the percpu crate to define per-CPU state src/percpu.rs(L27 - L28) 
  2. Initialization: Calling init() and hardware_enable() during hypervisor startup src/percpu.rs(L34 - L38) 
  3. Runtime Access: Using arch_checked() and arch_checked_mut() for safe access src/percpu.rs(L68 - L79) 
  4. Automatic Cleanup: Relying on the Drop implementation for proper shutdown src/percpu.rs(L97 - L103) 

Sources: src/percpu.rs(L21 - L39)  src/hal.rs(L1 - L55)