华为云计算技术与应用
上QQ阅读APP看书,第一时间看更新

1.2.3 虚拟化分类

从资源类型来看,虚拟化主要包括CPU虚拟化、内存虚拟化和I/O虚拟化。而对不同资源类型的虚拟化而言,其发展基本经历了全虚拟化、半虚拟化和硬件辅助虚拟化这3个阶段。

1.CPU虚拟化

在对这些虚拟化阶段进行介绍之前,需要先说明一下虚拟化之前计算机的CPU指令流,如图1-5所示,CPU将特权级分为4个级别:Ring 0、Ring 1、Ring 2、Ring 3。Ring 0拥有最高的级别,一般只给操作系统使用,Ring 1、Ring 2、Ring 3级别依次递减,Ring 3则给普通的应用程序使用。图1-5所示是传统模式下的CPU指令流,对操作系统来说,它运行在Ring 0级别,拥有最高的权限,可以进行修改页表、控制中断和访问底层设备等操作;对应用程序而言,它运行在Ring 3级别,拥有最低的权限。当应用程序执行调用底层的硬件、写文件等关键/核心型操作时,CPU的运行级别会先从Ring 3切换到Ring 0,同时,会调用相应的内核代码执行。当操作系统完成了相关的操作时,CPU级别会从Ring 0调整到Ring 3。而当应用程序执行一些非关键/核心型的操作时,CPU级别会一直处在Ring 3,不会进行级别的切换。

图1-5 传统模式下的CPU指令流

如果没有引入虚拟化技术,那么在传统模式下,CPU指令的运行并不会产生任何冲突,而采用了虚拟化技术后,就会带来一个问题:默认情况下操作系统运行在Ring 0级别,管控所有的硬件资源,而新增的虚拟化层也需要运行在Ring 0级别以管控所有的硬件资源,这种情况下,应该是谁运行在Ring 0级别呢?

(1)CPU全虚拟化

图1-6对给出了上述问题的答案,图1-6是全虚拟化下的CPU指令流,可以看到底层是硬件,虚拟化层运行在Ring 0级别中,虚拟机操作系统运行在Ring 1级别中,应用运行在Ring 3级别中,这样就能够保证虚拟化层能够获取对所有硬件资源的管控权,当虚拟机运行一些用户指令时,就能不经过虚拟化层直接运行。当运行一些核心指令时,若出现异常,虚拟化层就会捕获这个异常,进行二进制翻译,从而完成这些核心指令的执行,通过异常—捕获—二进制翻译这种方式,会消耗较多的系统资源,降低性能,但在一定程度上解决了Ring 0级别运行冲突问题。

图1-6 全虚拟化下的CPU指令流

课外扩展

二进制翻译:二进制翻译技术将源平台的二进制代码翻译为目标平台的二进制代码,这样代码的执行不仅能够适应相应的平台,而且具备较高的运行效率。

(2)CPU半虚拟化

为了解决全虚拟化中存在的资源消耗大、性能低等问题,提出了 CPU 半虚拟化这一方案。在CPU半虚拟化中,虚拟化层仍然处于Ring 0级别,虚拟机操作系统仍然处于Ring 1级别,应用则处于Ring 3级别。不同于全虚拟化,半虚拟化对虚拟机操作系统进行了相应的修改,这样对于核心指令的执行,就不用异常捕获、二进制翻译,而是通过Hypercall这一调用方式进行核心指令的执行,相比于全虚拟化,其性能有所提升。半虚拟化下的CPU指令流如图1-7所示。

图1-7 半虚拟化下的CPU指令流

(3)CPU硬件辅助虚拟化

不论是全虚拟化还是半虚拟化,其虚拟化功能的实现都需要通过虚拟化层,为了获得更高的性能和更好的体验,硬件辅助虚拟化应运而生。硬件辅助虚拟化的思想是将虚拟化层和虚拟机操作系统放到不同的模式下,CPU硬件辅助虚拟化指令流如图1-8所示,将虚拟机操作系统放到非ROOT模式下,将虚拟化层放到ROOT模式下,当虚拟机操作系统运行非核心指令(用户指令)时,可以直接下发指令到硬件执行,不需要经过虚拟化层。当虚拟机操作系统运行核心指令时,系统会从非ROOT模式切换到ROOT模式,这一过程也被称为VM-Entry,经由虚拟化层将指令处理完成之后,系统会从ROOT模式切换到非ROOT模式,这一过程也被称为VM-Exit。对于应用的用户指令,则会直接执行。目前主要有英特尔的VT-x和AMD的AMD-V这两种CPU硬件辅助虚拟化技术。

