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:
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:
- Tracks initialization state through the
cpu_id
field src/percpu.rs(L42) - Safely manages uninitialized memory using
MaybeUninit<A>
src/percpu.rs(L44) - Provides checked access methods that prevent use before initialization src/percpu.rs(L68 - L79)
- Automatically disables virtualization in the
Drop
implementation src/percpu.rs(L97 - L103)
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:
Function | Return Type | Purpose |
---|---|---|
alloc_frame() | Option | Allocate physical memory frame |
dealloc_frame(paddr) | () | Release physical memory frame |
phys_to_virt(paddr) | HostVirtAddr | Convert physical to virtual address |
virt_to_phys(vaddr) | HostPhysAddr | Convert virtual to physical address |
irq_fetch() | usize | Get 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:
- Static Definition: Using the
percpu
crate to define per-CPU state src/percpu.rs(L27 - L28) - Initialization: Calling
init()
andhardware_enable()
during hypervisor startup src/percpu.rs(L34 - L38) - Runtime Access: Using
arch_checked()
andarch_checked_mut()
for safe access src/percpu.rs(L68 - L79) - Automatic Cleanup: Relying on the
Drop
implementation for proper shutdown src/percpu.rs(L97 - L103)