Linux IOMMU页面表

6
我一直在研究Linux中的IOMMU支持,并对IOMMU中的页面表有一些疑问:
  1. IOMMU是否使用CPU MMU页面表来存储VA→PA映射?
  2. 如果不是,即虚拟地址不同,那么这些映射是针对每个设备还是每个IOMMU单元创建的?
我还没有查看任何驱动程序代码,所以如果有人能指向一些示例驱动程序代码,那就太好了。

你读了什么? - osgx
2个回答

7

IOMMU是否使用CPU MMU页面表来存储VA->PA映射?

不是。操作系统中有许多进程,每个进程都有自己的VA->PA映射(它们都在单独的虚拟地址空间中运行)。

物理内存由内存控制器控制。设备想要访问物理内存:CPU和外部总线控制器。CPU有自己的转换和总线控制器有自己的转换。

wiki image of mmu and iommu.svg by DTR and Intgr; public domain

如果虚拟地址不同,那么映射是按设备还是按IOMMU单元创建的?
映射是根据IOMMU的功能创建的。一些简单的IOMMU可能会为设备总线根控制器(PCI Express根复合器)创建一个全局映射。像英特尔的VT-d这样的复杂IOMMU可能会有几个映射或嵌套翻译,根据一些每个端口规则选择。(但桥后面的两个设备通常会有相同的翻译。)

https://www.kernel.org/doc/Documentation/Intel-IOMMU.txt

英特尔IOMMU驱动程序为每个域分配虚拟地址。每个PCIE设备都有自己的域(因此受到保护)。由于p2p桥的事务ID别名,位于p2p桥下的所有设备与所有其他设备共享虚拟地址。

https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txt

在一些系统中,总线地址与CPU物理地址相同,但通常不是这样。IOMMU和主机桥可以在物理地址和总线地址之间产生任意映射。(请参阅https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txt中“这里有一张图片和一些示例”的附近的图片。)
虚拟地址(X)...虚拟内存系统将X映射到系统RAM中的物理地址(Y)。驱动程序可以使用虚拟地址X来访问缓冲区,但设备本身无法访问,因为DMA不通过CPU虚拟内存系统。
在一些简单的系统中,设备可以直接对物理地址Y进行DMA。但在许多其他系统中,存在IOMMU硬件,用于将DMA地址转换为物理地址,例如将Z转换为Y。

请查看https://events.linuxfoundation.org/sites/events/files/slides/20140429-dma.pdf(2014年)和http://www.linuxplumbersconf.org/2014/wp-content/uploads/2014/10/LPC2014_IOMMU.txt,内容与编程有关。同时,请阅读http://developer.amd.com/wordpress/media/2012/10/IOMMU-ben-yehuda.pdf(2012年)的文章,了解设备内存重映射和IOMMU在虚拟化中的历史。


0

虽然 osgx的回答在内核中使用IOMMU的历史上是正确的,但是使用共享虚拟内存的情况,特别是使用PCIe PASID,将需要共享或影子IOMMU和CPU页表,以便可以直接从用户空间驱动程序将指针/ VA(例如到固定缓冲区)传递给设备,而无需任何dma_map相关的内核服务。

当然,这将需要新的API,以便用户空间能够请求SVM /共享页表。

请参见Intel Graphics上的SVM


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接