虚拟化概述

在第一节我们了解到了虚拟机分类的几种方法,同时,列了一些先修的知识点 ,在了解了这些知识点之后才能顺利的进行下面的了解。

这一节会提到虚拟化中的关键概念,有了这些概念,才便于立即后面的基于软化和硬件的虚拟化章节。

指令

VMM接管所有的敏感指令,当需要运行的时候,陷入到VMM的接管中,执行敏感指令。VMM的重点气质也就围绕在指令。

敏感指令

操作特权资源的指令,包括修改虚拟机的运行模式或者下面物理机的状态,例如关机指令;为了VMM可以完全控制系统资源,它不允许直接执行虚拟机上操作系统的敏感指令。也就是说,敏感指令必须在VMM的监控审查下进行,或者经过VMM来完成。

特权指令

系统中有一些关键操作指令只能在最高特权级别上执行,它们一般被称为特权指令,特权指令仅仅在当前的特权级别为零时(CPL=0)才会执行。如果在非特权级别上试图执行特权指令,将生成一个一般保护异常(这通常会生成一个应用程序错误),而非特权指令则可以在任何一个权限级别执行。

虚拟化漏洞

如果敏感指令都是特权指令,则它是可虚拟化的结构,否则无法在所有的敏感指令上触发异常,则不是一个可虚拟化的结构,称作“虚拟化漏洞”

指令的模拟

VMM运行在最高特权级,也就是可以执行敏感指令,而客户机操作系统运行在非高特权级,所以敏感指令要嵌入到VMM中执行。

模拟寄存器:为让客户操作系统认为自己能够运行特权级别的指令,使用虚拟寄存器来模拟相应的效果,而虚拟寄存器往往是在内存中;

虚拟上下文:由于操作系统进行调度要保存上下文,而虚拟机中的敏感指令更是要保存在虚拟寄存器中,所以虚拟上下文要保留更多的信息。

虚拟处理器:从客户操作系统的角度,希望在运行的处理器需要具备与其“期望”的物理处理器一致的功能和行为,为了满足这种期望,甚至可以允许客户操作系统的修改,比如KVM。

对称处理器技术的模拟

脱离和对多个处理器的物理依赖,甚至可以将Guest的操作指令分配到物理机的多个处理器上,只要完成等效的效果即可;另外还需要负责处理多个处理器的同步问题和初始化问题。

内存虚拟化

引入Guest物理地址空间,也就是物理内存和虚拟机看到的内存的一种转换,同时还需要负责分页和分段的转换。

I/O 虚拟化

外设的驱动程序,接收来自其他模块的请求,然后外设按照预定义好的方式完成事情;在虚拟化的情况下由于外设的实际资源是有限的,为了满足多个Guest访问外设的需求,VMM必须通过I/O虚拟化复用有限的资源。这就是IOMMU。

I/O 虚拟还包括设备的发现、对于设备的访问截取和设备模拟。而访问截取则需要根据设备的访问来决定,这其中又包括对于设备可以具有端口I/O资源、MMIO资源以及提供中断、DMA。

当然我们先考虑不是直通的情况,也就是非直接分配给GuestOS。

对于设备可以具有端口I/O资源

客户机中运行的IO指令是否陷入到VMM中由IO位图(bitmap)来指定:如果IO指令访问的某一端口地址在IO bitmap中对应位为1,则该条指令导致VM-Exit,否则意味着该端口可以被客户机直接所访问而无需VMM的介入。

I/O位图决定了I/O端口,VMM通过把设备的所有端口I/O中关闭,这样当Guest访问的时候,物理处理器就爆出一个保护异常,VMM就可以捕获异常,然后将请求发送给设备模拟器进行模拟;相反,如何Guest OS可以直接访问,那么VMM可以把该设备所属I/O 从I/O 位图打开,这样处理器就会把访问发送到系统总线,最终到达物理设备而不必模拟。

对于设备可以具有MMIO资源

假如设备可以提供MMIO资源(MMIO(Memory mapping I/O)即内存映射I/O,它是PCI规范的一部分,I/O设备被放置在内存空间而不是I/O空间。从处理器的角度看,内存映射I/O后系统设备访问起来和内存一样。这样访问AGP/PCI-E显卡上的帧缓存,BIOS,PCI设备就可以使用读写内存一样的汇编指令完成,简化了程序设计的难度和接口的复杂性。),那么由于MMIO也是物理地址空间的一部分,而物理地址空间的访问通过页表控制,因此在Host 的真实页表里面,VMM只要把映射到该MMIO的页表项设为无效,当指令试图访问的时候,Host cpu就抛出一个缺页异常,接着VMM接管,通过遍历Guest OS的页表就可以可以打开真实页表的映射。

对于设备可以提供中断

