x86_vcpu
路径:
virtualization/x86_vcpu类型:库 crate 分层:组件层 / x86 虚拟 CPU 后端 版本:0.2.2文档依据:当前仓库源码、Cargo.toml、README.md、src/lib.rs、src/vmx/*、src/regs/*
x86_vcpu 是 Axvisor 所依赖的 ArceOS Hypervisor 体系中面向 x86_64 的架构后端,实现了基于 Intel VT-x/VMX 和 AMD SVM 的 vCPU 执行引擎。它实现 axvm-types 给出的架构协议接口,并把 PIO、APIC、MSR、EPT/NPT 等 x86 语义保留在本 crate 内部,统一生命周期和运行循环由 axvm 负责。
架构设计
设计定位
该 crate 的职责可以概括为三点:
- 实现 x86_64 架构下的
VmArchVcpuOps - 实现每物理 CPU 的 VMX 启停逻辑
- 将 VMX/SVM exit 原因翻译成
axvm-types::VmExit
它不承担:
- VM 生命周期管理
- 访客内存布局组织
- 通用设备模型管理
- 调度多个 VM/vCPU 的系统级策略
这些职责分别位于 axvm、axaddrspace、axdevice、os/axvisor 等更高层。
模块结构
| 模块 | 作用 | 关键内容 |
|---|---|---|
lib.rs | feature 入口和公共导出 | 选择 vmx 路径、导出 VmxArchVCpu、has_hardware_support |
vmx/vcpu.rs | vCPU 主实现 | VmxVcpu、setup、run、vmexit、注入事件 |
vmx/percpu.rs | 每核 VMX 状态 | VmxPerCpuState、vmxon / vmxoff |
vmx/vmcs.rs | VMCS 访问封装 | 字段读写、控制域配置、exit 信息解析 |
vmx/structs.rs | VMX 内存结构 | VmxRegion、I/O bitmap、MSR bitmap、EPT pointer |
vmx/definitions.rs | 常量与枚举 | exit reason、控制位、事件信息等 |
vmx/instructions.rs | 特权指令辅助 | invept 等 |
regs/ | 通用寄存器布局与保存恢复 | GeneralRegisters 和汇编辅助 |
msr.rs | MSR 常量与访问 | VMX 能力和常见寄存器读写 |
ept.rs | EPT 相关辅助 | GuestPageWalkInfo 等辅助结构 |
1.3 VmxVcpu:核心状态载体
VmxVcpu<H> 是整个 crate 的中心结构。它内部聚合了:
- 客户机通用寄存器
- host 栈顶指针
launched状态vmcs- I/O bitmap
- MSR bitmap
pending_eventsvlapicxstate
其中几个字段的语义特别重要:
vmcs
每个 vCPU 一份 VMCS 区,负责保存:
- guest state
- host state
- execution controls
- exit/entry controls
- EPT pointer
pending_events
用于软件排队待注入的中断/异常事件。真正写入 VM-entry 注入字段发生在运行前的 inject_pending_events() 阶段。
vlapic
类型来自外部依赖 x86_vlapic::EmulatedLocalApic。这说明 LAPIC 虚拟化并不内嵌在本仓库内的独立 crate 中,而是作为外部组件由 x86_vcpu 调用。
xstate
负责 guest/host 间 XSAVE 相关上下文切换,保证启用扩展状态时客户机和宿主机的 XCR0/IA32_XSS 等状态不会互相污染。
1.4 VmxPerCpuState:每核硬件虚拟化开关
VmxPerCpuState 对应 axvm-types::VmArchPerCpuOps。它负责:
- 打开 CR4.VMXE
- 检查 VMX 能力 MSR
- 执行
vmxon - 在退出时
vmxoff
这层设计说明:
- vCPU 是每个虚拟 CPU 的运行实体
- VMX 开关状态是每个物理 CPU 的宿主状态
两者被清晰分离。
1.5 VMCS 配置主线
setup() 的核心就是构建一个可运行的 VMCS。流程大致是:
- 清理和装载 VMCS
- 写 host state
- 写 guest state
- 配置 pin-based / primary / secondary controls
- 安装 I/O bitmap 与 MSR bitmap
- 写入 EPT pointer
- 解绑并保留可供后续运行的状态
这里最关键的控制面包括:
- 使用 I/O bitmap
- 使用 MSR bitmap
- 开启 secondary controls
- 开启 EPT
- 开启 unrestricted guest
它们基本决定了该 vCPU 是一个可运行的现代 VMX 虚拟 CPU,而不是仅做极简演示。
1.6 VM-exit 处理分层
x86_vcpu 的 VM-exit 处理分成两层:
内建处理层
先由 builtin_vmexit_handler() 消化一部分 exit,例如:
- interrupt window
- preemption timer
XSETBV- 某些
CR_ACCESS CPUID- x2APIC 范围内的 MSR 读写
这一层的目标是把“已知且本后端自己能完全解决的 exit”在架构层内消化掉。
协议翻译层
如果 exit 不能在本地完全处理,就继续翻译成 VmExit 上抛给 axvm/VMM,例如:
HypercallIoRead/IoWriteSysRegRead/SysRegWriteExternalInterruptSystemDown
这种两层结构有助于减少高层 VMM 需要理解的 x86/VMX 细节。
1.7 当前实现中的重要边界
有两点需要在文档里明确:
仅 VMX 路径成熟
虽然 Cargo.toml 中声明了:
vmxsvm
但当前源码的完整实现只覆盖 Intel VMX。svm 更像占位 feature,而不是可用的 AMD SVM 后端。
EPT violation 尚未完整上抛
源码中已经有解析 EPT 相关信息的辅助逻辑,但 run() 并没有系统性地把 EPT violation 转换成统一的 NestedPageFault 风格退出。这意味着 x86 嵌套页错误路径在当前版本里还没有像 ARM/RISC-V 那样完全收束到统一协议层。
核心功能
功能概览
- 检测 x86 VMX 硬件支持
- 启用和关闭每核 VMX 状态
- 创建与配置 VMCS
- 运行 vCPU 并处理 VM-exit
- 拦截和转发 I/O、MSR、x2APIC 相关访问
- 注入中断和异常事件
- 维护 guest/host 扩展状态切换
2.2 关键 API 语义
作为 VmArchVcpuOps 实现,它最关键的接口包括:
new()set_entry()set_nested_page_table_root()setup()run()bind()unbind()inject_interrupt()set_return_value()
这些接口共同构成高层 axvm 调用架构后端的最小协议。
2.3 典型运行路径
2.4 与设备虚拟化的连接点
x86_vcpu 自己并不管理完整设备树,但它是若干设备模拟路径的重要入口:
- x2APIC MSR 访问会进入
vlapic - I/O 端口访问会变成
IoRead/IoWrite - 某些 MSR 访问会变成
SysRegRead/SysRegWrite
因此它扮演的是“CPU exit 解码与设备层之间的桥”。