侧边栏壁纸
博主头像
landery博主等级

行李箱里装不下我想去的远方

  • 累计撰写 45 篇文章
  • 累计创建 26 个标签
  • 累计收到 6 条评论

目 录CONTENT

文章目录

云计算_01_虚拟化技术_CPU虚拟化

landery
2022-04-23 / 0 评论 / 0 点赞 / 93 阅读 / 4,631 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-05-05,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

CPU虚拟化

目前大多数人都将虚拟化分为全虚拟化半虚拟化硬件辅助虚拟化。但是对划分的原因,也不太了解。因此本文主要是讨论一下关于虚拟化的分类以及原因。

虚拟化分类原因

我们都知道,cpu指令系统分为特权指令和非特权指令。以X86系统为例,共分为Ring0-Ring3 4个级别。其中Ring0 处于内核级别,拥有最高权限,Ring1-Ring3运行在用户级别,虽然CPU指令级别这样划分,但是操作系统不一定用完所有的指令级别,例如Linux只使用了Ring0 和 Ring3两个级别,分别在内核态和用户态运行。

  1. 为什么需要CPU虚拟化?

    • 没有虚拟化:操作系统处于最高的特权级,可直接访问所有物理资源(寄存器、内存、I/O外设等)。
    • 虚拟化:操作系统变为客户机操作系统(虚拟机操作系统)而降级到非最高特权级,这时,其试图访问关键资源的指令就成为了敏感指令。VMM 会通过各种手段,保证这些敏感指令的执行能够触发异常,从而陷入到VMM进行模拟,VMM将客户机操作系统的访问定位到VMM为其设计的虚拟的资源上以防止对VMM自身的运行造成破坏。
  2. CPU虚拟化要做什么?

    • CPU虚拟化的重点:由VMM和(物理)CPU共同完成敏感指令的模拟。
    • 对于虚拟机执行的非敏感指令,物理CPU直接解码处理,并将相关的效果直接反映到物理寄存器上;对于虚拟机执行的敏感指令,让虚拟机里执行的敏感指令陷入然后被VMM模拟,而不要直接作用于真实硬件上。

在非x86系统中经典的虚拟化做法,就是令VMM拥有超级特权,其指令都想运行在Ring0级别;令Guest OS运行在Ring1-Ring3级别,当其运行特权指令时,这些指令会产生异常并被VMM捕获到,VMM会在核心级别中模拟执行,再将运行结果返回给Guest OS。这种经典的虚拟化技术被称为特权解除和陷入模拟,以IBM的Power系列为代表。

其次,我们将操作系统会涉及底层公共资源调用的一些运行指令称为敏感指令。显然这些敏感指令在虚拟化的结构中也需要陷入到Ring0的核心级别执行,否则会导致不同GuestOS之间的资源调用冲突。大型服务器如PowerPC和SPARC运行的RISC指令集中,所有的敏感指令都属于特权指令,因此可以采用上面说的特权解除和陷入模拟技术完美的进行虚拟化实现。

但对于X86的CISC指令集而言,存在17条非特权指令的敏感指令,这些指令被GuestOS在Ring1级别执行时,会被直接执行,无法产生异常从而陷入Ring0处理,也就导致无法采用经典技术进行虚拟化, 因此下文将介绍的一系列方案都是为了解决此问题而设计的。

image.png

在上述问题中,涉及到三个主要对象,GuestOS、VMM和硬件CPU的指令集,其中VMM是新插入的对象,修改起来很方便,但OS和CPU改起来就难一-些了。解决方案的思路也由此分为三个方向:

  1. 只变动VMM。好处是兼容性最强,OS和CPU都不用动,但效率肯定是最低的。这种方案也被称为CPU Full-Virtualization,全虚拟化。
  2. 改动GuestOS。好处是效率较高,但缺点是Windows肯定不愿意干,只能在Linux上做些文章,而且使用特制的OS,会带来一些可扩展性方面的隐患。这种方案也被称为CPU Para-Virtualization ,半虚拟化。
  3. 改动CPU指令集。这个改动就只有Intel/AMD能做了,好处是对Guest OS可以不需变动,兼容Linux和Windows,VMM的使用效率也较高。缺点也有,就是增加了一些虚拟化指令和结构,导致对CPU的利用率下降,在部分应用场景下的性能表现不如前面的CPUPara-Virtualization方案。这种方案也被称为硬件辅助虚拟化技术HVM ( Hardware-assisted Virtualization Machine)。随着Intel/AMD的服务器CPU全部更新换代对其提供支持,HVM已经成为当前虚拟化技术应用的主流,硬件辅助虚拟化。

于是就出现了三个虚拟化种类,分别是全虚拟化(改动VMM)、半虚拟化(改动Guest OS)、硬件辅助虚拟化(改动CPU指令集)

CPU全虚拟化

CPU Full-Virtualization(CPU FV),这种思路又被细分为三种解决方案。Emulation、Scan-and-Patch和 Binary Translation。其中Emulation是根本解决方案,而Scan-and-Patch和 Binary Translation可以理解为是Emulation在X86体系上使用的扩展实现方案。CPU Full-Virtualization由于实现较为简单,早在上世纪末就已经出现,是最早期的x86虚拟化技术。

  1. Emulation:主要应用在跨平台进行虚拟机模拟。由于Guest OS和底层系统平台不同,尤其是指令集的不同,比如你需要在X86系统上模拟ARM的系统,那么VMM所做的工作就是实现将Guest OS的指令读取后进行模拟,模拟出结果后,再返回,逐条执行不区分用户指令和敏感指令,由于每条命令都陷入到Ring 0级别中,所以也就解决了之前的敏感指令的问题。代表产品就是Linux上的QEMU和Bochs,其中QEMU还可以通过KQEMU来提升处理速度。
  2. Scan-and-Patch:主要思路是将Guest OS的指令提前扫描一遍,找到其中的敏感指令,然后在VMM层中生成对应的补丁指令,同时将敏感指令修改为跳转指令,指向补丁指令。这样当执行到敏感指令时,会跳转到VMM中的补丁指令执行,在将结果返回给Guest OS。代表产品是Oracle的开源虚拟机系统VirtualBox,目前主要应用于在主机上进行虚拟机的模拟,服务器使用较少。
  3. Binary Translation,二进制转换,主要思路是将Guest OS的指令段进行整段翻译,将其中敏感指令替换成Ring 0中的对应特权指令,然后在执行的同时翻译下一个指令段。代表产品VMWare WorkStation、Microsoft virtual PC主机虚拟化工具,以及早期VMWare的 ESX/GSX系列服务器虚拟化系统,目前服务器上很少使用。

