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_idfield 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
Dropimplementation 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
percpucrate 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
Dropimplementation for proper shutdown src/percpu.rs(L97 - L103)