内存虚拟化硬件基础——EPT

名词解释

  • Guest态:Intel 手册中的非根模式(None-Root Mode)
  • Host态:Intel手册中的根模式(Root Mode)
  • EPT:Intel手册中的扩展页表,Extended Page Table
  • PML4:Intle手册中的4级结构页表的第一级(Page Map Level 4)
  • PDPT:页目录指针表,Page Directory Pointer Table
  • PD:页目录,Page Directory
  • PT:页表,Page Table

前言

  • EPT是Intel为实现内存虚拟化专门增加的硬件特性。实现内存虚拟化主要解决的问题是,Guest态的CPU对物理内存的读写,不能直接写到HPA,需要VMM进行模拟来实现,即VMM虚拟Guest CPU需要访问的物理内存。
  • Guest 态CPU,仍然要支持实模式,保护模式,保护模式下的三种分页模式以及各种地址转换的表,比如PDPT,PD,PT等等。当涉及到物理内存的读写时,如果是根模式就直接读写,但这里是非根模式,它是要模拟一个CPU,所有对于主机上资源的访问都要被监控或者被模拟,包括物理内存。因此传统的设计思路是非根模式下CPU对物理内存的访问被认定为敏感指令,会退回到根模式交给VMM处理,VMM负责将这段物理内存转化成主机上真实的物理内存然后返还给虚机CPU使用。
  • 传统的设计思路有两个问题:一是非根模式下的CPU访问物理内存很频繁,会频繁的触发CPU模式切换,开销非常大;二是退回到根模式后,VMM对客户机物理地址的模拟要经过GPA -> HVA -> HPA三个阶段的地址转换,软件实现效率低。
  • 影子页表解决了第二个问题,它的出发点是减少地址转换。基本原理是:当处于非根模式下的CPU有修改CR3的动作时(通常是下一个进程被调度的时候),意味着有页目录地址会被加载到CR3(如果是32-bit分页模式),这时VMM截获这个动作,退回到根模式,VMM中维护了一个hash链表,专用于存放CR3中页目录地址对应的影子地址,VMM拿到页目录地址后计算该地址的hash值并作为key放到hash表中,然后申请一个主机上的物理地址作为页目录的地址放到CR3寄存器中,同时主机上的物理地址也被存放到hash表中,CR3原有的应该被保存的页目录地址被VMM保存起来,当虚拟机进程被调度出去的时候,CR3中应该被保存的页目录地址要放回到进程控制块中,这时VMM会截获这个动作并提供之前保存的页目录地址。VMM在CR3寄存器被修改的过程中,偷天换日,将本应该放到CR3中的地址拿走,替换成自己申请的地址,当客户机要从CR3中取回这个地址时替换回去。影子页表的示意图如下,由于每个进程都有自己的地址空间,因此都有一个CR3的内存值,所以影子页表的Hash链表中,一个Node节点对应存放一个进程的页目录地址。
    在这里插入图片描述
  • KVM通过监听CR3寄存器读写,为每一个在VMX模式下使用CR3加载页表的进程,在主机上维护了对应的页目录和页表(注意,影子页表的说法并不准确,因为主机上除了页表,还维护了页目录,这些都是影子)。CR3指向的是进程的一个内存地址空间,所以主机需要为VMX模式下的所有进程,都维护这样一份影子页目录和影子页表,放在hash表中,当进程被调度,页表被加载时,从hash表中找到对应的影子页目录的地址放到CR3中。影子页表通过增加内存维护成本,减少地址转换的路径。有一定效果,但每个进程的页表和页目录的维护成本也不小,因此进一步引入了EPT机制
  • EPT克服了影子页表使用软件维护GVA->HPA地址转换的缺点,它使用硬件来维护GPA->HPA,因此效率大大提高。而且,影子页表虽然缩短了地址转换路径,但每次虚机进程访问CR3时,都会引起VMX的模式切换,开销很大。影子页表在每次加载和卸载的时候都会引起模式切换,而EPT减少了这种开销,EPT只在缺页的时候才引起VMX模式切换,一旦页表建立好之后,EPT就不再有模式切换的开销,虚机内存的访问一直在客户态。