由于CPU FV受性能影响,在服务器上目前被逐渐淘汰。主要代表产品VirtualBox和VMware WorkStation大都应用于主机虚拟化的一些开发测试环境中。

CPU半虚拟化

CPU Para-Virtualization称为半虚拟化。此技术以Hyper-V和Xen作为代表,但VMware的ESX Server和Linux的KVM两种主流的虚拟化产品也都支持Para-Virtualization,另外还有基于Linux的Lguest和基于Windows的CoLinux等各具特色的小型产品也都通过部分Para-Virtualization技术来实现操作系统的虚拟化。CPU Para-virtualization以下简称CPU PV。

CPU PV技术实现的主要原理如下,首先VMM公布其一些称为 Hypercalls的接口函数出来,然后在 Guest OS中增加根据这些接口函数修改内核中的代码以替代有问题的17条敏感指令执行系统调用操作。修改后的指令调用通常被称为 Hypercalls,Guest OS可以通过 Hypercalls 直接调用VMM进行系统指令执行,相比较前面提到的陷入模拟方式极大的提升了处理效率。

然而CPU PV修改操作系统内核代码的方式带来了对Guest OS的很多使用限制,如只有Hyper-v可以支持 Para-Virtualization方式的Windows Server作为Guest Os,另外由于KVM/Xen/VMware vMI/Hyper-V各自Hypercalls代码进入Linux内核版本不同,因此采用Linux作为Guest OS时也必须关注各个发行版的Linux内核版本情况。KVM是2.6.20,VMI是2.6.22,Xen是2.6.23,Hyper-V是2.6.32。

由于CPU PV方式对Guest OS的限制,应用范围不是很广,但是由于其技术上的系统调用效率提升,仍然被部分开发与使用者所看好,在某些特定场景也有一定存在需求。

CPU硬件辅助虚拟化 HVM

硬件辅助虚拟化就是从硬件出发,修改CPU指令集来解决敏感指令的问题。当前的X86厂商主要是Intel和AMD两家,这两家都提出了自己的CPU虚拟化技术,Intel推出的技术是在Xeon CPU上的 VT-x,和Itanium CPU上的 VT-i,AMD提出的是AMD-V。下面以VT-x为例介绍HVM技术,其他的两种类似。

VT-x在CPU操作方面有两个主要特性:

  1. 是增加了VMCS (Virtual-Machine ControlStructure)数据结构和13条专门针对vM的处理指令,用于提升VM切换时的处理效率。
  2. 通过引入Root/Non-Root操作模式解决前面遇到的Guest OS敏感指令无法陷入问题。

13条新指令中包括5条用于VMCS维护, 4条用于VMX管理,2条用于VMX对TLB(TranslationLook aside Buffer)的管理,2条用于Guest OS调用。

Root/Non-Root 操作模式将原有的CPU操作区分为VMM所在的Root操作与VM的Non-Root操作,每个操作都拥有Ring0-Ring3的所有级别。通过VMCS数据结构指向Guest OS到VMM的操作切换。

image.png

VMM在初始化的时候会在物理内存中为每个VM开辟一段空间用于存储对应的一个VMCS数据结构,可以理解一个VMCS就对应一个vCPU。VM切换时,VMM可以通过VMCS 指针方便的在不同VMCS间进行跳转,有效的提升了CPU使用效率。

VT-x技术还包含以下三个重要内容:

  1. EPT (Extended Page Table): 由VMM控制的一种新页表结构,主要目的为了在保证多个VM访问物理内存相互隔离的同时,提升大块内存的读写效率。
  2. FlexMigration:灵活迁移技术,用于VM在使用不同型号CPU的物理服务器间进行迁移,促成了类似vMotion的vM迁移技术的发展。
  3. FlexPriority :灵活优先级技术,用于优化 CPU中断处理过程中对TPR(Task-Priority Register)的使用,提高中断处理效率。

VT-x和AMD-v等技术的出现,解决了前面两种纯软件方案进行X86虚拟化时,CPuFull-Virtualization性能低和Para-Virtualization的Guest OS兼容性差问题.随着服务器CPU两三年一换代的更新速度,当前的主流x86服务器已经都可以支持VT-x/AMD-v等技术,因此HVM成为当前云计算 laaS服务器虚拟化的主流。主要的几款vMM产品Xen/VMware ESXi/KVM/Hyper-V都已经能够支持HVM功能。

CPU虚拟化总结

虚拟化分类,个人理解是从CPU虚拟化角度来分类较为恰当,虽然从I/O设备虚拟化的角度来说,也有所谓的I/O FV、I/O PV,但是个人觉得从CPU角度来区分全虚拟化、半虚拟化、硬件辅助虚拟化较为恰当。接下来会继续介绍虚拟化技术02_I/O虚拟化。

参考文献

感谢以下作者的分享,文章大部分内容来自以下参考文献。

0

评论区