接前一篇文章:一文读懂IOMMU(1)
1.2 IOMMU作用
根据上一节内容,总结IOMMU主要作用如下:
屏蔽物理地址,起到保护作用。典型应用包括两个:一是实现用户态驱动,由于IOMMU的映射功能,使HPA对用户空间不可见,在vfio部分还会举例;二是将设备透传给虚机,使HPA对虚机不可见,并将GPA映射为HPA。
IOMMU可以将连续的虚拟地址映射到不连续的多个物理内存片段,这部分功能与MMU类似,对于没有IOMMU的情况,设备访问的物理空间必须是连续的,IOMMU可有效地解决这个问题。
1.3 IOMMU工作原理
前面简单介绍了IOMMU的映射功能,下面讲述IOMMU到底如何实现映射的。为便于分析,这里先不考虑虚拟化的场景,阐述工作原理。以下图为例:
IOMMU的主要功能就是完成映射,类比MMU利用页表实现VA->PA的映射,IOMMU也需要用到页表,那么下一个问题就是如何找到页表。
在设备发起DMA请求时,会将自己的Source Identifier(包括Bus、Device、Func)包含在请求中,IOMMU根据这个标识,以RTADDR_REG指向空间为基地址,然后利用Bus、Device、Func在Context Table中找到对应的Context Entry,即页表首地址,然后利用页表即可将设备请求的虚拟地址翻译成物理地址。这里作以下说明:
上图中红线的部分,是两个Context Entry指向了同一个页表。这种情况在虚拟化场景中的典型用法就是这两个Context Entry对应的不同PCIe设备属于同一个虚机,那样IOMMU在将GPA->HPA过程中要遵循同一规则。
由图中可知,每个具有Source Identifier的设备都会具有一个Context Entry。如果不这样做,所有设备共用同一个页表,隶属于不同虚机的不同GPA就会翻译成相同HPA,则会产生问题。
有了页表之后,就可以按照MMU那样进行地址映射工作了,这里也支持不同页大小的映射,包括4KB、2MB、1GB,不同页大小对应的级数也不同。下图以4KB页大小为例说明,映射过程和MMU类似,不再详细阐述。
1.4 Source Identifier
在讲述IOMMU的工作原理时,讲到了设备利用自己的Source Identifier(包括Bus、Device、Func)来找到页表项来完成地址映射,不过存在下面几个特殊情况需要考虑:
- 对于由PCIe switch扩展出的PCI桥及桥下设备,在发送DMA请求时,Source Identifier是PCIe switch的。这样的话,该PCI桥及桥下所有设备都会使用PCIe switch的Source Identifier去定位Context Entry,找到的页表也是同一个。如果将这个PCI桥下的不同设备分给不同虚机,由于会使用同一份页表,这样会产生问题,针对这种情况,当前PCI桥及桥下的所有设备必须分配给同一个虚机,这就是VFIO中组的概念,下面会再讲到。
- 对于SRIO-V,之前介绍过VF的Bus及devfn的计算方法,所以不同VF会有不同的Source Identifier,映射到不同虚机也是没有问题的。
更多内容请看下回。