EPT页结构

  • Intel处理器设计了EPT的页结构用来将保存GPA到HPA的映射,因此说EPT是硬件支持的,EPT的页结构如下图的咖啡色部分,整个页结构有4级,和4-level分页模式的结构一模一样,只有存放PML4 Table物理地址的地方不一样,4-level将PML4 Table的地址存放在CR3寄存器中;EPT没有,EPT中PML4 Table的地址被称为EPTP,它存放在VMCS中的VM-execution 控制字段。VMM用VMCS来配置VM的运行环境以及控制VM的运行。进入客户态之前,VMM首先通过特殊指令VMPTRLD加载VMCS内存地址的指针,其中就包括EPTP字段,因此理论上EPTP是针对每个虚机而言的,EPT对每个虚机是可以配置的。有人会问,客户态的所有物理地址都是GPA,那么存放EPT物理地址的EPTP是什么地址呢?个人理解,这个地址不是GPA,它非常特殊,因为它是在未进入客户态之前由VMM加载的,不可能是GPA,应该是主机上的地址HPA。
    在这里插入图片描述

EPTP —— Extended Page Table Pointer

  • EPTP(extended-page-table pointer)是VMCS中存放EPT页表物理地址的字段,它的格式如下:
    在这里插入图片描述
  • EPTP指向的下一级是PML4 Table,它是页对齐的,因此至少是4K对齐,所以低12 bit没有用,可以拿来复用,其中bit 6是和脏页跟踪有关的标志位,它被置1时,CPU访问EPTP指向的任何下级页结构的时候,Access位都会被置1,最后的页表项中的Dirty位会被置1。
  • EPTP bit 12之上的字段用来存放下一级表PML4 Table的物理地址。

PML4E —— Page Map Level 4 Entry

在这里插入图片描述

  • Accessed flag:bit 8访问标志位,当EPTP中的accessed and dirty flags置位时,CPU每次通过EPT多级页表结构转换物理地址时,只要使用到这一级的页表项,就需要将Accessed flag置位。
  • Physical address:bit 12 ~ bit (N-1),存放下一级页表结构的物理地址。

PDPT —— Page Directory Pointer Table

在这里插入图片描述

  • Accessed flag:bit 8访问标志位,当EPTP中的accessed and dirty flags置位时,CPU每次通过EPT多级页表结构转换物理地址时,只要使用到这一级的页表项,就需要将Accessed flag置位。
  • Physical address:bit 30 ~ bit (N-1),存放下一级页表结构的物理地址。

PDE —— Page-Directory Entry

在这里插入图片描述

  • Accessed flag:bit 8访问标志位,当EPTP中的accessed and dirty flags置位时,CPU每次通过EPT多级页表结构转换物理地址时,只要使用到这一级的页表项,就需要将Accessed flag置位。
  • Physical address:bit 12 ~ bit (N-1),存放下一级页表结构的物理地址。

PTE —— Page Table Entry

在这里插入图片描述

  • Accessed flag:bit 8访问标志位,当CPU对该页表项指向的物理页又访问操作时,读写操作都算,会将Dirty flag置位。
  • Dirty flag:bit 9脏页标志位,当CPU对该页表项指向的物理页进行写操作时,会将Dirty flag置位。
  • Physical address:bit 12 ~ bit (N-1),存放下一级页表结构的物理地址。

