arm_vgic
路径:
virtualization/arm_vgic类型:库 crate 分层:组件层 / 可复用基础组件 版本:0.2.1文档依据:Cargo.toml、README.md、src/lib.rs、src/vgic.rs、src/vgicd.rs、src/interrupt.rs、src/devops_impl.rs、src/consts.rs、src/registers.rs、src/vtimer/*、src/v3/*
arm_vgic 是 ARM 虚拟中断控制器相关组件集合。它既包含面向 guest 的 GIC MMIO 设备实现,也包含虚拟定时器系统寄存器设备,以及可选的 GICv3 透传/窗口模型。它不是完整的“所有中断虚拟化逻辑都在这里”的单体,而是与 arm_vcpu、axvm、axdevice、axvisor_api 明确分工的组件。
架构设计
设计定位
arm_vgic 的职责可以概括为“两类虚拟设备 + 一层状态建模”:
- 一类是 guest 可见的 GIC MMIO 设备窗口,如
Vgic、VGicD、VGicR、Gits。 - 一类是 guest 可见的系统寄存器设备,如虚拟物理定时器
CNTP_*设备。 - 中间层则是软件维护的中断元数据、寄存器解码和若干宿主 GIC 访问/屏蔽逻辑。
但它 不 完整负责:
- vCPU 进入/退出生命周期,这属于
arm_vcpu。 - 虚拟中断最终注入执行,这一动作已由
arm_vcpu/axvisor_api承担。 - 全量 GIC 寄存器行为建模,当前实现范围明显小于 README 中较强的宣传语。
模块结构
src/lib.rs:crate 入口与按 feature 导出,统一api_reexp的宿主 GIC / 注入接口。src/vgic.rs:精简 GICv2 风格 MMIO 设备主对象Vgic。src/vgicd.rs:GIC distributor 软件状态,维护Vgicd、VgicInt与若干寄存器读写行为。src/interrupt.rs:中断元数据定义,包括中断类型、状态与 enable/trigger 属性。src/registers.rs:大量 GICD 偏移到GicRegister的地址解码表。src/devops_impl.rs:为Vgic实现BaseDeviceOps,把 guest MMIO 访问映射到读写方法。src/consts.rs:VGIC 相关常量、向量边界和寄存器偏移。src/vtimer/*:虚拟定时器系统寄存器设备,包括CNTP_CTL_EL0、CNTPCT_EL0、CNTP_TVAL_EL0。src/v3/*:GICv3 路径,实现VGicD、VGicR、Gits及其 MMIO 辅助逻辑。
1.3 关键数据结构与对象
Vgic:对外最直接的 GIC MMIO 设备对象,内部持有Mutex<Vgicd>。Vgicd:保存 distributor 核心状态,如ctrlr、typer、iidr和一组VgicInt。VgicInt/Interrupt:每个虚拟中断的元数据,包括 enable、status、priority、trigger、vcpu 等。GicRegister:寄存器地址解码结果,用于把 guest MMIO 地址映射到软件处理逻辑。VGicD/VGicR/Gits:vgicv3feature 下的 GICv3 设备实现。SysCntpCtlEl0、SysCntpctEl0、SysCntpTvalEl0:虚拟定时器系统寄存器设备。
1.4 设备建模与访问主线
GICv2 风格 Vgic
Vgic 的读写主线大致如下:
当前实现里:
GicdCtlr、GicdTyper、GicdIidr、Isenabler等少量寄存器有明确行为。- 大量寄存器枚举虽然已 经定义,但尚未完全落到真实行为分支里。
GICv3 路径
启用 vgicv3 后,VGicD / VGicR / Gits 提供的是一种“带掩码的宿主窗口”模型:
VGicD会维护assigned_irqs位图,只允许 guest 访问被分配的 SPI。VGicR面向每个 vCPU 暴露 GICR 窗口。Gits负责 ITS/LPI 相关窗口,但当前实现仍带有明显的场景限制和 TODO。
1.5 虚拟中断注入与 vCPU 的分工
这是阅读 arm_vgic 时最容易误解的地方:
arm_vgic负责 设备建模 和 寄存器/状态管理。- 真正的“把某个虚拟中断注入到正在运行的 guest vCPU”动作,当前已经迁到
arm_vcpu,通过axvisor_api::arch::hardware_inject_virtual_interrupt()执行。 vtimer是一个例外中的例外:它在定时器到期回调里会直接请求注入 PPI 30,这是一条系统寄存器设备主动触发注入的路径。
因此,这个 crate 更像“虚拟 GIC 设备层”,而不是“完整的虚拟中断执行层”。