在虚拟化技术中涉及的有三个核心角色,分别是宿主机,客户机和虚拟机监控器。宿主机,也被称为 Host,一般指代物理主机。客户机,也被称为 Guest,是指运行在宿主机上的虚拟机。而负责为客户机准备虚拟 CPU,虚拟内存等虚拟资源,并同时对客户机进行管理的模块,就是虚拟机监控器 (Virtual Machine Monitor , VMM)。
陷入模型的核心思想是:将 Guest 运行的指令进行分类,一类是安全的指令,也就是说这些指令可以让 Host 的 CPU 正常执行而不会产生任何副作用,例如普通的数学运算或者逻辑运算,或者普通的控制流跳转指令等;另一类则是一些“不安全”的指令,又称为“Trap”指令,也就是说,这些指令需要经过 VMM 进行模拟执行,例如中断、IO 等特权指令等。
现代的 X86 芯片提供了 VMX 指令来支持虚拟化,并且在 CPU 的执行模式上提供了两种模式:root mode 和 non-root mode,这两种模式都支持 ring 0 ~ ring 3 三种特权级别。VMM 会运行在 root mode 下,而 Guest 操作系统则运行在 non-root mode 下。
在虚拟机 Guest 启动的时候,宿主机 Host 肯定是运行在保护模式的,也就是说,分页机制已经开启。但是 Guest 仍然运行在实模式下,所以 Guest 会采用虚拟 8086 模式运行。在这种情况下,因为 Guest 是直接操作 GPA 的,所以 VMM 只需要做好 GPA 到 HPA 的转换就行了。
当 Guest 进入保护模式后,Guest 也会维护自己的页表,我们把这个页表叫做虚拟机页表,也就是 gPT。显然 gPT 是不能将 Guest 的虚拟地址转换成真正的物理地址的,这就需要 VMM 来做一次处理,将 gPT 替换为自己精心准备过的页表,也就是影子页表,sPT。
不过,影子页表的维护和切换的效率十分低下,为了解决这个问题,硬件厂商提供了 EPT,它可以协助 MMU 进行第二次页表转换。也就是说,MMU 负责将 GVA 转换为 GPA,然后 EPT 再将 GPA 转换为 HPA,来完成真正的内存页映射。
此文章为7月Day12学习笔记,内容来源于极客时间《编程高手必学的内存知识》