1 两级转换
1.1 什么是stage2转换
Stage2转换允许hypervisor控制虚拟机VM中内存视图。它允许hypervisor控制一个虚拟机可以访问哪块内存映射的系统资源,以及这些资源应该出现在虚拟机地址空间的哪个位置。
这种控制内存访问的能力对于隔离是非常重要的。Stage2转换用于保证一个虚拟机仅能够看到分配给它的资源,分配给其他虚拟机或hypervisor的资源它是无法看到。
对于内存地址转换,stage2转换为转换的第2阶段。为了支持它,要求一组新的转换表stage2表,如下所示:
OS操作系统控制一组转换表,它们用于将虚拟地址空间映射到它认为的物理地址空间。但是,这个过程还经历第二级转换才将其变成真实的物理地址空间。第二级转换由hypervisor控制。
OS控制的转换称为stage1转换,hypervisor控制的转换称为stage2转换。OS认为的物理地址空间称为中间物理地址空间IPA。
用于stage2转换表的格式与stage1类似。但是,在stage2中一些属性被不同处理,Type、Normal或Device被直接放在页表项中,而不是在MAIR_ELx寄存器中。
1.2 VMIDs
每个虚拟机VM都有一个VMID。VMID用于标记TLB项,这些TLB项用于区分它们属性哪个VM。这个标记允许多个不同VM的转换可以同时出现在TLB中。
VMID由VTTBR_EL2保存,可以为8位或16位。VMID由VTCR_EL2.VS位控制。对16位VMID的支持是可选的。
NOTE:EL2和EL3转换域的转换不会被标记VMID,因为它们并不是受限于stage2转换。
1.3 VMID与ASID交互
TLB项也可以通过ASID被标记。一个应用通过OS被赋予ASID,应用中所有TLB项由ASID标记。这意味着不同应用的TLB项可以在TLB中共存,这就避免了一个应用使用的TLB项属于另一个应用。
每个VM有自己独立的ASID空间。比如,两个VM可能都使用ASID 5,但使用它们来表示不同的事情。因此VMID和ASID的联合就是非常重要的。
1.4 属性合并和覆盖
Stage1和stage2映射都包含像type和访问权限等属性。MMU会将两阶段的属性联合到一个有效的值。MMU是通过选择更严格的阶段来实现的。如下所示:
在这个例子中,Device类型比Normal更严格。因此最后的类型为Device。
属性联合的方法适用于绝大多数情况,但有时hypervisor可能希望覆盖这个行为。比如,在VM早期boot过程。对于这种情况,有一些控制位来覆盖正常的行为:
- HCR_EL2.CD:它将所有stage1属性变成non-cacheable
- HCR_EL2.DC:它强制stage1属性变成Normal,Write-Back Cacheable
- HCR_EL2.FWB:它允许stage2属性覆盖stage1属性,而不是正常的两阶段联合
1.5 MMIO的模拟
像物理机上的物理地址空间,虚拟机上IPA空间用于访问内存和外设,如下图所示:
虚拟机可以使用外设区域来访问真实的外设(通常是直接访问)和虚拟外设。
虚拟外设由hypervisor完全模拟,如下图所示:
一个assigned外设通常是分配给虚拟机的真实物理设备,它会被映射到IPA地址空间。它允许运行在VM上的软件与外设直接交互。
虚拟设备为hypervisor将要用软件模拟的设备。相对应的stage2表项将被标记成fault。虚拟机中软件认为它可以直接访问外设,但每次访问会触发stage2 fault,然后hypervisor会模拟异常处理中外设的访问。
为了模拟一个外设,hypervisor需要知道访问哪个外设,同时也要知道访问外设的哪个寄存器,访问是读还是写,访问的大小,用于传输数据的寄存器。
从地址开始,异常模型介绍FAR_ELx寄存器。当处理stage1 fault时,这些寄存器报告触发异常的虚拟地址。一个虚拟地址对Hypervisor没有帮助,因为hypervisor通常不知道Guest OS是如何配置它的虚拟地址空间的。对于stage2 fault,存在额外寄存器,HPFAR_EL2,它报告产生异常的IPA地址。因为IPA地址空间由hypervisor控制,它使用信息来决定它需要模拟哪个寄存器。
异常模型介绍了ESR_ELx寄存器是如何报告异常的信息的。对于单个通用寄存器的load和store,它会触发一个stage2 fault,并提供其他额外的症状。这些信息包括访问的大小,源寄存器,目的寄存器,并允许hypervisor决定访问的类型。
下图描述了陷入以及模拟访问的过程:
过程如下步骤所示:
(1)虚拟机中软件尝试访问虚拟外设。在这个例子中,访问的是虚拟UART的FIFO。
(2)访问被阻塞在stage2转换上,它会导致路由到EL2的abort。
- 异常abort提供ESR_EL2异常相关信息,包括访问的大小,目标寄存器,是load还是store。
- 异常abort提供HPFAR_EL2异常访问的IPA地址
(3)hypervisor使用ESR_EL2和HPFAR_EL2区分访问的虚拟外设寄存器。这些信息允许hypervisor模拟这些操作,然后再通过ERET返回vCPU
1.6 arm64两stage转换的例子
下图描述了arm64两级转换的例子,其中虚拟机和物理机都是48位:
其中GVA是虚拟机中虚拟地址,GPA是虚拟机中物理地址,HPA是host上物理地址。注意,在虚拟机中页表项中存放虚拟机中认为的物理地址即GPA,而页表项存放在真实的物理内存中即HPA。
当虚拟机中访问GVA时,由虚拟机VTTBR_ELx指向虚拟机中页表项,但由于存放的是GPA,需要经过stage2的四级转换,最终得到下一级页表项的真实物理地址HPA。因此虚拟机中访问物理内存,最终需要访问的内存次数(5*4+4)=24次。