Core VCPU Implementation
Relevant source files
Purpose and Scope
This document covers the core virtual CPU implementation centered around the RISCVVCpu
struct and its fundamental operations. The RISCVVCpu
serves as the primary abstraction for executing RISC-V guest virtual machines within the ArceOS hypervisor framework, handling register state management, guest execution control, and hypervisor interactions.
For detailed information about VCPU creation and lifecycle management, see VCPU Lifecycle and Management. For SBI call processing and hypercall handling, see SBI Interface and Hypercalls. For VM exit event processing, see VM Exit Processing.
Core Data Structures
The VCPU implementation is built around several key data structures that manage virtual CPU state and execution context:
RISCVVCpu Structure
The main RISCVVCpu<H: AxVCpuHal>
struct src/vcpu.rs(L23 - L27) encapsulates all virtual CPU state:
Field | Type | Purpose |
---|---|---|
regs | VmCpuRegisters | Complete guest register state including GPRs, CSRs, and trap context |
sbi | RISCVVCpuSbi | SBI interface implementation for handling supervisor binary interface calls |
_marker | PhantomData | Type marker for hardware abstraction layer integration |
SBI Integration Structure
The RISCVVCpuSbi
struct src/vcpu.rs(L29 - L33) implements the RustSBI interface using the #[derive(RustSBI)]
macro, providing automatic forwarding for standard SBI extensions including console, PMU, fence, reset, info, and HSM operations.
Configuration Structures
The system defines two configuration types:
VCpuConfig
src/vcpu.rs(L18 - L19) - Architecture-dependent configuration (currently empty)RISCVVCpuCreateConfig
src/lib.rs(L29 - L36) - Creation-time configuration including hart ID and device tree address
Architecture Overview
The following diagram illustrates the core VCPU architecture and its relationship to key code entities:
flowchart TD subgraph subGraph3["External Assembly Interface"] RunGuest["_run_guest()Assembly Entry Point"] TrapHandler["Trap Handlingtrap.S"] end subgraph subGraph2["Internal Implementation Methods"] VmexitHandler["vmexit_handler()VM Exit Processing"] AdvancePc["advance_pc()PC Manipulation"] GetGpr["get_gpr()Register Access"] SetGpr["set_gpr_from_gpr_index()Register Modification"] end subgraph subGraph1["AxArchVCpu Trait Implementation"] NewMethod["new()VCPU Creation"] SetupMethod["setup()CSR Configuration"] RunMethod["run()Guest Execution"] BindMethod["bind()Memory Binding"] SetEntryMethod["set_entry()Entry Point Setup"] SetEptRootMethod["set_ept_root()Page Table Root"] end subgraph subGraph0["RISCVVCpu Core Structure"] RISCVVCpu["RISCVVCpu<H>Main VCPU Implementation"] VmCpuRegisters["VmCpuRegistersComplete Register State"] RISCVVCpuSbi["RISCVVCpuSbiSBI Interface Handler"] end RISCVVCpu --> BindMethod RISCVVCpu --> NewMethod RISCVVCpu --> RISCVVCpuSbi RISCVVCpu --> RunMethod RISCVVCpu --> SetEntryMethod RISCVVCpu --> SetEptRootMethod RISCVVCpu --> SetupMethod RISCVVCpu --> VmCpuRegisters RunGuest --> TrapHandler RunMethod --> RunGuest RunMethod --> VmexitHandler TrapHandler --> VmexitHandler VmexitHandler --> AdvancePc VmexitHandler --> GetGpr VmexitHandler --> SetGpr
Sources: src/vcpu.rs(L23 - L164)
VCPU State Management
The VCPU maintains comprehensive state through the VmCpuRegisters
structure, which includes guest general-purpose registers, control and status registers, and trap context information.
Register Access Interface
The VCPU provides controlled access to guest registers through dedicated methods:
flowchart TD subgraph subGraph1["Internal Storage"] GuestRegs["guest_regs.gprsGeneralPurposeRegisters"] VirtualCSRs["virtual_hs_csrsHypervisor CSRs"] TrapCSRs["trap_csrsTrap Context"] end subgraph subGraph0["Register Access Methods"] GetGpr["get_gpr(GprIndex)Read Guest Register"] SetGprIndex["set_gpr_from_gpr_index()Write by GprIndex"] SetGprOffset["set_gpr(usize, usize)Write by Offset"] end GetGpr --> GuestRegs GuestRegs --> TrapCSRs GuestRegs --> VirtualCSRs SetGprIndex --> GuestRegs SetGprOffset --> GuestRegs
Sources: src/vcpu.rs(L129 - L153)
Execution Control Flow
The VCPU execution follows a structured pattern that integrates with the hypervisor's execution model:
Core Execution Cycle
sequenceDiagram participant HostHypervisor as "Host/Hypervisor" participant RISCVVCpurun as "RISCVVCpu::run()" participant _run_guest as "_run_guest()" participant vmexit_handler as "vmexit_handler()" HostHypervisor ->> RISCVVCpurun: Call run() RISCVVCpurun ->> RISCVVCpurun: Setup interrupts (sie) RISCVVCpurun ->> _run_guest: _run_guest(&mut regs) _run_guest ->> _run_guest: Execute guest code _run_guest ->> vmexit_handler: VM Exit occurs vmexit_handler ->> vmexit_handler: Read trap CSRs vmexit_handler ->> vmexit_handler: Process exit reason vmexit_handler ->> RISCVVCpurun: Return AxVCpuExitReason RISCVVCpurun ->> RISCVVCpurun: Cleanup interrupts RISCVVCpurun ->> HostHypervisor: Return exit reason
Sources: src/vcpu.rs(L92 - L111) src/vcpu.rs(L167 - L308)
Integration with ArceOS Framework
The VCPU implements the AxArchVCpu
trait src/vcpu.rs(L42 - L142) providing standardized interfaces for:
Method | Purpose | Key Operations |
---|---|---|
new() | VCPU creation | Initialize registers, set hart ID and DTB address |
setup() | Configuration | ConfiguresstatusandhstatusCSRs |
set_entry() | Entry point | Set guest program counter (sepc) |
set_ept_root() | Memory setup | Configure hypervisor guest address translation (hgatp) |
bind() | Memory binding | Activate guest page tables and invalidate TLB |
run() | Execution | Execute guest code and handle VM exits |
Hardware Abstraction Layer Integration
The VCPU uses a generic type parameter H: AxVCpuHal
src/vcpu.rs(L23) to integrate with hardware abstraction layers, enabling platform-specific optimizations while maintaining a consistent interface.
Sources: src/vcpu.rs(L42 - L142) src/lib.rs(L18 - L20)
Memory Management Integration
The VCPU integrates with the ArceOS address space management through several key mechanisms:
Extended Page Table Support
The set_ept_root()
method src/vcpu.rs(L87 - L90) configures the hgatp
CSR with an Sv48 page table format (mode 8) and the physical page number of the root page table, enabling two-stage address translation for guest memory access.
Memory Binding Operations
The bind()
and unbind()
methods src/vcpu.rs(L113 - L126) manage the activation and deactivation of guest address spaces, including TLB invalidation through hfence_gvma_all()
to ensure memory consistency.