非直接分配给Guest设备产生中断,VMM提供机制,供设备模拟器在接收到物理中断并需要触发中断时,可以通知到虚拟中断逻辑,然后虚拟中断逻辑模拟一个虚拟中断的注入;相反。对于直接分配给Guest OS 的设备,VMM物理中断处理喊出在接收到物理中断后,辨别出中断源输入那个Gest,然后通知Guest 的虚拟中断逻辑。

对于设备可以提供DMA

DMA允许设备绕过处理器直接目标内存,如果Guest驱动程序未经修改,则设备模拟器接到的DMA目标地址是Guest 的地址,因此,VMM就只需要提供一种机制,让设备模拟器知道各种地之间的转换关系,从而可以把Guest物理地址映射成自己的虚拟地址,真正的支持DMA目标地址的访问。

设备模拟

既然VMM无论如何都需要在Guest OS中提供一个特定的驱动系统,那么可以把这个驱动程序简化,我们称Guest OS 中的Driver 是FE(Front-end), 而VMM中驱动程序称为BE(Back-End)。

所谓可以简化,就是说FE将其他请求通过Guest 之间的特殊通信机制,直接发送给BE,而BE处理之后返回给前者。

这种简化与传统的流程相比,传统的Driver涉及到多个寄存器的操作,使得VMM要截获每一个寄存器访问并进行相应的模拟,也就导致上下文切换,但是这种方式基于请求/事务,能在很大程度上减少上下文切换的频率。

IOMMU,如果是直通,那么VMM不需要为此进行模拟,Guest中的驱动程序也可以无缝地操作目标设备,这种从I/O虚拟化具有最优的性能,但是这收到硬件的限制,比如需要主板和CPU都有IOMMU。

设备共享

设备模拟器运行在I/O 特权环境中,环境中有物理驱动程序,同时相关设备模拟器作为物理驱动程序的一个客户存在,比如用户进程。环境中大多数物理驱动程序都是可以自动接收多个客户或者进程的请求,从而达到物理资源的复用。同时,每个VM都由自己专属的设备模拟逻辑,也就是在I/O特权环境中,存在相对应的用户进程。

按虚拟平台分类

完全虚拟化

 客户无修经过修改,x86 从历史上,分为软件辅助的完全虚拟化(当时虚拟化不完整的替代方法,把不支持的特殊指令的二进制级别翻译为支持的指令)和硬件辅助的完全虚拟化,

类虚拟化

 在源代码级别修改命令以回避虚拟化漏洞的方法来是VMM能够对物理资源实现虚拟化。在完全虚拟中遇到的难以避免的虚拟化漏洞,类虚拟化则使用的方法是修改操作系统内核的代码,使得操作系统完全避免这些难以虚拟化的指令。
 类虚拟化为了解决如何插入VMM,典型做法是修改OS的处理器相关代码,让操作系统主动让出特权级别,而运行在次一级别上,这样当GuestOS 试图执行特权指令时,保护异常被触发,从而提供截获点供VMM来模拟。
 类虚拟化还有一个好处,因为内核代码可以被改变,所以进一步优化I/O,也就是说不是去虚拟设备,因为太多的寄存器虚拟会降低性能,相反,类虚拟化可以定义出高度优化的I/O协议,可以完全基于事务,达到接近物理机的速度。

Hypervisor 模型

在Hypervisor模型中,VMM可以看作一个完备的操作系统,VMM与传统的OS不同,是转为虚拟化设计的,VMM直接管理所有的物理资源,同时由于VMM具有虚拟化功能,因此物理资源虚拟化的效率会高一些;

有得必有失,VMM由于是完全拥有物理资源,因此,就需要相应设备的驱动,由于驱动开发的工作量太大,因此只会选择一个服务器的设备进行开发,所以,所以往往面向的是服务器市场。

宿主模型

比如VIrtualBox,VMware

物理资源是Host操作系统. 由于传统的OS不是为了虚拟化而设计的,因此本身并不举报虚拟化功能,实际的虚拟化由VMM提供。

VMM在这种模型中通常是HOST OS 中独立的内核模块,还包括一些用户态进程,通常把Guest作为Host的一个进程参与调度。

Host模型的优缺点就是与Hypervisor模型相反,Host模型可以充分的利用Host的设备驱动,VMM无需重新实现Driver,而缺点就是如果Host 的内核是不安全的,那么虚拟机的安全不仅依赖的于VMM的安全,也依赖Host OS。

混合模式

比如UNRAID

就是宿主模型以及Hypervisor模型的混合。VMM依然位于底层,拥有所有的物理资源,但是让出大部分I/O 设备的控制器,将他们交到一个运行在特权虚拟机中的特权操作系统来控制。那么虚拟化的任务VMM来承担,I/O虚拟化则由VMM和特权操作系统共同完成。

当然,也是由坏处的,由于特权操作系统运行在虚拟机上,当需要提供服务的时候,VMM就必须切换到特权OS,产生上下文切换的开销,因此,当切换比较频繁时,就会造成性能明显下降。因此,处于出于性能考虑,除了调度程序和电源管理,更多的功能放到VMM中实现。