03
2024
04
10:20:31

SMMU和IOMMU技术



推荐点击下面图片,通过本站淘宝优惠价购买:

image.png

设备访问 memory 引入的 IOMMU/SMMU技术,同时留了一个问题:IOMMU/SMMU 是否可以同时支持 GVA->GPA 和 GPA->HPA 的转换?答案是Yes。

在虚拟化的环境中,借助 IOMMU 的 GPA->HPA 转换,DMA 控制器可以直接以 guest VM 提供的 GPA 作为 source 或者 destination,减少了 VMM 的参与。

在非虚拟化的环境中,借助 IOMMU 的 HVA->HPA 转换,DMA 控制器也可以直接以 userspace buffer 的 HVA 作为 source/destination,而不需要 OS kernel 将 user process 的 VA 转换后的 PA 填入 DMA 控制器。

两者其实是统一的,不管 HVA 还是 GPA,都不是 real phsical address,有了 IOMMU/SMMU 之后,DMA 控制器就可以使用虚拟地址,也不再要求对应的内存是物理连续的了。

ARM的SMMU

那IOMMU/SMMU具体应该如何使用呢?本文将主要以ARM的SMMU为例,讲解其转换地址的过程。

在Linux的实现中,一个进程有一个对应的页表,而SMMU是为设备服务的,几个设备可能同属于一个guest VM,因此多个设备可能会共用一个GPA->HPA的转换页表。同一个guest VM的设备可能属于或者不属于某一个特定的进程,因此也可能共用或者不共用GVA->GPA的转换页表。

在SMMU中,一个发起DMA传输(transaction)的设备的信息由一个Stream Table Entry(STE)来描述。所有的STEs共同构成了Stream Table,可由StreamID作为Stream Table数组的索引,查找得到对应的STE,因此StreamID也就成了设备唯一性的标识。Stream table可以是1-level的:

也可以是2-level的,比如一个10位的StreamID使用[9:8]的2个bits作为第一级Stream table的索引,[7:0]的8个bits作为第二级Stream table的索引,这和使用虚拟地址作为索引查找页表是一样的(参考这篇文章)。

不同的是,多级页表中每级页表的大小是相同的,而第二级Stream table的大小可以是不同的,比如下图中A就是占满了的,有255个entries,而B和C分别只有4个entries和1个entry。用户可以根据实际的需要灵活配置,以节约内存空间。

大家应该都知道,ARM公司主要是依靠出售core的license来赚钱的,它给予了具体的芯片厂商一些自由发挥的空间,比如SMMUv3只规定了StreamID的大小是0-32个bits,但具体采用多少个bits,以及StreamID是怎样构成的,则都属于implementation defined。

但SMMUv3同时也做出了限制:如果StreamID的数目超过了64(也就是超过了6个bits),那么必须使用2-level的Stream table。

如果一个STE对应的设备要进行的是GPA->HPA的stage 2转换(关于stage请参考这篇文章的注[1]),那么该STE包含的S2TTB(Stage 2 Translate Table Base)将直接指向设备所属的guest VM对应的stage 2页表(下图中的D)。设备所属的VM由STE中的VMID标识,属于同一个VM的设备对应的STEs将指向同一个stage 2页表。

在同一个VM内,一个设备可能被VM内的多个进程共享,而这些进程会有不同的页表,因此一个设备在和不同进程交互时,也会使用不同的页表。为了区分,需要一个设备对应进程的描述信息,这个描述信息被称为CD(Context Descriptor)。

如果该设备需要进行的是GVA->GPA的stage 1转换(比如前面提到的用户空间的DMA传输),那么描述该设备的STE将指向当前进程对应的这个CD(下图中的B)。和同一个进程交互的不同设备将共用这个进程的stage 1页表,因此这些设备的STEs将指向同一个CD。

每个CD包含了一个标识进程的ASID,由TTB0和TTB1指向进程对应的stage 1页表(上图中的C)。熟悉ARM架构的同学应该知道,TTBR0和TTBR1是ARM中分别用来存储进程页表和内核页表的基地址的寄存器,由于这里不再是Register,而是内存中的Descriptor,但用途类似,所以就叫TTB0和TTB1。

