虚拟化中的虚拟地址与物理地址的映射——EPT机制
当 secondary processor-based VM-execution control 字段 “enable EPT” 为 1 时,启用 EPT ( Extended Page Table,扩展页表)机制
开启 EPT 机制后 VMM 需要建立 EPT 页表结构,通过在 EPTP ( Extende Page Table Pointer ) 中提供 EPT 页表结构的指针值,为每个 VM 准备不同的 EPT 页表结构或在同一个 EPT 页表结构中准备不同的页表项
1. GPA (guest-physical address) 64位宽
guest 软件使用的物理地址,不是真正的物理地址。启用 EPT 机制后,VM 有自己独立的 guest-physical address 空间,每个 VM 之间的 GPA 空间互不干扰。
启用分页时,guest 软件的线性地址首先转换为 GPA,最后 GPA 必须通过 EPT 转换为最终的 HPA
1)有效的GPA值
当前 VMX 架构实现了最高48位有效的GPA值 (bits47:0)。x86/x64 体系下最高可实现 52 位的物理地址。实际 GPA 值宽度与 MAXPHYADDR 值相关
- CR3 的 bits 63:N (N= MAXPHYADDR) 是保留位
- EPTP 字段 的 bits 63:N (N= MAXPHYADDR) 是保留位。
- guest paging structure 里每个表项的 bits 63:N (N = MAXPHYADDR) 是保留位
2)GPA的产生
-
由 guest-linear address 转换而来 ( guest 未分页时 guest-linear address 直接等于 GPA )
32 位分页模式下的线性地址转换为 32 位物理地址,则 GPA 高 32 位补为 0。实模式下线性地性为 20 位(物理地址),则 GPA 的 bits 63:20 则补为 0 值
-
不是由guest-linear address转换而来(执行MOV to CR3指令,或者访问guest paging structure页表项)
2. HPA (host-physical address)
物理平台上的地址。未启用 EPT 机制时,guest 软件的物理地址是 HPA。启用 EPT 机制时,guest 软件的物理地址是 GPA,而 host 软件的物理地址是 HPA。VMM 软件使用的是 HPA
与这两种物理地址相对应的页转换表结构如下:
3. guest paging-structure
存在于 guest 端,是 x86/x64 体系开启分页机制下的产物,用来将线性地址转换为物理地址。但在 guest 中,线性地址通过 guest paging-structure 转换为 guest-physical address,而不是真正的平台物理地址
1)guest 的分页模式
x64(CRO.PG=1 时):
- 当CR4.PAE = 0时,guest使用32位分页模式。当CR4.PSE =1,并且MAXPHYADDR值大于等于40时,允许在4M页面上使用40位的物理地址
- 当IA32_EFER.LMA=0,并且CR4.PAE=1时,guest使用PAE分页模式
- 当IA32_EFER.LMA= 1,并且CR4.PAE=1时,guest使用IA-32e分页模式
guest 的线性地址根据上面的分页模式转换 guest-physical address;当 guest 使用 PAE 分页模式,并且启用 EPT 机制时,在 VM-entry 时会加载 4 个 PDPTE 字段
2)引发 GPA 转换 HPA
- guest 进行内存访问,包括读写访问及执行访问
- guest 使用 PAE 分页模式加载 PDPTE,包括下面的途径:
- 执行 MOV to CR3 指令更新 PDPT 基址 (CR3 指向 PDPT)
- 执行 MOV to CRO 指令修改了 CRO.CD,CRO.NW 或者 CRO.PG 位,从而引起加载 PDPTE
- 执行 MOV to CR4 指令修改了 CR4.PAE,CR4.PSE,CR4.PGE 或者 CR4.SME 位,从而引起加载 PDPTE
- 在 guest-linear address 转换为 guest-physical address 的过程中,处理器访问 guestpaging structure 表项内的地址,它们属于 GPA
3)guest分页机制下GPA的转换
分页机制下,完成整个 guest 访问内存操作会引发一系列的 GPA 转换 HPA 过程。假设 guest 使用 IA-32e 分页模式 (IA32_EFER.LMA = 1,CR4.PAE = 1,CRO.PG =1 ),并且使用 4K 页面
完成这个内存访问操作一共需要进行 5 次 GPA 到 HPA 的转换(N=MAXPHYADDR)
- CR3 寄存器的 bits N-1:12 提供 PML4T 基址。在定位 PML4T 时需要对 PML4T 基址进行 GPA 转换。成功转换 HPA 后得到 PML4T 的物理地址,再由 PML4E index 查找 PML4E
- PML4E 的 bits N-1:12 提供 PDPT 基址。在定位 PDPT 时需要对 PDPT 基址进行 GPA 转换。在成功转换 HPA 后得到 PDPT 的物理地址,再由 PDPTE index 查找 PDPTE
- PDPTE 的 bits N-1:12 提供 PDT 基址。在定位 PDT 时需要对 PDT 基址进行 GPA 转换。在成功转换 HPA 后得到 PDT 的物理地址,再由 PDE index 查找 PDE
- PDE 的bits N-1:12 提供 PT 基址。在定位 PT 时需要对PT 基址进行 GPA 转换。在成功转换 HPA 后得到 PT 的物理地址,再由 PTE index 查找 PTE
- PTE 的 bits N-1:12 提供 4K page frame 基址。这个 page frame 基址加上 guest-linear address 的 offset 值 (bits 11:0) 得到目标 GPA 值。处理器将这个 GPA 转换为 HPA 得到最终的物理地址,从而完成 guest 内存的访问
在这一系列的 GPA 转换过程中,任何一个环节都可能会产生 EPT violation 或者 EPT misconfiguration 而导致 VM-exit 发生;也可能由于 guest paging structure 而引发 guest 产生 #PF 异常,从而使得 guest 处理 #PF 异常处理例程或者由于 #PF 异常直接或者间接导致 VM-exit
总结:
-
当 guest 使用 32 位分页模式时,guest 的内存访问操作需要 3 次 GPA 转换。CR3 寄存器内的 PDT 基址需要进行 GPA 转换,PDE 内的 PT 基址需要进行 GPA 转换,以及合成的 GPA 需要进行转换
-
当 guest 使用PAE分页模式时,guest 的内存访问操作同样需要 3 次 GPA 转换。PDPTE 寄存器内的 PDT 基址需要进行 GPA 转换, PDE 内的 PT 基址需要进行 GPA 转换,以及合成的 GPA 需要进行转换。
在 PAE 分页模式下,guest 执行 MOV to CR3 指令更新 CR3 寄存器 (也包括更新 CRO 或 CR4 寄存器某些控制位) 引发对 PDPTE 的加载。因此,加载 PDPTE 表项时也会进行 GPA 的转换。
4. EPT paging-structure
这个页表结构只能由 VMM 进行设置,将 GPA 转换为 HPA。guest 软件不知道它的存在,即 guest 软件不能设置 EPT paging-structure
查询 IA32_VMX_EPT_VPID_CAP 寄存器的 bit 6 来确定是否支持 4 级页表结构,为 1 时指示 EPT 支持 4 级页表结构。每个 EPT 页表大小为 4K,每个 EPT 页表项为 64 位宽
- EPT PML4T (EPT Page Map Level-4 Table) ,表项为 EPT PML4E。
- EPT PDPT (EPT Page Directory Pointer Table),表项为 EPT PDPTE。
- EPT PDT (EPT Page Directory Table) ,表项为 EPT PDE。
- EPT PT (EPT Page Table) ,表项为 EPT PTE。
EPT支持三种页面:
- lG页面,IA32_VMX_EPT_VPID_CAP[17] = 1 时处理器支持 1G 页面。PDPTE 的 bit7 允许置 1 使用 1G 页面
- 2M页面,当IA32_VMX_EPT_VPID_CAP[16] = 1时处理器支持 2M 页面,PDE 的 bit7 允许置 1 使用 2M 页面
- 4K页面,PDPTE[7] = PDE[7] = 0时使用 4K 页面,PTE 提供 4K 物理页面地址
5. EPTP(Extended Page Table Pointer 扩展页表指针)
提供 EPT 页表结构顶层的 PML4T 物理地址,即 EPT4TA (EPTP[N-1:12]),这个物理地址属于 HPA
- bit 2:0:设置 EPT paging structure 使用的内存类型,UC(uncacheable:0);WB(writeback:6);EPTP 所支持内存类型可从IA32_VMX_EPT_VPID_CAP 寄存器 bit 8与bit 14查询
- bit 5:3:设置 EPT 页表的 walk 长度,即访问 EPT 页表的级数,必须为 3(表示要经过 4 级页表的 walk),EPT 支持 4 级 EPT 页表可从 IA32_VMX_EPT_VPID_CAP 寄存器 bit 6 查询
- bit 6:EPT 页表项的 dirty 与 accessed 标志开启位,当 IA32_VMX_EPT_VPID_CAP[21]=1 时,处理器支持 EPT 的 dirty 与 accessed标志位,当 EPTP[6] =1 时将启用 EPT 的 dirty及 accessed 位,EPT 页表项的 bit 8与bit 9 被视为 accessed 与 dirty 标志位
- bits N-1:12:PML4T 的物理地址 (host-physical address) 值。如,当 MAXPHYADDR = 36 时,EPTP 的 bits 35:12 是 PML4T 地址值, bits 63:36 是保留位。
6. 4K页面下的EPT页表结构
4K 页面下,GPA 分为:
- PML4E index (bits 47:39) ,用于在 PML4T 中索引查找 PML4E
- PDPTE index (bits 38:30),用于在 PDPT 中索引查找 PDPTE
- PDE index (bits 29:21) ,这个 index 值用于在 PDT 中索引查找 PDE
- PTE index (bits 20:12) ,这个 index 值用于在 PT 中索引查找 PTE
- Offset(bits11:0),这个 offset 值用于在 4K 页面中定位最终的物理地址
GPA 转换到 HPA 需要经过 4 级 EPT 页表结构 (walk 次数为 4)
GPA->HPA 的查表转换过程:
- 在 PML4T base + PML4E index * 8 中找到 PML4E。PML4E 的 bits N-1:12 提供下一级 PDPT 基址的 bitsN-l:12 位,低 12 位补为 0值
- 在 PDPT base + PDPTE index * 8中找到 PDPTE。PDPTE 的 bits N-1:12 提供下一级 PDT 基址的 bitsN-1:12 位,低 12 位补为 0 值
- 在 PDTbase + PDEindex * 8 中找到 PDE。PDE 的 bitsN-1:12 提供下一级PT基址的 bitsN-1:12 位,低 12 位补为 0 值
- 在 PTbase + PTEindex * 8 中找到 PTE。PTE 的 bitsN-1:12 提供 4K 页面的 bitsN-1:12 位,低 12 位补为 0 值
- 这个 4K 页面基址加上 GPA 的 offset 值 (bits 11:0) 得到最终的 HPA 值,完成 GPA 的转换
7. 参考
- 《x86_x64体系探索及编程(邓志)》
- 《处理器虚拟化技术(邓志)》