• 979阅读
  • 0回复

x86硬件辅助虚拟化之迷 [复制链接]

上一主题 下一主题
离线天道酬勤
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2016-05-30

x86硬件辅助CPU虚拟化的过程

注:首先需要明确一点,英特尔的CPU虚拟化采用的技术别称为VT-x,但VT-x中并不仅仅只包含CPU虚拟化,还包括中断虚拟化和内存虚拟化等内容,而AMD在AMD-V在官方资料中也是把CPU、内存和中断等虚拟化技术全部放在了SVM技术规范中进行统一讲解的。

传统的IA32处理器架构并不是十分可靠的虚拟化架构,为了解决这个问题,英特尔通过VT-x技术对原有架构进行了扩展补充,其核心操作模式示意图如图11。

图11 支持VT-x技术的虚拟化架构

VT-x技术引入了两种专为虚拟化打造的操作模式,称为根操作模式(VMX Root Operation)和非根操作模式(VMX Non-Root Operation),其中VMM运行在根操作模式下,而客户操作系统则运行在非根操作模式下,每个模式都存在Ring0-3四个特权级别,所以在VT-x中,对特权级别进行描述时必须说明是在根模式还是在非根模式下。对照前面我们讲解的软件完全虚拟化时的示意图我们不难发现,客户操作系统(Guest OS)所运行的特权级别发生了变化,由Ring1变成了Ring0,而原本工作在Ring0的VMM则被注明是工作在根操作模式下的Ring0上(有一些文档中称之为Ring-1)。相信仔细阅读上期虚拟化文章的读者朋友,不难理解英特尔为什么要制造出两个新的操作模式来,因为客户操作系统重新回到了Ring0上(当然这里是非根模式下的),而且经过英特尔对相关指令的重新设计,使得原本不能通过先陷入后模拟的方式执行的指令都可以顺利执行,而在根模式下,所有指令的执行和传统IA-32相比不会有任何变化,从而保证了原有软件和虚拟环境的正常运转。

图12 英特尔VCPU创建,运行和退出示意图

在硬件辅助CPU虚拟化中,陷入的概念已经被VM-Exit操作取代,它意味着从非根操作模式切换到根操作模式,对应的从根操作模式切换回非根操作模式被称为VMEntry。我们在上一期的文章中提到了CPU虚拟化的基本原理,这里我们有必要温习一下。里面提到了“CPU虚拟化是为物理机器上的每一个虚拟机提供一个或者多个虚拟CPU(简称VCPU),每个VCPU分时复用物理CPU,在任意时刻一个物理CPU只能被一个VCPU使用,VMM要在整个过程中合理分配时间片以及维护所有VCPU的状态”,这里谈到的VCPU状态维护其实就是VCPU的上下文切换,而VCPU的环境结构主要有硬件使用部分和软件使用部分组成,软件部分主要由VMM控制,主要包括VCPU的状态信息,浮点寄存器等,而硬件使用部分指的是英特尔和AMD用来描述和保存VCPU状态信息的内存空间,它们分别存放在被称为VMCS(Virtual-Machine Control Structure,虚拟机控制结构)和VMCB(Virtual-Machine Control Block虚拟机控制块)的数据域中,VMCS和VMCB都是最大不超过4KB的内存块。在进行VCPU上下文切换的时候,要涉及硬件部分和软件部分两方面,而本篇主要是介绍和硬件部分关系密切的VMCS和VMCB。

介绍完两种操作模式,下面我们就以英特尔平台为例来对新指令和虚拟机控制结构进行进一步介绍。

如果暂不考虑EPT(内存虚拟化)相关指令,英特尔为VMX和VMCS共引入了十条指令,并且分别有明确的分工和定义,下面先简单介绍一下引入指令。

图13 每个VMCS对应一个虚拟CPU(假设每个虚拟机只用一个虚拟CPU)

VMX ON和VMX OFF是用来打开和关闭VMX操作模式的指令,在默认情况下,VMX是关闭的,当需要使用这个功能时,可以通过VMX ON随时进行VMX模式。在进入VMX模式后,VMM又会通过VMLAUNCH或者VM RESUME指令产生VMEntry,使CPU从根操作模式切换至非根操作模式,从而开始运行客户机相关软件。在运行软件的过程中如果发生中断或者异常,就会激活VM-Exit操作,此时CPU又进行了一次模式切换,只不过这次是切换到根操作模式,在处理完成后一般又会返回非根操作模式去运行客户机软件。如果不想运行虚拟机软件的时候,则会利用VMX OFF关闭VMX操作模式。除此之外,还有一条VMCALL指令,因为这个指令涉及到大家不常用的SMM(系统管理模式)VM Exit,所以这里就不多作介绍了。

而在VMCS方面,每个VMCS对应一个虚拟CPU(VCPU),在虚拟化软件的设置中,我们一般设置一个虚拟机对应一个虚拟CPU。

图14 VMCS的内部结构

而VMCS在使用时要与逻辑CPU绑定,一个逻辑CPU在任意的一个时间点都只能绑定一个VMCS,而VMCS在不同的时刻是可以和不同的逻辑CPU绑定的。VMCS用来绑定和解除绑定的命令分别是VMPTRLD和VMCLEAR,而用来对VMCS数据域进行读写的指令分别为VMREAD和VMWRITE。除此之外还有一条VMPTRST的指令,是指将当前的VMCS状态值存储到一个指定的内存空间。

最后我们来谈一谈VMCS结构,看一看这个4KB大小的内存空间里都有些什么。

在偏移0处是VMCS版本标识,偏移4处是VMX失败指示,这里将存放因VM-Exit执行不成功而产生的VMX失败原因,而我们下面要详细介绍的是在偏移8处的VMCS数据域。我们可以把这个数据域分成三部分:状态区域,控制区域和VM退出信息区域(见表1)。

表1
状态区域
客户机状态域

宿主机状态域

控制区域
VM执行控制域

VM-Exit控制域

VM-Entry控制域

VM退出信息区域
VM-Exit信息域

客户机状态域是用来保存非根模式VCPU运行状态的,当发生VM-Exit时,VCPU的当前运行状态将写入客户机状态域(并非全部,另有一部分为VMM控制的软件部分,下同),而当VM-Entry发生时,CPU会将客户机状态域中保存的状态加载到自己身上从而保证顺利地切换到非根操作模式。而宿主机状态域则用来保存在根操作模式下CPU的运行状态,它仅仅在发生VM-Exit时将状态值写入CPU中,而在VMEntry发生时不进行保存操作。

控制区域中VM-Entry控制域和VM-Exit控制域是对VM-Entry和VM-Exit操作的具体行为进行控制规定的地方,如VM-Entry控制域中的MSR加载、事件注入控制和VM-Exit控制域中的主机地址空间等,而VM执行控制域的作用是控制VM-Exit操作发生时的行为,比如某些敏感指令、异常和中断是否产生VM-Exit操作,也就是说只要是在这个控制域里列明的指令,都是可根据实际情况进行VM-Exit操作的开启和关闭操作的。当然没有写入控制域的一些指令也会产生VM-Exit操作,那些指令可以称之为无条件VM-Exit指令,凡是产生VM-Exit操作的指令都会由VMM来模拟完成。

VM-Exit信息域比较简单,存放的是VM-Exit产生的原因和具体的分类细化指标。

快速回复
限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
上一个 下一个