同一个设备对应的所有CDs构成了一个CD table。CD table使用的查找索引被称为SubstreamID。SubstreamID最多占20个bits,这个规定是有出处的。熟悉PCIe的同学可能知道,PCIe中有个PASID,而PASID最大就是20个bits。SubstreamID基本就是和PASID对等的概念,虽然SMMU并不限于只支持PCIe的设备,但这里SubstreamID还是和PASID保持了统一的步调。

同Stream table一样,CD table可以是1-level的(下图中的D),也可以是2-level的(下图中的E和F)。

如果是熟悉x86的segmentation机制或者是看过这个系列的文章的同学,会不会发现SMMU中的这个Stream table/CD table,其实和x86中的GDT/LDT是很相似的。都是通过索引查找得到对应的entry,每一个entry都是记录的一些描述信息,而且后面还都是跟的page tables。

限于篇幅控制,下文继续。


参考:

ARM System Memory Management Unit Architecture Specification, version 3.1

SMMU支持stage 1的GVA->GPA(按ARM的叫法则是VA->IPA)的转换,也支持stage 2的GPA->HPA(IPA->PA)的转换,你可以选择只进行stage 1的转换,不进行stage 2的转换,也可以绕过stage 1的转换,只用stage 2的转换,还可以stage 1和stage 2的转换都用。stage 1和stage 2的转换都不用……那就没SMMU什么事了。

就像你可以选择周六来加班,或者周天来加班,或者周六周天都来加班。周六周天都不来加班……一点问题也没有,反正只要来加班既有double的工资(这个不太恰当的类比源自笔者过去一段真实的工作经历,那么自由的时间安排和报酬的合理支付,以至于让我有次细数以前的加班经历时,竟然把这一段漏掉了,让你加了班还让你感觉到好像没有加过,这恐怕是加班的最高境界了吧)。

linux内核中关于SMMU的实现形式,也就是上面提到的这四种情况:

enum arm_smmu_domain_stage {
	ARM_SMMU_DOMAIN_S1 = 0,
	ARM_SMMU_DOMAIN_S2,
	ARM_SMMU_DOMAIN_NESTED,
	ARM_SMMU_DOMAIN_BYPASS,}

x86的IOMMU

再来看看友商的 IOMMU 技术。其实原理都是差不多的,只是构造和名称上有些许差别。相对于 SMMU,Intel 的 IOMMU 跟 PCI(e) 的联系更加紧密。它是用 PCI(e) 中的 BDF 号(Bus/Device/Function,也叫 Requester ID)来标识设备。

BDF 号被分为了两个部分,第一部分 Bus 占 8 个 bits,作为 Root Table 的索引;第二部分 Device 和 Function分别各占 5 个 bits 和 3 个 bits,作为 Context Table 的索引。这里 Root Table 和 Context Table 分别类似于SMMU 中 Stream table 的第一级和第二级,而 BDF 的作用就等同于 SMMU 中的 StreamID。

I/O页表

前面的文章还留了一个问题:为什么IOMMU要使用专门的I/O页表?以AMD的IOMMU为例,它和内置在一个CPU内的MMU(以下称作CPU MMU,ARM的CoreLink MMU,还有前面介绍的EPT/NPT,都属于CPU MMU)是存在一些区别的:

  • 64位的x86_64系列的CPU MMU只支持4KB, 2MB和1GB的页大小(参考这篇文章),而AMD的IOMMU除了支持这些默认的页大小,还支持8KB, 16KB, 1MB, 4MB, 4GB的页大小。

  • CPU MMU需要按照页表结构一级一级的遍历,而当虚拟地址包含一长串的0的时候,AMD的IOMMU在查找时可以跳过其中的一级页表。

正因为有了IOMMU设计上的这些差异,使用专门的I/O页表可以获得更快的查找速度。如果非要用普通的页表也不是不可以,但需要舍弃IOMMU的一些特性,以适配普通页表的查找规则。然而,ARM的SMMU的设计就不是这样的,它使用普通的页表依然可以工作的很好,不需要专门的I/O页表。


参考:

  • Intel Virtualization Technology for Directed I/O Architecture Specification, Rev. 3.1

  • AMD I/O Virtualization Technology (IOMMU) Specification, Rev. 3.0.0


本文链接:https://hqyman.cn/post/5629.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:





休息一下,本站随机推荐观看栏目:


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

您的IP地址是: