3. IOMMU核心概念
IOMMU(Input/Output Memory Management Unit)位于设备与系统内存之间,是设备直通、虚拟化和安全隔离的硬件基石。它把“设备发出的DMA地址”翻译成“系统物理地址”,同时把设备中断安全地投递到目标CPU或虚拟机。理解IOMMU,必须抓住六个关键词:DMA重映射、中断重映射、地址空间、页表、域与设备表,以及它与MMU的本质区别。
一、核心原理:IOMMU在数据通路上做了什么
在没有IOMMU的系统中,设备驱动把物理地址直接写入设备寄存器,设备发起DMA时直接访问该物理地址。这带来三个问题:设备只能使用物理地址、恶意或缺陷设备可越界访问任意内存、虚拟机无法安全地把设备分配给客户机。
IOMMU引入后,设备发出的地址先经过IOMMU翻译。设备看到的是IOVA(I/O Virtual Address),IOMMU依据页表把它转换为系统物理地址(SPA/PA)。因此,DMA重映射的本质是“为设备建立一套独立的地址视图”,让设备像进程一样拥有自己的虚拟地址空间。
中断重映射则解决另一条通路:设备产生MSI/MSI-X中断时,写入的是中断地址和数据。IOMMU的中断重映射表(IRTE)会校验并重定向该中断,把它映射到指定CPU向量,甚至直接投递到某个虚拟机的虚拟APIC,从而避免中断被伪造或误投。
二、地址空间、页表、域与设备表
IOMMU的地址空间由页表定义。与MMU类似,IOMMU页表也是多级结构,常见为4级或5级,每级索引若干位,最终得到物理页帧号。不同之处在于,IOMMU页表由系统软件(内核或Hypervisor)为设备建立,设备本身不参与页表管理。
域(Domain)是IOMMU的隔离单位。一个域拥有一套页表,域内设备共享同一地址视图;不同域之间默认不可互访。设备表(Device Table)则把“设备标识符(BDF,Bus/Device/Function)”映射到域ID。这样,当设备发起DMA时,IOMMU先根据BDF查设备表找到域,再用该域的页表翻译地址。
中断重映射表(IRTE)与设备表配合工作。每个设备的中断请求会携带源ID,IOMMU据此查找IRTE,决定该中断是否允许、投递到哪个CPU、使用哪个向量。对于虚拟化场景,IRTE还可以把中断直接注入客户机,减少Hypervisor介入。
| 概念 | 作用 | 关键数据结构 | 典型使用场景 |
|---|---|---|---|
| DMA重映射 | 把设备IOVA翻译为物理地址 | IOMMU页表 | 设备直通、驱动使用虚拟地址 |
| 中断重映射 | 校验并重定向MSI/MSI-X中断 | IRTE | 中断隔离、虚拟中断注入 |
| 域 | 定义隔离边界与共享地址空间 | Domain结构 | 多设备分组、VM隔离 |
| 设备表 | 由BDF索引到域 | Device Table Entry | 设备发现与归属管理 |
| 页表 | 描述IOVA到PA的映射与权限 | 多级页表 | 地址翻译、读写权限控制 |
三、IOMMU与MMU的区别
MMU服务于CPU,翻译的是“进程虚拟地址 → 物理地址”,页表由操作系统为进程维护,切换进程时切换页表基址。IOMMU服务于设备,翻译的是“设备IOVA → 物理地址”,页表由内核或Hypervisor为设备/域维护,切换域时切换页表根。
两者都做地址翻译和权限检查,但触发者、地址来源、页表管理者和故障处理路径不同。MMU缺页会触发CPU异常,由操作系统处理;IOMMU翻译失败通常产生DMA故障,由IOMMU驱动记录并上报,严重时可能隔离设备或触发内核告警。
一句话区分:MMU让CPU进程以为自己独占内存;IOMMU让设备以为自己独占内存。前者保护进程,后者保护系统与虚拟机。
四、案例与场景:设备直通中的一次DMA
假设一台虚拟机需要使用直通网卡。Hypervisor先为网卡创建IOMMU域,建立客户机物理地址到主机物理地址的页表,并把网卡BDF写入设备表指向该域。网卡驱动在客户机内分配缓冲区,得到客户机物理地址,Hypervisor将其映射为IOVA并写入网卡寄存器。
网卡发起DMA,IOMMU根据BDF找到域,用页表把IOVA翻译为主机物理地址,完成数据写入。若网卡试图访问未映射地址,IOMMU会阻止并记录故障,避免破坏主机或其他虚拟机。中断路径上,网卡MSI写入被IRTE重定向到客户机vCPU,实现中断直通。
# 查看IOMMU分组与设备归属(Linux示例)
for g in /sys/kernel/iommu_groups/*; do
echo "IOMMU Group ${g##*/}:"
for d in $g/devices/*; do
echo -e "\t$(lspci -nns ${d##*/})"
done
done
# 典型日志:DMA翻译失败
DMAR: [DMA Read] Request device [03:00.0] fault addr 0xfffff000
DMAR: DRHD: handling fault status reg 3
五、误区与复盘
- 误区一:开启IOMMU一定更安全。若使用宽松映射或直通整个域,隔离效果会下降;必须结合设备分组和最小权限页表。
- 误区二:IOMMU页表就是MMU页表。两者格式可能相似,但归属、生命周期和故障路径不同,不能混用同一套管理逻辑。
- 误区三:中断重映射可有可无。在虚拟化直通中,没有中断重映射,MSI中断可能无法正确投递或被恶意设备伪造。
- 复盘要点:排障时先确认设备BDF、域ID、页表映射和IRTE四项是否一致,再检查DMA故障日志与中断统计。
工程建议:为每个直通设备建立独立域,页表只映射必要区域;启用中断重映射并校验源ID;在Hypervisor中记录DMA故障地址与设备BDF,便于快速定位越界访问。