CPU 虚拟化技术初探

 

我们日常开发过程中都会用到各大云服务(阿里云, GCP 等)的 VPS 和自己电脑上的虚拟机(VMware, PVE 等).

作为上层的软件开发者, 我们不需要了解其底层实现的细节就可以享受虚拟化带来的便利, 谈及其中最核心的 CPU 虚拟化技术时也常常轻描淡写地一笔带过.

最近出于好奇检索了更多资料, 整理一些 CPU 虚拟化相关的资料在此.

总览

在没有硬件虚拟化的情况下, x86 指令集有 Ring0-Ring3 4个特权等级, OS内核运行在 Ring0, 用户态程序运行在 Ring3, 虚拟内存机制为每个进程提供了独立的地址空间.

这种情况下, 因为缺少了能隔离多个内核态的 CPU 指令, 想要在同一台机器上运行多个独立的 OS 就变得困难. QEMU 通过 recompile 实现了完全 User-mode 下的全系统模拟, 但是代价是巨大的性能损失. (我还实现过一个纯解释执行的 QEMU 青春版)

为了解决上述问题, Intel 和 AMD 都提出了自己的硬件虚拟化方案(VT 和 SVM), 以下以 Intel VT-x 为例.

VMX 相关指令

VT-x 中, Intel 引入了一系列相关指令用于支持硬件虚拟化的实现.

Intel MnemonicDescription
INVEPTInvalidate Translations Derived from EPT
INVVPIDInvalidate Translations Based on VPID
VMCALLCall to VM Monitor
VMCLEARClear Virtual-Machine Control Structure
VMFUNCInvoke VM function
VMLAUNCHLaunch Virtual Machine
VMRESUMEResume Virtual Machine
VMPTRLDLoad Pointer to Virtual-Machine Control Structure
VMPTRSTStore Pointer to Virtual-Machine Control Structure
VMREADRead Field from Virtual-Machine Control Structure
VMWRITEWrite Field to Virtual-Machine Control Structure
VMXOFFLeave VMX Operation
VMXONEnter VMX Operation

VM Monitor 和 Guest 的状态切换VM Monitor 和 Guest 的状态切换

VT-x 引入了两种额外的 CPU 模式:

  1. VMX Root 操作模式: 通过 VMXON 指令进入, 此时主机成为 Hypervisor
  2. VMX Non-Root 操作模式: Guest 所处的模式, 在 VMX Root 模式下通过 VMLAUNCH 进入, 限制了敏感资源的访问, 访问敏感资源会触发 VM exits 退出到 VMX Root

VMX 生命周期如下:

  • 软件通过 VMXON 指令进入 VMX 操作模式。
  • VMM 可以通过 VM entries 进入 Guest VM(单次只能执行一个 VM),VMM 通过 VMLAUNCH (第一次进入 VM)与 VMRESUME (从 VMM 中恢复到 VM)指令来使能 VM entry,通过 VM exits 重获控制权。
  • VM exits 通过 VMM 指定的入口点移交控制权,VMM 对 VM 的退出原因进行响应后通过 VM entry 返回到 VM 中。
  • 当 VMM 想要停止自身运行并退出 VMX 操作模式时,其通过 VMXOFF 指令来完成。

VMX 根模式与非根模式VMX 根模式与非根模式

VMX Root 就类似 Ring0 权限, VMX Non-Root 中运行的 Guest 就类似运行在 Ring3 下. Guest 访问敏感资源的请求(特权寄存器)会被交给 VMX Root 的 VM-exits Handler 处理. VMX Root 可以调度多个 Guest 同时运行.

VMCS

VMCS(Virtual Machine Control Structure) 是用于储存 Guest 和 Host 状态的一个结构体, 主要储存寄存器状态(用于保存/恢复现场)以及控制 VM 行为的一些 Flag.

VMCS 不能直接读写, 需要通过 VMREADVMWRITE 指令修改.

VMCSVMCS

VMCSVMCS

EPT

EPT(Extended Page Table, 拓展页表) 与页表类似, 提供了地址转换的功能.

CPU 能将 VMX Non-Root 模式下的物理内存读写根据 EPT 映射成对主机物理地址的读写.

在常用的虚拟机中, 每个 Guest 内的物理地址都会被独立的映射到主机上不同的物理地址区块上, 实现互不干扰, 独立运行.

EPT TranslationEPT Translation

与主机中的页表类似, EPT 也支持访问控制 (Read, Write, Execute), 访问控制功能后续在 Hypervisor-assisted debugger 中发挥了重要作用: 可以给正常运行的程序移除指定区域的 RWE 权限, 这样程序执行到对应位置时则会触发 VM-exits, 可以 trace 被调试程序的行为, 并进一步修改程序.

更多实际应用

硬件虚拟化技术开始主要用于在一台 bare metal 上运行多个 OS, 近年来也被用于软件调试, 二进制安全等领域:

  • 最常见的虚拟机 (如 VMware, VirtualBox, Hyper-V, PVE, ESXi)
  • Hypervisor 辅助的调试器 HyperDbg
  • 操作系统及杀毒软件 基于虚拟化的安全 (沙盒)

更多资料

CTF Wiki 上的虚拟化介绍: https://ctf-wiki.org/pwn/virtualization/basic-knowledge/cpu-virtualization/#reference

自己实现一个 Hypervisor: https://rayanfam.com/topics/hypervisor-from-scratch-part-1

本文采用 CC BY-NC-SA 4.0 许可协议发布.

作者: lyc8503, 文章链接: https://blog.lyc8503.net/post/hypervisor-explore/
如果本文给你带来了帮助或让你觉得有趣, 可以考虑赞助我¬_¬