接前一篇文章:《PCI Express体系结构导读》随记 —— 第II篇 第13章 PCI总线与虚拟化技术(2)
13.1 IOMMU
13.1.1 IOMMU的工作原理
DMA-Remapping逻辑的组成结构如图13-1所示:
在上一回的处理器模型中,假设存在两个外部设备Device A和Device B。这两个外部设备分属于不同的Domain,Device A属于Domain 1,而Device B属于Domain 2。在同一段时间内,Device A只能访问Domain 1的GPA1空间,也只能被Domain 1操作;而Device B只能访问Domain 2的GPA2空间,也只能被Domain 2操作。Device A和Device B通过DMA-Remapping机制,最终访问不同Domain的存储器。
使用这种方法可以保证Device A和Device B访问的空间彼此独立,而且只能被指定的Domain访问,从而满足了虚拟化技术所要求的空间隔离。这一模型非常完美,如果每个Domain都可以自由访问所有外部设备当然更加合理,但是单纯使用VT-d机制还不能实现这种访问机制。
在这种模型之下,Device A/B进行DMA操作时使用的物理地址仍然属于PCI总线域的物理地址,Device A/B仍然使用地址路由或者ID路由进行存储器读写TLP的传递。值得注意的是,虽然在x86处理器系统中,这个PCI总线地址与GPA地址一一对应且相等,但这两个地址所代表的含义仍然完全不同。
GPA地址为存储器域的地址,隶属于不同的Domain;而PCI设备使用的地址依然是PCI总线域的物理地址。只是在虚拟化环境下,PCI设备与Domain间有明确的对应关系。当这个PCI设备进行DMA读写时,TLP(Transaction Layer Packet)首先到达地址转换部件TA(Translation Agent),并通过ATPT(Address Translation and Protection Table)后将PCI总线域的物理地址转换为与GPA地址对应的HPA地址(ATPT相当于I/O页表,每一个Domain都具有独立的I/O页表),然后对主存储器进行读写操作。其转换关系如图13-2所示:
在上图所示的处理器系统中,存在两个虚拟机,其使用的地址空间分别为GPA Domain1和GPA Domain 2。假设每个GPA Domain使用1GB大小的物理地址空间,而且Domain间使用的地址空间独立,其地址范围都为0x00000000~0x40000000(0~1G)。其中,Domain 1使用的GPA地址空间对应的HPA地址范围为0x00000000~0x3FFFFFFF;Domain 2使用的GPA地址空间对应的HPA地址范围为0x40000000~0x7FFFFFFF。在一个处理器系统中,不同的虚拟机使用的物理空间是隔离的。
在这个处理器系统中存在两个PCIe设备,分别为EP1和EP2,其中EP1隶属于Domain 1,而EP2隶属于Domain 2,即EP1和EP2进行DMA操作时,只能访问Domain 1和Domain 2对应的HPA空间。但是EP1和EP2作为一个PCIe设备,并不知道处理器系统进行的这种绑定操作,EP1和EP2依然使用PCI总线域的地址进行正常的数据传送。因为处理器系统的这种绑定操作由TA和ATPT决定,而对PCIe设备透明。在EPT1和EPT2进行DMA操作时,当TLP到达TA和ATPT,经过地址转换后,才能访问实际的存储器空间。
下面以EP1和EP2进行DMA写操作为例,说明在这种虚拟化环境下,不同种类地址的转换关系。具体步骤如下:
(1)Domain 1和Domain 2填写EP1和EP2的DMA写地址和长度寄存器,启动DMA操作。
其中,EP1最终将数据写入到GPA1的0x10000000~0x1000007F这段数据区域;而EP2最终将数据写入到GPA2的0x10000000~0x1000007F这段数据区域。然而,EP1和EP2仅能识别PCI总线域的地址。Domain 1和Domain 2填入EP1和EP2的DMA写地址为0x10000000,长度为0x80,这些地址都是PCI总线地址。
在x86处理器系统中,这个地址与GPA1和GPA2存储器域的地址恰好相等,但是这个地址仍然是PCI总线域的地址,只是由于IOMMU的存在,相同的PCI总线地址可能被映射到相同的GPA地址空间,然而这些GPA地址空间对应的HPA地址空间不同。这个PCI总线地址仍然在RC中被转换为存储器域地址,并由TA转换为合适的HPA地址。
(2)EP1和EP2的存储器写TLP到达RC。
来自EP1和EP2的存储器写TLP经过地址路由最终到达RC,并由RC将TLP的地址字段转发到TA和ATPT,进行地址翻译。
EP1和EP2使用的I/O页表已经事先被VMM设置完毕,TA将使用Domain 1或Domain 2的I/O页表,进行地址翻译。EP1隶属于Domain 1,其地址0x10000000(PCI总线地址)被翻译为0x10000000(HPA);而EP2隶属于Domain 2,其地址0x10000000(PCI总线地址)被翻译为0x50000000(HPA)。值得注意的是,在TA中设置了IOTLB,以加速I/O页表的翻译效率,因此TA并不会每次都从存储器中查找I/O页表。
(3)来自EP1和EP2存储器写TLP的数据将被分别写入到0x10000000~0x1000007F和0x50000000~0x5000007F这两段数据区域。
(4)Domain 1和Domain 2都使用0x10000000~0x1000007F这段GPA地址访问来自EP1和EP2的数据,这个GPA地址将被转换为HPA地址,然后发向存储器控制器。在IA处理器系统中,使用EPT和VPID技术进行GPA地址到HPA地址的转换。
IA处理器和AMD处理器使用不同的技术实现TA和ATPT。其中,IA处理器使用VT-d技术,而AMD使用IOMMU。从工作原理上看,这两种技术类似,但在实现细节上,两者有较大区别。
更多内容请看下回。