IOMMU历史知识及与VFIO的联系
IOMMU历史知识及与VFIO的联系
在虚拟化普及之前,IOMMU主要提供2种功能,避免bounce buffers的功能,创建连续DMA操作功能。
- Bounce Buffers
如果外设的寻址空间小于平台(如PC)的寻址空间,例如外设只支持寻址4GB空间,但是PC支持寻址8GB,如果PC中的驱动程序分配了4GB以上的空间给设备,那么设备将无法对该空间执行DMA操作。
解决该问题的一种思路就是利用bounce buffers. Bounce buffers是处于较低内存中的缓冲区空间,外设可以在其中进行临时的DMA操作,操作完成后,将结果复制到驱动程序分配的高地址内存缓冲区中。
但是这种方法会导致效率降低,因为多了一步复制操作,当数据量比较大时,会明显降低数据处理效率。
IOMMU为外设提供IOVA空间,驱动程序可以通过访问IOVA来访问设备空间,避免了bounce buffers的使用,提高了数据处理效率。
- Creating contiguous DMA operations
当驱动程序使用多个buffers时,IOMMU可以将这多个buffer映射成连续的地址,这样方便操作,例如之前需要对2个4KB大小的buffer进行2个4KB大小的DMA操作,现在只需要进行1个8KB大小的DMA操作,提高了效率。
这两个功能对于host上的高性能I / O仍然很重要,但是从虚拟化角度来看,我们喜欢的IOMMU功能是现代IOMMU的隔离功能。在PCI-Express之前,不可能进行大规模的隔离,因为常规PCI不会使用请求设备的ID(请求者ID)来标记transaction。 PCI-X包含某种程度的请求者ID,但是互连规则使支持的隔离性不完整。使用PCIe,每个设备都使用该设备唯一的请求者ID(PCI总线/设备/功能编号,BDF)来标记事务,该请求者ID用于引用该设备的唯一IOVA表。我们忽然之间从 “从共享的IOVA空间卸载无法访问的内存并整合内存”,到“每个设备都拥有一个IOVA空间”,我们不仅可以将其用于这些功能(卸载无法访问的内存并整合内存),还可以限制来自设备的DMA访问。为了分配给虚拟机,现在只需要将IOVA放在Host分配给VM使用的物理空间内,该设备就可以在Guest地址空间中透明地执行DMA。
IOMMU_GROUP: IOMMU group试图描述从IOMMU的角度来看可以隔离的最小设备集。这样做的第一步是每个设备必须关联到唯一的IOVA空间。也就是说,如果多个设备使用相同的IOVA空间作为别名,则IOMMU无法区分它们。这就是典型的x86 PC将所有常规PCI设备分组在一起的原因,所有这些设备的别名为同一PCIe至PCI桥接器。旧式KVM设备分配将允许用户独立分配这些设备给guest,但是肯定会配置失败。 VFIO由IOMMU组控制,因此可以防止违反IOMMU粒度这一最基本要求的配置。