图1-8 CPU硬件辅助虚拟化指令流

2.内存虚拟化

内存虚拟化如图1-9所示,需要了解以下几个概念。

① GVA:Guest Virtual Address,虚拟机虚拟地址。

② GPA:Guest Physical Address,虚拟机物理地址。

③ HVA:Host Virtual Address,主机虚拟地址。

④ HPA:Host Physical Address,主机物理地址。

图1-9 内存虚拟化

内存虚拟化和 CPU 虚拟化类似,经历了内存全虚拟化、内存半虚拟化和内存硬件辅助虚拟化这3个主要发展阶段。

(1)内存全虚拟化

如图1-10所示,内存全虚拟化需要完成GVA到GPA、GPA到HVA、HVA到HPA的地址转换工作。其中,GVA到GPA的地址转换是由虚拟机的系统页表进行的,HVA到HPA的地址转换工作是由主机的系统页表完成的,此时,VMM需要完成GPA到HVA之间的地址转换工作。这样可以将主机物理层中非连续性的地址整合成逻辑上连续性的内存地址提供给虚拟机使用,并保障每台虚拟机能够得到一个逻辑地址从零开始的连续内存地址段,同时,能够保证每台虚拟机获得的地址空间在逻辑上是隔离的。

图1-10 内存全虚拟化

采用内存全虚拟化技术,需要经过多层地址的转换,在一定程度上会导致计算机性能的损耗,此时,为了解决性能损耗大的问题,提出了内存半虚拟化。

(2)内存半虚拟化

如图 1-11 所示,内存半虚拟化是通过影子页表技术实现的。影子页表记录了GVA到HPA之间的地址映射关系,在很大程度上降低了性能的损耗,对每台虚拟机而言,其进程中有内存维护的页表,当在虚拟机中对页表进行相关修改时,这种动作就会被VMM截获,在这之后,VMM要重新计算出新的GVA到HPA之间的地址映射关系,更改相应的页表项。相比于内存全虚拟化方式,采用影子页表这种方式实现内存半虚拟化,减少了内存地址之间的多层转换,在一定程度上提高了效率,但这种方式也有其缺陷,如实现方式比较复杂。同时,对每台虚拟机而言,都需要去维护一套自己的页表,当虚拟机数量较多时,会增加内存的负担,此外,VMM 截获时陷入中断等动作也会加重CPU的负担。

图1-11 内存半虚拟化

(3)内存硬件辅助虚拟化

内存硬件辅助虚拟化可以通过扩展页表(Extended Page Table,EPT)来实现。通过使用硬件技术,在原有的页表的基础上增加一个EPT,用于记录GPA到HPA的映射关系。VMM预先把EPT设置到CPU中。虚拟机修改虚拟机页表,无须VMM干预。地址转换时,CPU自动查找两张页表完成GVA到HPA的转换,从而减少整个内存虚拟化所需的开销。

3.I/O虚拟化

I/O虚拟化有I/O全虚拟化、I/O半虚拟化和I/O硬件辅助虚拟化3种。

(1)I/O全虚拟化

在I/O全虚拟化中,虚拟化的工作由Hypervisor进行相应的模拟,包括I/O设备寄存器和读写操作的模拟。这种方式的优点是可以直接使用相应的驱动,无须修改相应的操作系统,缺点是每次都需要进行相应的中断,对性能有一定影响,同时,Hypervisor需要模拟不同的硬件。

(2)I/O半虚拟化

在I/O半虚拟化中,需要在虚拟机的操作系统中添加相应的前端驱动,同时在Hypervisor层上需要添加相应的驱动程序。相较于 I/O 全虚拟化,采用 I/O 半虚拟化方式需要修改相应的虚拟机操作系统,但是性能比全虚拟化好一些。

(3)I/O硬件辅助虚拟化

I/O硬件辅助虚拟化也被称为I/O透传。在这种方式中,虚拟化功能是在硬件层面完成的,直接将硬件层面的虚拟I/O资源提供给不同的虚拟机使用,不用经过Hypervisor这一层。采用I/O硬件辅助虚拟化,其性能比前面两种方式好,目前主要有英特尔的VT-d、AMD的IOMMU和PCI-SIG的IOV这3种I/O硬件辅助虚拟化技术。