16. x86 IOMMU 支持

可以从以下位置获取架构规范。

本指南提供了一些基本理解的快速备忘单。

16.1. 基本知识

ACPI 枚举并列出平台上的不同 IOMMU,以及设备和哪个 IOMMU 控制它们的设备范围关系。

一些 ACPI 关键字

  • DMAR - Intel DMA 重映射表

  • DRHD - Intel DMA 重映射硬件单元定义

  • RMRR - Intel 保留内存区域报告结构

  • IVRS - AMD I/O 虚拟化报告结构

  • IVDB - AMD I/O 虚拟化定义块

  • IVHD - AMD I/O 虚拟化硬件定义

16.1.1. 什么是 Intel RMRR?

有一些设备由 BIOS 控制,例如用于执行 PS2 仿真的 USB 设备。用于这些设备的内存区域在 e820 映射中标记为保留。当我们启用 DMA 转换时,到这些区域的 DMA 将会失败。因此,BIOS 使用 RMRR 来指定这些区域以及需要访问这些区域的设备。操作系统应为这些区域设置统一映射,以便这些设备可以访问这些区域。

16.1.2. 什么是 AMD IVRS?

该架构定义了一个称为 I/O 虚拟化报告结构 (IVRS) 的 ACPI 兼容数据结构,该结构用于向系统软件传达与 I/O 虚拟化相关的信息。IVRS 描述了平台中包含的 IOMMU 的配置和功能,以及有关每个 IOMMU 虚拟化的设备的信息。

IVRS 提供有关以下方面的信息

  • 平台中存在的 IOMMU,包括其功能和正确配置

  • 与每个 IOMMU 相关的系统 I/O 拓扑

  • 无法以其他方式枚举的外围设备

  • SMI/SMM、平台固件和平台硬件使用的内存区域。这些通常是系统软件配置的排除范围。

16.2. 如何生成 I/O 虚拟地址 (IOVA)?

行为良好的驱动程序在向需要执行 DMA 的设备发送命令之前,会调用 dma_map_*() 调用。一旦 DMA 完成并且不再需要映射,驱动程序就会执行 dma_unmap_*() 调用以取消映射该区域。

16.3. Intel 特定说明

16.3.1. 图形问题?

如果遇到图形设备的问题,您可以尝试添加选项 intel_iommu=igfx_off 以关闭集成图形引擎。如果这解决了任何问题,请确保您提交错误报告该问题。

16.3.2. IOVA 的一些例外情况

中断范围不进行地址转换,(0xfee00000 - 0xfeefffff)。点对点事务也是如此。因此,我们保留 PCI MMIO 范围的地址,以便它们不分配给 IOVA 地址。

16.4. AMD 特定说明

16.4.1. 图形问题?

如果遇到集成图形设备的问题,您可以尝试将选项 iommu=pt 添加到内核命令行,以便为 IOMMU 使用 1:1 映射。如果这解决了任何问题,请确保您提交错误报告该问题。

16.5. 故障报告

当报告错误时,IOMMU 通过中断发出信号。导致错误的故障原因和设备会打印在控制台上。

16.6. 内核日志示例

16.6.1. Intel 启动消息

类似这样的内容会被打印出来,指示 ACPI 中存在 DMAR 表

ACPI: DMAR (v001 A M I  OEMDMAR  0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0

当 ACPI 处理和初始化 DMAR 时,会打印 DMAR 位置和处理的任何 RMRR

ACPI DMAR:Host address width 36
ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000
ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed91000
ACPI DMAR:DRHD (flags: 0x00000001)base: 0x00000000fed93000
ACPI DMAR:RMRR base: 0x00000000000ed000 end: 0x00000000000effff
ACPI DMAR:RMRR base: 0x000000007f600000 end: 0x000000007fffffff

当启用 DMAR 以供使用时,您会注意到

PCI-DMA: Using DMAR IOMMU

16.6.2. Intel 故障报告

DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
DMAR:[fault reason 05] PTE Write access is not set
DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
DMAR:[fault reason 05] PTE Write access is not set

16.6.3. AMD 启动消息

类似这样的内容会被打印出来,指示 IOMMU 的存在

iommu: Default domain type: Translated
iommu: DMA domain TLB invalidation policy: lazy mode

16.6.4. AMD 故障报告

AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0007 address=0xffffc02000 flags=0x0000]
AMD-Vi: Event logged [IO_PAGE_FAULT device=07:00.0 domain=0x0007 address=0xffffc02000 flags=0x0000]