iommu简介
对于Intel的硬件辅助虚拟化方案而言核心的两大技术分别是VT-x和VT-d。 其中VT-x中主要引入了non-root模式(VMCS)以及EPT页表等技术,主要关注于vCPU的虚拟化和内存虚拟化。 而VT-d的引入则是重点关注设备直通(passthrough)方面(即IO虚拟化),我们知道DMA是可以让设备直接绕过cpu直接存取内存,但是DMA要读取的地址都是物理地址,简单直接,但是缺点是要求物理内存必须是连续的一整块,同时无法满足虚拟机的直通要求,这时候就出现了io虚拟化的DMAR(DMA remapping),I/O设备访问的DMA地址不再是物理内存,而是经过经过MMU的DMAR转译,负责DMAR的硬件成为IOMMU,比较类似就是MMU是支持内存地址转虚拟地址的硬件,MMU是主要为cpu服务,而IOMMU是为I/O设备服务,是将DMA地址进行虚拟化的硬件。
IOMMU不仅将DMA地址地址虚拟化、还会使用不同的domain单元起到隔离、保护的作用,详细可以参阅:Intel® Virtualization Technology for Directed I/O (VT-d): Enhancing Intel platforms for efficient virtualization of I/O devices
硬件结构
在多路服务器上我们可以有多个DMAR Unit(这里可以直接理解为多个IOMMU硬件), 每个DMAR会负责处理其下挂载设备的DMA请求进行地址翻译。 例如上图中, PCIE Root Port (dev:fun) (14:0)下面挂载的所有设备的DMA请求由DMAR #1负责处理, PCIE Root Port (dev:fun) (14:1)下面挂载的所有设备的DMA请求由DMAR #2负责处理, 而DMAR #3下挂载的是一个Root-Complex集成设备[29:0],这个设备的DMA请求被DMAR #3承包, DMAR #4的情况比较复杂,它负责处理Root-Complex集成设备[30:0]以及I/OxAPIC设备的DMA请求。 这些和IOMMU相关的硬件拓扑信息需要BIOS通过ACPI表呈现给OS,这样OS才能正确驱动IOMMU硬件工作。
这里面有几个概念需要大概了解一下,在阅读代码的时候会经常遇到:
- DRHD: DMA Remapping Hardware Unit Definition 用来描述DMAR Unit(IOMMU)的基本信息
- RMRR: Reserved Memory Region Reporting 用来描述那些保留的物理地址,这段地址空间不被重映射
- ATSR: Root Port ATS Capability 仅限于有Device-TLB的情形,Root Port需要向OS报告支持ATS的能力
- RHSA: Remapping Hardware Static Affinity Remapping亲和性,在有NUMA的系统下可以提升DMA Remapping的性能
BIOS通过在ACPI表中提供一套DMA Remapping Reporting Structure 信息来表述物理服务器上的IOMMU拓扑信息, 这样OS在加载IOMMU驱动的时候就知道如何建立映射关系了。
我们可以通过一些命令将acpi表相关信息dump出来查看:
[root@node-2 zjp]# acpidump > acpidump.out
[root@node-2 zjp]# acpixtract -a acpidump.out
Intel ACPI Component Architecture
ACPI Binary Table Extraction Utility version 20160527-64
Copyright (c) 2000 - 2016 Intel Corporation
...
Acpi table [ERST] - 624 bytes written to erst.dat
Acpi table [DSDT] - 32809 bytes written to dsdt.dat
Acpi table [SRAT] - 1216 bytes written to srat.dat
Acpi table [HEST] - 1400 bytes written to hest.dat
Acpi table [BERT] - 48 bytes written to bert.dat
Acpi table [DMAR] - 352 bytes written to dmar.dat
Acpi table [FACP] - 244 bytes written to facp.dat
...
18 binary ACPI tables extracted
[root@node-2 zjp]# iasl -d dmar.dat
Intel ACPI Component Architecture
ASL+ Optimizing Compiler version 20160527-64
Copyright (c) 2000 - 2016 Intel Corporation
Input file dmar.dat, Length 0x160 (352) bytes
ACPI: DMAR 0x0000000000000000 000160 (v01 DELL PE_SC3 00000001 DELL 00000001)
Acpi Data Table [DMAR] decoded
Formatted output: dmar.dsl - 12676 bytes
[root@node-2 zjp]# cat dmar.dsl
/*
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
*/
[000h 0000 4] Signature : "DMAR" [DMA Remapping table]
[004h 0004 4] Table Length : 00000160
[008h 0008 1] Revision : 01
[009h 0009 1] Checksum : D0
[00Ah 0010 6] Oem ID : "DELL "
[010h 0016 8] Oem Table ID : "PE_SC3 "
[018h 0024 4] Oem Revision : 00000001
[01Ch 0028 4] Asl Compiler ID : "DELL"
[020h 0032 4] Asl Compiler Revision : 00000001
...
参考资料:
https://kernelgo.org/intel_iommu.html
http://linuxperf.com/?p=67
https://software.intel.com/content/www/us/en/develop/blogs/intels-virtualization-for-directed-io-aka-iommu-part-1.html
https://www.kernel.org/doc/Documentation/Intel-IOMMU.txt