Per-CPU VMX State
Relevant source files
This document covers the per-CPU VMX (Virtual Machine Extensions) state management system, which handles processor-specific initialization, enablement, and disablement of Intel's VMX virtualization technology. This system ensures that each CPU core in a multi-processor system can independently manage its VMX capabilities while maintaining proper hardware validation and state tracking.
For information about VMCS field management and virtual machine control structures, see VMCS Field Management. For details about VMX data structures like VmxRegion, see VMX Data Structures.
VmxPerCpuState Structure
The VmxPerCpuState<H: AxVCpuHal> struct serves as the central management entity for VMX state on individual processor cores. It maintains the essential components needed for VMX operation including hardware compatibility information and memory regions.
flowchart TD
subgraph subGraph2["Hardware Abstractions"]
AxVCpuHal["AxVCpuHal traitHardware abstraction layer"]
VmxRegionImpl["VmxRegion implementation4KB aligned memory"]
end
subgraph subGraph1["AxArchPerCpu Trait Implementation"]
NewMethod["new(cpu_id: usize)Initialize per-CPU state"]
IsEnabled["is_enabled()Check VMX status"]
HwEnable["hardware_enable()Enable VMX on CPU"]
HwDisable["hardware_disable()Disable VMX on CPU"]
end
subgraph subGraph0["VmxPerCpuState Structure"]
VmxPerCpu["VmxPerCpuState<H>"]
RevisionId["vmcs_revision_id: u32VMCS compatibility identifier"]
VmxRegion["vmx_region: VmxRegion<H>Memory region for VMXON"]
end
VmxPerCpu --> HwDisable
VmxPerCpu --> HwEnable
VmxPerCpu --> IsEnabled
VmxPerCpu --> NewMethod
VmxPerCpu --> RevisionId
VmxPerCpu --> VmxRegion
VmxRegion --> VmxRegionImpl
VmxRegionImpl --> AxVCpuHal
Sources: src/vmx/percpu.rs(L17 - L29)
The structure contains two primary fields:
| Field | Type | Purpose |
|---|---|---|
| vmcs_revision_id | u32 | VMCS revision identifier ensuring software-hardware compatibility |
| vmx_region | VmxRegion | Memory region used for VMXON instruction execution |
Hardware Enable Process
The hardware_enable() method implements a comprehensive VMX initialization sequence that validates hardware support, configures control registers, and executes the VMXON instruction to enter VMX operation mode.
sequenceDiagram
participant Caller as "Caller"
participant VmxPerCpuState as "VmxPerCpuState"
participant CPUHardware as "CPU Hardware"
participant ModelSpecificRegisters as "Model Specific Registers"
participant ControlRegisters as "Control Registers"
Caller ->> VmxPerCpuState: hardware_enable()
VmxPerCpuState ->> CPUHardware: has_hardware_support()
alt No VMX support
CPUHardware -->> VmxPerCpuState: false
VmxPerCpuState -->> Caller: AxError::Unsupported
end
VmxPerCpuState ->> ControlRegisters: Check CR4.VMXE
alt Already enabled
ControlRegisters -->> VmxPerCpuState: VMX enabled
VmxPerCpuState -->> Caller: AxError::ResourceBusy
end
VmxPerCpuState ->> VmxPerCpuState: XState::enable_xsave()
VmxPerCpuState ->> ModelSpecificRegisters: Read FeatureControl MSR
VmxPerCpuState ->> ModelSpecificRegisters: Enable VMXON if unlocked
VmxPerCpuState ->> ModelSpecificRegisters: Validate CR0/CR4 against VMX_FIXED MSRs
alt Invalid control registers
ModelSpecificRegisters -->> VmxPerCpuState: Validation failed
VmxPerCpuState -->> Caller: AxError::BadState
end
VmxPerCpuState ->> ModelSpecificRegisters: Read IA32_VMX_BASIC
VmxPerCpuState ->> VmxPerCpuState: Validate VMX capabilities
VmxPerCpuState ->> VmxPerCpuState: Create VmxRegion with revision_id
VmxPerCpuState ->> ControlRegisters: Set CR4.VMXE
VmxPerCpuState ->> CPUHardware: vmxon(vmx_region.phys_addr())
CPUHardware -->> VmxPerCpuState: Success
VmxPerCpuState -->> Caller: Ok(())
Sources: src/vmx/percpu.rs(L43 - L117)
Hardware Validation Steps
The enable process performs several critical validation steps:
- VMX Support Detection: Verifies CPU supports VMX extensions src/vmx/percpu.rs(L44 - L46)
- Feature Control MSR: Enables VMXON capability in IA32_FEATURE_CONTROL src/vmx/percpu.rs(L55 - L64)
- Control Register Validation: Ensures CR0 and CR4 comply with VMX requirements src/vmx/percpu.rs(L67 - L81)
- VMX Basic Capabilities: Validates memory type, addressing, and control features src/vmx/percpu.rs(L84 - L99)
Control Register Validation
The implementation uses a macro-based approach to validate control registers against VMX fixed MSRs:
flowchart TD
subgraph subGraph1["Control Register Validation"]
CR0["CR0 Register"]
ValidationMacro["cr_is_valid! macro(!fixed0 | value != 0) && (fixed1 | !value != 0)"]
CR4["CR4 Register"]
subgraph subGraph0["VMX Fixed MSRs"]
Fixed0["IA32_VMX_CR0_FIXED0Must be set bits"]
Fixed1["IA32_VMX_CR0_FIXED1Must be clear bits"]
Fixed0_CR4["IA32_VMX_CR4_FIXED0"]
Fixed1_CR4["IA32_VMX_CR4_FIXED1"]
end
end
CR0 --> ValidationMacro
CR4 --> ValidationMacro
Fixed0 --> ValidationMacro
Fixed0_CR4 --> ValidationMacro
Fixed1 --> ValidationMacro
Fixed1_CR4 --> ValidationMacro
Sources: src/vmx/percpu.rs(L67 - L81)
Hardware Disable Process
The hardware_disable() method provides a safe teardown sequence for VMX operation, executing VMXOFF and restoring the processor to non-VMX state.
flowchart TD Start["hardware_disable()"] CheckEnabled["Check is_enabled()"] Error["Return BadState error"] VmxOff["Execute vmxoff instruction"] ClearCR4["Clear CR4.VMXE bit"] UninitRegion["vmx_region = VmxRegion::uninit()"] Success["Return Ok(())"] VmxOffError["Return BadState error"] CheckEnabled --> Error CheckEnabled --> VmxOff ClearCR4 --> UninitRegion Start --> CheckEnabled UninitRegion --> Success VmxOff --> ClearCR4 VmxOff --> VmxOffError
Sources: src/vmx/percpu.rs(L119 - L140)
State Management and Lifecycle
The VmxPerCpuState follows a clear lifecycle pattern that ensures proper resource management and state transitions.
| Method | Purpose | Key Operations |
|---|---|---|
| new() | Initialize uninitialized state | Setsvmcs_revision_idto 0, creates uninitializedVmxRegion |
| is_enabled() | Check current VMX status | Reads CR4.VMXE flag |
| hardware_enable() | Enable VMX on current CPU | Hardware validation, VMXON execution, state setup |
| hardware_disable() | Disable VMX on current CPU | VMXOFF execution, CR4 cleanup, resource deallocation |
Sources: src/vmx/percpu.rs(L31 - L140)
Integration with Hardware Abstraction
The per-CPU VMX state integrates with the broader hardware abstraction system through the AxVCpuHal trait and AxArchPerCpu interface.
flowchart TD
subgraph subGraph1["Hardware Abstraction Integration"]
AxArchPerCpu["AxArchPerCpu traitGeneric per-CPU interface"]
VmxPerCpuImpl["VmxPerCpuState<H>VMX-specific implementation"]
AxVCpuHal["AxVCpuHal traitHardware abstraction layer"]
subgraph Dependencies["Dependencies"]
VmxRegionDep["VmxRegion<H>Memory management"]
FeatureControl["FeatureControl MSRHardware feature control"]
VmxBasic["VmxBasic MSRVMX capabilities"]
HasSupport["has_hardware_support()Hardware detection"]
end
end
AxArchPerCpu --> VmxPerCpuImpl
VmxPerCpuImpl --> AxVCpuHal
VmxPerCpuImpl --> FeatureControl
VmxPerCpuImpl --> HasSupport
VmxPerCpuImpl --> VmxBasic
VmxPerCpuImpl --> VmxRegionDep
VmxRegionDep --> AxVCpuHal
Sources: src/vmx/percpu.rs(L1 - L11) src/vmx/percpu.rs(L31 - L37)
The system leverages several key abstractions:
- AxArchPerCpu: Provides a generic interface for per-CPU architecture-specific state
- AxVCpuHal: Hardware abstraction layer for memory management and physical addressing
- VmxRegion: RAII-managed memory regions for VMX operations
This design enables the VMX per-CPU state to operate independently on each processor core while maintaining consistent interfaces for higher-level hypervisor components.