5

我一直在阅读有关Linux 中IOMMU支持的信息,并且对 IOMMU 中的页表有一些疑问:

  1. IOMMU 是否使用 CPU MMU 页表来存储 VA → PA 映射?
  2. 如果不是,即虚拟地址不同,那么映射是按设备还是按 IOMMU 单元创建的?

我还没有查看任何驱动程序代码,所以如果有人能指出一些示例驱动程序代码,那就太好了。

4

2 回答 2

6

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

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

有物理内存,由内存控制器控制。还有一些设备想要访问物理内存:CPU 和外部总线控制器。CPU有自己的翻译,总线控制器有自己的。

DTR 和 Intgr 的 mmu 和 iommu.svg 的 wiki 图像; 公共区域

如果不是,即虚拟地址不同,那么映射是按设备还是按 IOMMU 单元创建的?

映射是根据 IOMMU 的功能创建的。一些简单的 IOMMU 可能有一个用于设备总线根控制器(PCI-express 根组件)的全局映射。像 Intel 的 VT-d 这样的复杂 IOMMU 可能有多个映射或嵌套转换,这些映射或嵌套转换是根据一些每个端口的规则选择的。(但桥后面的两个设备通常会有相同的翻译。)

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

英特尔 IOMMU 驱动程序为每个域分配一个虚拟地址。每个 PCIE 设备都有自己的域(因此受到保护)。由于 p2p 网桥的事务 ID 别名,p2p 网桥下的设备与 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 用于虚拟化的历史。

于 2016-06-28T23:42:22.743 回答
0

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

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

请参阅英特尔显卡上的 SVM

于 2017-01-09T23:17:25.290 回答