iommu-testdev:裸机测试用 IOMMU 设备
概述
iommu-testdev 是仅供测试的最小 PCI 设备,
用于在无需固件或客户机操作系统的情况下测试 ARM SMMUv3 等 IOMMU 地址转换。
测试可填入已知转换表并触发 DMA,使请求经过 IOMMU 转换路径。
它 不是 忠实的 PCIe 端点,应视为 QEMU 内部测试工具。
主要功能
裸机 IOMMU 测试:无需客户机内核或固件。
可配置 DMA 属性:通过 MMIO 配置地址空间。
确定性验证:按已知模式先写后读,自动核对结果。
状态
位置:
hw/misc/iommu-testdev.c头文件:
include/hw/misc/iommu-testdev.h构建开关:
CONFIG_IOMMU_TESTDEV
设备接口
设备提供一个 PCI BAR0,含以下 32 位 MMIO 寄存器:
ITD_REG_DMA_TRIGGERING(0x00):读取触发 DMA,并消费已准备请求。ITD_REG_DMA_GVA_LO(0x04):DMA IOVA 的 [31:0] 位。ITD_REG_DMA_GVA_HI(0x08):DMA IOVA 的 [63:32] 位。ITD_REG_DMA_GPA_LO(0x1C):回读验证所用 GPA 的 [31:0] 位。ITD_REG_DMA_GPA_HI(0x20):回读验证所用 GPA 的 [63:32] 位。ITD_REG_DMA_LEN(0x0C):DMA 传输长度。ITD_REG_DMA_RESULT(0x10):DMA 结果,0 成功,0xffffffff 空闲,0xfffffffe 已准备。ITD_REG_DMA_DBELL(0x14):写 1 准备 DMA,写 0 取消准备。 准备仅标记请求并设置 BUSY,不锁存或检查参数;为 qtest 提供显式控制点, 也为异步执行或锁存留出空间。ITD_REG_DMA_ATTRS(0x18):映射 MemTxAttrs 部分字段的 DMA 属性:位 0:secure,1 为 Secure,0 为 Non-Secure。
位 [2:1]:ArmSecuritySpace,0 为 Secure,1 为 Non-Secure。
位 3:space_valid,1 表示 space 有效,0 则忽略并默认 Non-Secure。 仅设置 space_valid 才使用 MemTxAttrs 的 space。 Secure/Non-Secure 情况下 secure 与 space 必须一致,否则返回 ITD_DMA_ERR_BAD_ATTRS。 其他位保留,未来测试需要额外属性时可接入。
转换设置流程
iommu-testdev 不自行构建 SMMU、AMD-Vi 或 RISC-V IOMMU 结构。
架构专用构造完全在 qtest/libqos 辅助函数中完成:
将页表及架构数据结构填入客户机内存,直接配置仿真 IOMMU 寄存器。
SMMUv3 示例见 tests/qtest/libqos/qos-smmuv3.c 的
qsmmu_setup_and_enable_translation()。
DMA 操作流程
准备语义:
向 DMA_DBELL 写 bit0=1,将请求标记为已准备,并把 DMA_RESULT 设为 BUSY。 不锁存 GVA/LEN/ATTRS,读取 DMA_TRIGGERING 时才采样。
写 bit0=0 取消准备,并将 DMA_RESULT 设为 IDLE。
读取 DMA_TRIGGERING 消费请求并清除准备状态,即使发生错误也如此。
流程拆分为以下步骤,便于时序控制与调试。 qtest 可以分别测试并断言 NOT_ARMED、BAD_LEN、TX/RD 失败、数据不匹配等路径, 而非将所有副作用隐藏在单一步骤中:
测试配置 IOMMU 转换表。
配置 DMA IOVA(GVA_LO/HI)、回读 GPA、长度和属性。
向 DMA_DBELL 写 1 准备操作。
读取 DMA_TRIGGERING 执行 DMA。
轮询 DMA_RESULT:
0x00000000:成功。
0xFFFFFFFE:已准备,等待触发。DMA 同步运行,触发读取结束后看不到 BUSY。
0xDEAD0006:属性错误,S/NS 的 secure 与 space 不一致。
0xDEAD000X:其他错误码。
设备以已知模式 0x12345678 先写后读,自动验证数据完整性。
运行 qtest
SMMUv3 测试套件使用此设备,覆盖多种转换模式:
cd build
QTEST_QEMU_BINARY=./qemu-system-aarch64 \\
./tests/qtest/iommu-smmuv3-test --tap -k
覆盖以下场景:
仅阶段 1 转换。
仅阶段 2 转换。
嵌套转换,即阶段 1 加阶段 2。
实例化
设备默认不接入任何开发板,测试通过命令行实例化:
-device iommu-testdev
使用 SMMUv3 的 ARM 平台:
-M virt,iommu=smmuv3 -device iommu-testdev
IOMMU 位于同一 PCI 根复合体 pci.0 时,设备自动置于其后。 其他 PCI 拓扑需显式指定总线。
限制
不提供真实 PCIe 枚举、MSI/MSI-X 或中断处理。
不支持 ATS/PRI。
除 DMA 测试模式外没有实际设备功能。
仅供测试,不适合生产或逼真机器仿真。
Secure/Root/Realm 地址空间支持取决于架构,并由 space_valid 控制。
回读使用配置的 GPA,经系统内存访问,避免再次经过 IOMMU。
另见
tests/qtest/iommu-smmuv3-test.c:SMMUv3 测试套件。tests/qtest/libqos/qos-smmuv3.{c,h}:SMMUv3 测试库。SMMUv3 仿真:
hw/arm/smmu*。