虚拟化的三大特征

在1974年Popek和Goldberg发表的虚拟化名篇《Formal Requirements for Virtualizable Third Generation Architectures》中定义了虚拟机(VM)可以被认为是物理机的一种高效隔离的复制,并指出虚拟机应具有的三大特征:

  1. 一致性, 一个运行于虚拟机上的程序,其行为应与直接运行于物理机上的同程序的行为基本一致,只允许有细微的差异,比如在系统时间方面。
  2. 可控性,VMM(虚拟化管理器)对系统资源有完全的控制能力和管理权限,包括资源的分配,监控和回收。
  3. 高效性,绝大多数的客户机指令应该由硬件直接执行而无需VMM的参与。

但是要满足这三点,并非易事,因为系统的指令集架构(ISA)需要相应地满足四个的条件:

  1. CPU能支持多个特权级,并且VM上面运行的指令能在底特权级(比如Ring 3)下正确执行。
  2. 非特权指令(允许用户直接使用的指令)的执行效果不依赖于CPU的特权级。
  3. 敏感指令(对系统资源配置有影响的指令)都是特权指令(不允许用户直接使用的指令)。
  4. 必须支持一种内存保护机制来保证多个虚拟机之间在内存方面的隔离,例如段保护或页保护。

为什么X86架构很难被虚拟化?

虽然X86架构在PC市场占据绝对的垄断地位,但是由于其在初始设计时,并没有考虑到虚拟化需求,所以它对虚拟化的支持不够,特别是它没有满足上面四个条件里面的第三个,其因为是X86的ISA有17条敏感指令(比如LGDT等)不属于特权指令。也就是说,当虚拟机执行到这些敏感指令的时候,很有可能出现错误,将会影响到整个机器的稳定。更困难的是,上面所提出的问题只是X86虚拟化所需要面对的问题的一小部分而已,还有许许多多的问题还未涉及。

下面将分CPU虚拟化,内存虚拟化和I/O虚拟化这三部分来介绍全虚拟化,半虚拟化和硬件辅助虚拟化所采用的相关技术。

CPU虚拟化

CPU虚拟化的目标是使虚拟机上的指令能被正常地执行,而且效率接近物理机。

全虚拟化:主要采用优先级压缩(Ring Compression)和二进制代码翻译技术(Binary Translation)这两个技术。优先级压缩能让VMM和Guest运行在不同的特权级下,对X86架构而言,就是VMM运行在特权级最高Ring 0下,Guest的内核代码运行在Ring 1下,Guest的应用代码运行在Ring 3下。通过这种方式能让VMM截获一部分在Guest上执行的特权指令,并对其进行虚拟化。但是有一些对虚拟化不友好的指令则需要二进制代码翻译来处理,它通过扫描并修改Guest的二进制代码来将那些难以虚拟化的指令转化为支持虚拟化的指令。

半虚拟化:其通过修改Guest OS的代码,使其将那些和特权指令相关的操作都转换会发给VMM的Hypercall(超级调用),而且Hypercall支持Batch(批处理)和异步这两种优化方式,使得通过Hypercall能得到近似于物理机的速度,

硬件辅助虚拟化:主要有Intel的VT-x和AMD的AMD-V这两种技术,而且这两种技术在核心思想上非常相似,都是通过引入新的指令和运行模式,来让VMM和Guest OS能分别运行在其合适的模式下。在实现方面,VT-X支持两种处理器工作方式:第一种称为Root模式(Operation),VMM运行于此模式,用于处理特殊指令,另一种称为Non-Root模式(Operation),Guest OS运行于此模式,当在Non-Root 模式Guest执行到特殊指令的时候,系统会切换到运行于Root模式VMM,让VMM来处理这个特殊指令。

内存虚拟化

内存虚拟化的目标是能做好虚拟机内存空间之间的隔离,使每个虚拟机都认为自己拥有了整个内存地址,并且效率也能接近物理机。

全虚拟化:影子页表 (Shadow Page Table),就是为每个Guest都维护一个“影子页表”,在这个表中写入虚拟化之后的内存地址映射关系,而Guest OS的页表则无需变动,最后,VMM将影子页表交给MMU进行地址转换。

半虚拟化:页表写入法,当Guest OS创建一个新的页表时,其会向VMM注册该页表,之后在Guest运行的时候,VMM将不断地管理和维护这个表,使Guest上面的程序能直接访问到合适的地址。

硬件辅助虚拟化:EPT(Extended Page Table,扩展页表),EPT通过使用硬件技术,使其能在原有的页表的基础上,增加了一个EPT页表,通过这个页表能够将Guest的物理地址直接翻译为主机的物理地址,从而减低整个内存虚拟化所需的Cost。

I/O虚拟化

I/O虚拟化的目标是不仅让虚拟机访问到它们所需要的I/O资源,而且要做好它们之间的隔离工作,更重要的是,减轻由于虚拟化所带来的开销。

全虚拟化:通过模拟I/O设备(磁盘和网卡等)来实现虚拟化。对Guest OS而言,它所能看到就是一组统一的I/O设备,同时Guest OS每次I/O操作都会陷入到VMM,让VMM来执行。这种方式,对Guest而言,非常透明,无需顾忌底层硬件,比如Guest操作的是SCSI的设备,但实际物理机只有SATA的硬盘。

半虚拟化:通过前端(Front-End)/后端(Back-End)架构,将Guest的I/O请求通过一个环状队列传递到特权域(Privileged Domain,也被称为Domain-0)。因为这种方式的相关细节较多,所以会在后文进行深入分析。

硬件辅助虚拟化:最具代表性莫过于Intel的VT-d,AMD的IOMMU和PCI-SIG的IOV(I/O Virtulization)这三个技术。在这里介绍一下VT-d,其核心思想就是让虚拟机能直接使用物理设备,但是这会牵涉到I/O地址访问和DMA的问题,而VT-d通过采用DMA重映射(Remapping)和I/O页表来解决这两个问题,从而让虚拟机能直接访问物理设备。还有,IOMMU和VT-d在技术上有很多相似之处。

总结

 全虚拟化半虚拟化硬件辅助虚拟化
CPU虚拟化二进制代码翻译HypercallVT-x
内存虚拟化影子页表页表写入法EPT
I/O虚拟化模拟I/O设备前端/后端架构VT-d

表1. X86虚拟化技术总结

X86虚拟化技术的未来

随着硬件辅助虚拟化技术不断地发展和优化,将使其在速度和架构方面的优势更明显,但是由于全虚拟化和半虚拟化的一些技术在某些方面还是保持了一定的优势,比如半虚拟化的前端和后端架构和全虚拟化的二进制代码翻译技术。所以,我个人认为今后X86虚拟化技术的发展将会以硬件辅助虚拟化技术为主,同时以全虚拟化和半虚拟化技术为辅.

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