SPEC
Feature
iommucap
register
- S bit: 支持 2-stage 地址翻译
- A bit: 支持 AIA
- MRF: 支持 imsic 的 MRF 模式
iommucapen
register
E bit , E=1 时, iommu 开启.
device table walk
- RSID (Requester Source ID) 设备源ID
- RSIDHI
- RSIDLO
device table entry
dtbase 寄存器, 保存 device table 的首地址.
- 当 rsiddiv 不为 0 时, device table 有两级
- 当 rsiddiv 为 0 时, device table 只有一级.
在 rsiddiv 不为 0 时
第一级的 device table entry 结构如下:
第二级的 device table entry 结构如下:
在 rsiddiv 为 0 时, 只有一级 device table entry, 也如上图 (图 6) 结构所示
- V 有效位, V=0, 关闭该设备的地址翻译.
- S 控制是否开启 2-stage 地址翻译
- F 控制是否开启 1-stage 地址翻译
- Addr 指向 translation descriptor
device table walk 流程
1 级 device table walk.
When the rsiddiv
is zero, the IOMMU uses only one level of device table. 012
2 级 device table walk
When rsiddiv
is not zero, the IOMMU uses two levels of device table 013
Register-based Device Table
如果 device table 不是以 dtbase 实现的, 即非内存驻留的方式.
而是 iommu 提供地址寄存器 dte[x], x< 2^RSIDLEN-1, 该方式只支持一级 device table entry.
- P 位为 1 时, iommu 在引起 walk fault 时暂停该次翻译, P = 0, iommu 终止该次翻译.
- V 有效位
- Addr 指向 Translation Descriptor
Translation Descriptor
地址翻译描述符
128-191 位主要作用是保留 RSID. 并对 device table walk 和 address table walk 发生 fault 时的行为进行配置
Bit 0-1 Bit 2-3 Configuration Bits 控制 walk fault 行为
Bit 4 为 1 时, 1-stage device table walk 总是使用 Pause mode
Bit 5 为 1 时, 1-stage address table walk 总是使用 Pause mode
如果 device table entry 的 S bit 为 0, Bit 4 Bit 5 被忽略.
当 desc.S2MODE != 0 时, 43-0 位为 GPA 的页号
If the S2MODE field is not zero, bits 0-63 contains the 4K-aligned physical page number of the register MMIO page for the IOMMU allocated by the hypervisor. 011
当 desc.S2MODE = 0 时, 63-0 位为 1-stage 的控制域
Address Translation
Translation Descriptor 在内存中.
除了进行地址转换外,IOMMU 还根据相关地址表项中的权限位向源设备授予权限。
如果请求的访问类型没有在表项中被授予,IOMMU 就会报告一个错误情况。
由各个设备协商并在 IOMMU 翻译表中设置适当的权限。例如,由设备驱动来配置权限.
IOMMU 支持两个阶段的地址转换。两个翻译阶段都可以独立地启用和禁用。
当第一阶段转换被启用时,操作系统通常使用它将设备分配给各个进程。
当启用第二阶段转换时,管理程序通常使用它将设备分配给虚拟机。
虚拟机可以进一步启用第一阶段转换,以控制设备对虚拟机内进程的分配。
1-stage 地址翻译
当 desc.S2MODE = 0 时, 进行 1-stage 地址转换. 根据 dtbase 找到 device table, 根据 RSID 找到对应的 device table entry, 根据 desc 的 63-0 的 S1PPN 找到一级页表的 pgd. 根据 63-0 的 S1MODE 模式进行地址翻译, 翻译过程同 mmu.
2-stage 地址翻译
当 desc.S2MODE 不为 0 时, 进行 2-stage 地址翻译.
根据末级 device table entry 的 F/S 的设备确定是只进行 G-stage 翻译还是需要进行 G-stage 和 S-stage 翻译.
如果只进行 G-stage (S 位为 1, F 位为 0), 则 RPAddr 为 GPA pgd. 继而根据 desc.S2MODE 进行页表翻译, 翻译过程同 mmu
如果要进行 2-stage 翻译, 则以下表的流程? 没看懂, desc 在 S2MODE 打开时, 只有一个 PRAddr 地址, 这个 PRAddr 指向的是什么? #TODO
根据对 simple code 的解读, 可以先大概看下 2-stage 地址翻译的过程:
1 | // rsiddiv 不为0 时, 为两级 device table |
通过上述 simple code 的解析, 大概和上图的流程基本一致.
为什么设计的这么麻烦, 需要两次 device table walk 的流程?
第二次 device table walk 过程中, 所涉及的地址还全是 GPA, 需要 s2_atp 进行地址翻译到 HPA, 才能进行下一步翻译.
Fault Reporting
支持两种模式
pause mode
在 fault 上报之前暂停翻译, 软件处理 fault, 软件可以选择终止翻译事务还是恢复翻译事务, 如软件选择了恢复 (映射好对应的页表), iommu 硬件可以恢复该翻译事务.
iommu 的具体行为取决于其在哪个阶段触发了 fault.- device table walk 过程中触发了 fault, iommu 只能终止该事务
- address table walk 过程中触发了 fault, iommu 可以根据 desc 128-191 中的 Bit 0-1 2-3 4 5 bit 的配置选择恢复还是 abort 该事务.
abort mode 终止地址翻译并将 fault 上报给软件
寄存器
iommuinten.E
控制是否启用 iommu 的中断.
同一时刻可能有多个异常产生, 对应多个进程可能发生的 fault 异常.
iommuintno
中断号
如果 iommu 支持 AIA, Translation Descriptor 被扩展, 增加到 Bit 384 位宽.
iommucause
原因寄存器
ftval
寄存器提供 fault 的地址
resume
寄存器, pause mode 下使用
- T = 1 代表恢复, T=0 代表终止事务
T=1 时, iommu 会重新开始该次翻译事务.
中断发送
IOMMU 可能设计用于两种类型的中断系统,传统 PLIC 和 AIA。
当使用 PLIC 时,当支持 2-stage 时,不提供单独的中断。
当使用 IMSIC 时, iommu 可以直接将中断分发给对应的 vcpu, 这可以直接通过写 imsic 的 setipnum 来实现.
TLB
提供 invltlb
RSID 刷新 RSID 对应设备的 tlb entry.
排序一致性
IOMMU 对于特定的 RSID 翻译事务保持顺序, 当该 RSID 的某个翻译事务触发 fault 时, 排在其后面的翻译事务只能等待, 直到该事务被终止或恢复完成. 因此需要按 RSID 来将事务缓存到 buffer 中的能力.
处理该错误可能导致 IOMMU 或软件直接取消事务,在这种情况下,IOMMU 对具有相同 RSID 的所有后续事务返回错误。
IOPMP
IOMMU 与 IOPMP 相互补充,对恶意设备的恶意 DMA 请求提供深度防御。
当前 IOMMU 的设计完全控制了授予每个设备的权限。然而,当设备表的 V 位被清除时,设备获得对物理内存的直接访问。此外,IOMMU 的未来版本预计将与 PCI-Express 的地址翻译服务(ATS)一起工作。ATS 允许设备将 DMA 请求标记为“已翻译”,以便 IOMMU 简单地将请求传递给互连。这是一个潜在的安全漏洞,因为恶意设备总是可以将任何 DMA 请求标记为“已翻译”。在这种情况下,IOMMU 可以与指定给定设备允许的物理地址范围的 IOPMP 配对,即使请求被标记为已翻译,IOPMP 也能够拒绝访问。