系列目录 漫谈虚拟化技术
上个月,我曾经和一个龙芯的支持者聊过关于龙芯和云计算的关系。虽然我个人还是非常支持龙芯,但是在谈到龙芯的未来,我深有顾虑,原因有二:其一,是缺乏经验丰富的工程师团队,虽然胡老师研究毛选的水平相当顶尖,但是我个人觉得身为龙芯项目带头人的他在芯片设计上面的造诣很难列于世界顶尖。其二,和本文是密切相关的,就是在低功耗和移动方面,龙芯的MIPS架构好比RISC的代表IBM的Power,而ARM架构和CISC的代表Intel的X86有几分类似,虽然IBM的Power架构在早期由于RISC的原因,在速度上面极为领先,但是由于X86在所支持软件方面的优势,使Intel能投入几倍的资源在研发上面,使得它不仅在市场上处于垄断,而且在速度上面直追Power芯片。这个在PC时代发生的故事我希望不要在云计算时代重演。 (因为在CPU产业上面的研究不是很深入,如果我说了什么不合适的,请见谅。我个人也希望龙芯能成功) 接下来就跟大家讲解一下上面提到的X86架构的虚拟化技术。 虚拟化的三大特征在1974年Popek和Goldberg发表的虚拟化名篇《Formal Requirements for Virtualizable Third Generation Architectures》中定义了虚拟机(VM)可以被认为是物理机的一种高效隔离的复制,并指出虚拟机应具有的三大特征:
但是要满足这三点,并非易事,因为系统的指令集架构(ISA)需要相应地满足四个的条件:
为什么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在技术上有很多相似之处。 总结
表1. X86虚拟化技术总结 X86虚拟化技术的未来随着硬件辅助虚拟化技术不断地发展和优化,将使其在速度和架构方面的优势更明显,但是由于全虚拟化和半虚拟化的一些技术在某些方面还是保持了一定的优势,比如半虚拟化的前端和后端架构和全虚拟化的二进制代码翻译技术。所以,我个人认为今后X86虚拟化技术的发展将会以硬件辅助虚拟化技术为主,同时以全虚拟化和半虚拟化技术为辅. 本篇结束,下篇将关注VMware ESX的架构! 参考资料: |
剖析系统虚拟化(2)- X86虚拟化技术
最新推荐文章于 2024-03-01 17:01:06 发布