EPT地址转换

  • EPT地址转换的输入有两个,一个是客户机的物理地址GPA(Guest Physical Address),一个是PML4 Table的物理地址,指向了EPT的页结构。当运行在客户态下的CPU访问CR3指向的页结构时,如果涉及到对物理内存的内容的访问,就会触发EPT地址转换,Intel硬件接管这个任务,完成转换,步骤如下:
  1. 根据VMCS中的EPTP字段找到页结构的起始地址:PML4 Table的地址,加载对应的PML4 Table内容,PML4 Table中由512个条目,将GPA的高9位作为索引,在PML4 Table中索引PDPT(Page Directory Pointer Table)的地址。
  2. 根据PDPT地址加载PDPT内容,也是512个条目,将GPA的次9位作为索引,在PDPT中索引PDT(Page Directory Table)的地址。
  3. 根据PDT地址加载PDT内容,同样是512个条目,将GPA从高到低的第3个9位作为索引,在PDT中索引页表的地址。
  4. 根据页表的地址加载其内容,同样是512个条目,将GPA从高到底的第4个9位作为索引,在页表中找到页的地址。
  5. 根据页地址,加载页的内容,将GPA的低12位作为索引,在页中找到最终要访问的页的内容。
  • 对EPT页结构中的访问,如果页不存在或者出错,可能导致缺页异常,如果VMCSVM-execution controlEPT-violation字段为0,页访问出错会触发VM-exit,分下面两种情况:
  1. EPT violation,这种情况典型场景就是页结构不存在,类似于主机上的缺页异常(#PF Page Fault),发生这种异常后CPU会退回到内核态,同时会在VM-exit qualification字段记录EPT violation异常的详细信息。EPT页结构和主机上普通的页结构类似,页表都是异常触发,逐渐填充页结构的过程。在客户态模式下,这是EPT violation异常;在主机上,这就是异常。怎样判断页结构不存在呢?通过查看每个描述页结构条目的低3位(read/write/execute),如果低3位全都为0,就表示指向的下一级页结构不存在(not-present)。这是非页表的情况,如果是页表(Page Table),它的条目的最低位是Present位,可以单独用来表示指向的页是否存在。
  2. EPT misconfiguration,另一种会导致页异常的情况,它是在页结构存在的情况下(页结构低3位的任何一位非0),发现页结构的内容设置不恰当而产生的异常,这种情况是EPT的页结构真的出了配置上的问题而产生的异常,对于EPT misconfiguration,并不会记录详细信息。VM-exit qualification字段为未定义值。
    注意,异常不同于中断,硬件异常后会跳转到相应的异常处理例程,在处理完之后会重新运行异常处的指令而非下一条,EPT violation和主机页表中的Page Fault一样,都属于异常。对于使用EPT页表或者主机页表的用户程序来说,当访问到不存在的页结构触发了异常后,硬件会处理然后重新执行,用户程序是感觉不到的。

EPT转换开关

  • EPT是Intel为支持虚拟化的开发的硬件特性,因此使能开关应该在虚拟化相关的域中,secondary processor-based VM-execution contro是VM-execution的一个控制字段,它位于VMCS(Virtual Machine Control State)中,它是一个32bit的字段,其中一个bit就是EPT使能位。

EPT转换时机

  • EPT使能之后,客户态模式下所有物理地址都被识别成guest-physical address,CPU对这些地址的访问需要通过EPT转换成主机上的物理地址。EPT地址转换时机就是CPU访问GPA的时侯。为了让客户机的程序感觉不到自己处于客户态,EPT需要支持实模式,保护模式和保护模式下所有的分页模式,所有这些模式下对物理地址的访问,都要触发GPA地址转换。实模式下,进程的所有线性地址都是GPA;保护模式下,进程页表的物理地址,页目录地址,页表地址,这些都是GPA。
  • 以保护模式下32-bit分页模式为例(CR0.PG = 1)为例,介绍客户态模式下物理页查询过程中的地址转换,假设MMU的输入是一个32bit的进程线性地址:
  1. MMU首先从CR3中取出页目录地址,访问该页目录的内容,此时页目录地址被认为是GPA,会触发EPT页表的查询,返回的HPA指向页目录。MMU取32-bit线性地址的高10位作为索引,在页目录中查找并获取页表地址
  2. MMU拿到页表地址后,访问该页表内容,此地址也被认为是GPA,会触发EPT页表查询,返回一个HPA指向页表。MMU取32-bit线性地址的中间10位作为索引,在页表中查找对应的条目,获取物理页地址
  3. MMU拿到物理页地址后,访问该页内的偏移,再次触发EPT页表查询,返回HPA指向主机的物理页。MMU取32-bit线性地址的最低12位作为偏移,读写物理页的内容。
    注意,EPT转换只有在客户态真正访问GPA内容时才发生。MMU单单获取GPA时不会触发地址转换。

Q&A

Q:EPT violation和EPT misconfig都是缺页故障,两者有什么区别吗?
A:从字面意思看,misconfig主要表达的是配置错误,因此当页结构中的entry被写入了违反intel手册规范的值,可能出现misconfig,比如entry中的保留位被设置了就会触发EPT misconfig。还有种情况是内存只允许写不允许读(bit0:0,bit1:1)。写这种内存页会触发EPT misconfig,比如virtio-pci的notify配置空间地址。还有一种是MMIO类型内存的写,会产生EPT misconfig,比如对virtio-pci的common config空间的device_status写数据。
对于violation,它主要就是缺页故障,当内存读写都不被允许时(bit0:0,bit1:0)就会触发,也可以说,缺页故障中,除了misconfig余下的都是violation故障。

  • 11
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

享乐主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值