30 两个世界,一个CPU:虚拟化中的root操作和非root操作

# 30 两个世界,一个CPU:虚拟化中的root操作和非root操作

现代英特尔处理器的虚拟化依赖于通过虚拟机扩展(VMX,Virtual Machine Extensions)建立的执行环境的严格划分。这种分离定义了两个操作世界:VMX root模式和VMX非root模式,从而在CPU的严格控制下实现安全、高效的虚拟化。

当KVM模块设置了CR4.VMXE并执行VMXON时,VMX操作开始,将CPU转换为root模式并启用VMX指令。在客户机运行之前,KVM为每个虚拟CPU(vCPU)分配并配置一个虚拟机控制结构(VMCS,Virtual Machine Control Structure),其中包含客户机和主机处理器状态以及执行和控制字段。

客户机执行以VMLAUNCH开始或以VMRESUME恢复。CPU从VMCS加载客户机状态并进入VMX非root模式。在这种模式下,客户机操作系统直接在硬件上运行,同时与主机隔离,即使在 0 环(ring 0)执行也是如此。

大多数客户机指令在执行时无需虚拟机管理程序干预,除非被VMCS控制所禁止。特权指令、I/O端口访问、控制寄存器修改或外部中断会触发VM退出。在VM退出期间,CPU将客户机状态保存到 VMCS 中,恢复主机状态,记录退出原因,并将控制权交还给在root模式下运行的KVM。

KVM读取退出原因并处理该事件。CPU状态更改、特权操作或中断处理直接在内核中处理,而设备访问或用户驱动的事件则转发给QEMU等用户空间监视器。如果vCPU线程被抢占,KVM会保存客户机上下文并让步给Linux调度器。

在vCPU之间切换时,KVM使用VMPTRLD加载新vCPU的专用VMCS。每个vCPU维护自己的VMCS,切换涉及更新活动VMCS指针以确保客户机之间的隔离。Linux调度器将vCPU视为普通线程,允许在vCPU之间或客户机与主机进程之间进行公平调度。

重新调度后,当再次选择vCPU时,KVM会根据需要更新VMCS,并使用VMRESUME恢复客户机执行。

VMCS在转换过程中维护处理器状态,包括通用寄存器、控制寄存器、指令指针、标志和执行控制。对VMCS字段的精心管理可最大限度地减少开销、保持隔离并确保客户机行为正确。

客户机和主机之间的内存一致性通过INVEPT和INVVPID等指令维护,从而能够选择性地使地址映射和TLB条目失效,而无需完全刷新处理器。

当客户机终止时,KVM发出VMXOFF,结束VMX操作并将CPU恢复为正常的主机执行。

通过root模式和非root模式之间的结构化划分、每个vCPU的专用VMCS结构以及KVM转换的协调,现代处理器提供了安全高效的硬件虚拟化。

image-20250617135403945

上次更新: 2026/07/14, 19:37:40

社区交流

讨论与留言

前往 GitHub Issues →

本留言区仅对应当前文章,欢迎补充观点、提出问题或帮助修正文中疏漏。 留言由 GitHub/Gitalk 提供,需要使用 GitHub 登录。

最近更新
第 1 课:专栏导论与安全边界
07-01
第 3 课:安装编译与调试环境
07-01
第 4 课:第三方库下载、编译与依赖管理
07-01
更多文章>