4. ARM虚拟化硬件支持

在 Xen ARM 平台移植中,虚拟化能力并非完全由 Hypervisor 软件“模拟”出来,而是依赖 ARM 处理器提供的硬件虚拟化扩展。理解这些扩展,是判断一块 SoC 能否高效运行 Xen、以及如何配置启动流程的前提。本节围绕 ARMv7/v8 虚拟化扩展、EL2 异常级别、Stage-2 地址转换、GIC 虚拟化和 SMMU 五个核心机制展开,它们共同构成 Xen on ARM 的硬件基石。

一、ARMv7 与 ARMv8 虚拟化扩展的差异

ARMv7 的虚拟化扩展(Virtualization Extensions)首次引入 HYP 模式,使 Hypervisor 可以运行在比内核更高的特权级。它主要面向 32 位系统,配合 Large Physical Address Extension(LPAE)实现第二阶段地址转换。ARMv8-A 则将虚拟化能力系统化,引入 AArch64 与 AArch32 两种执行状态,并把异常级别从传统的 7 种模式重构为 EL0~EL3 四级模型。Xen 在 ARMv8 上通常运行于 EL2,Guest OS 运行于 EL1,用户态应用运行于 EL0,而安全固件(如 ARM Trusted Firmware)运行于 EL3。

对移植工作而言,关键区别在于:ARMv7 需要检查是否具备 HYP 模式与 LPAE,ARMv8 则需要确认 EL2 是否可用、是否被安全固件正确移交。若芯片启动时停留在 EL3 或 EL1,Xen 将无法获得虚拟化控制权。

二、EL2 异常级别与启动移交

EL2 是 Xen 在 ARMv8 上的运行级别,它拥有对 Stage-2 转换、虚拟中断注入和部分系统寄存器的控制权。典型启动链路为:BL1/BL2(EL3)→ BL31(EL3 安全监控)→ BL33(U-Boot,EL2 或 EL1)→ Xen(EL2)→ Dom0 内核(EL1)。移植时最常见的问题是 U-Boot 把 CPU 降到了 EL1,导致 Xen 启动时读取 CurrentEL 发现不是 EL2,从而报错退出。

# 在 Xen 启动早期确认当前异常级别
mrs x0, CurrentEL
cmp x0, #(2 << 2)      // EL2 对应值
b.ne  panic_not_el2

# U-Boot 中可强制以 EL2 启动
setenv bootargs "console=ttyAMA0"
booti 0x40000000 - 0x44000000
若 U-Boot 运行在 EL2,执行 booti 进入 Xen 时仍保持 EL2;若 U-Boot 自身运行在 EL1,则需通过 PSCI 或 ATF 重新进入 EL2,否则 Xen 无法启动。

三、Stage-2 地址转换:虚拟化的内存隔离核心

ARM 虚拟化采用两阶段地址转换。Stage-1 由 Guest OS 控制,把虚拟地址(VA)转换为中间物理地址(IPA);Stage-2 由 Xen 控制,把 IPA 转换为真实物理地址(PA)。这样 Guest 看到的“物理地址”并非真实内存,Xen 通过 Stage-2 页表即可实现内存隔离、气球回收和设备直通映射。

Stage-2 转换由 VTTBR_EL2 指向的页表基址驱动,配合 VTCR_EL2 配置页粒度、IPA 位宽和内存属性。Xen 为每个 Domain 维护独立的 Stage-2 页表,当发生 Stage-2 缺页时,会触发 hypervisor 异常并由 Xen 决定映射或拒绝。

ARM 两阶段地址转换与虚拟化硬件支持 Guest 应用 EL0 / VA Guest OS EL1 / Stage-1 Xen Hypervisor EL2 / Stage-2 真实物理内存 PA GIC 虚拟化 vGIC / 中断注入 SMMU DMA 重映射 虚拟中断 IPA → PA Stage-2 映射 设备 DMA 隔离 关键寄存器与页表: VTTBR_EL2 → Stage-2 页表基址 | VTCR_EL2 → 页粒度 / IPA 位宽 / 内存属性 ICH_* / GICV / GICH → 虚拟中断控制 | SMMU_S2CR / SMMU_CB → 流表与上下文

四、GIC 虚拟化与中断注入

GIC(Generic Interrupt Controller)虚拟化让 Guest 可以直接管理自己的中断,而无需每次陷入 Xen。以 GICv2 为例,硬件提供 GICV(虚拟 CPU 接口)和 GICH(虚拟接口控制)两组寄存器;GICv3/v4 则通过 ICH_* 系统寄存器与 List Registers 实现。Xen 负责把物理中断映射为虚拟中断号,并通过维护 LR(List Register)把中断注入到 Guest 的 vCPU。

移植时需重点关注:GIC 版本是否与 Xen 配置匹配、中断号映射是否正确、以及 Dom0 的设备树中 interrupt-parent 与 interrupt-cells 是否准确。若 GIC 虚拟化未启用,Guest 将频繁陷入 EL2,性能显著下降。

五、SMMU:让 DMA 也受虚拟化约束

CPU 的内存访问受 Stage-2 页表约束,但设备通过 DMA 直接访问物理内存时,若不加限制就会绕过隔离。SMMU(System MMU)为设备提供地址转换与隔离能力,它使用流表(Stream Table)和上下文描述符(Context Descriptor)把设备 ID 映射到对应的 Stage-2 页表。Xen 在直通设备给 Guest 时,必须配置 SMMU 使设备 DMA 只能访问该 Guest 的 IPA 范围。

机制 作用 关键寄存器/结构 移植检查点
EL2 异常级别 Xen 运行特权级 CurrentEL、HCR_EL2 启动时是否处于 EL2
Stage-2 转换 IPA 到 PA 隔离映射 VTTBR_EL2、VTCR_EL2 页表基址与位宽配置
GIC 虚拟化 虚拟中断注入 GICV/GICH、ICH_LR GIC 版本与中断映射
SMMU 设备 DMA 隔离 Stream Table、S2CR 流表与设备 ID 匹配

六、常见误区与复盘

  • 误区一:认为只要 CPU 支持 ARMv8 就一定能跑 Xen。实际上还需 EL2 未被禁用、GICv2/v3 可用、内存控制器支持 Stage-2 页表格式。
  • 误区二:忽略 U-Boot 的异常级别。很多开发板默认从 EL1 启动,需在 ATF 或 U-Boot 中显式切换到 EL2。
  • 误区三:设备直通时只配置 Stage-2 而忘记 SMMU,导致设备 DMA 越界访问,系统随机崩溃。
  • 复盘建议:移植前先用 cat /proc/cpuinfo 和 ATF 日志确认 EL 级别与 GIC 版本,再检查设备树中 interrupt-parent、iommus 属性是否完整。
在 ARMv7 平台上,若未启用 LPAE,Stage-2 转换将无法使用 40 位物理地址,Xen 可能只能以 32 位模式运行,限制 Guest 内存大小。移植前务必确认 CONFIG_ARM_LPAE 与硬件支持情况。

综上,ARM 虚拟化硬件支持是一个从异常级别、地址转换、中断控制到设备隔离的完整体系。Xen 在 ARM 上的移植质量,很大程度上取决于对这些硬件机制的识别与正确配置。只有把 EL2、Stage-2、GIC 虚拟化和 SMMU 串联起来理解,才能在启动工程中快速定位“为什么起不来”和“为什么跑不快”这两类核心问题。