虚拟化(2):虚拟化概述

1. 虚拟化概述

不论采用何种虚拟化, VMM对物理资源的虚拟可以归结为三个主要任务: 处理器虚拟化内存虚拟化I/O虚拟化

1.1 可虚拟化架构和不可虚拟化架构

​ 前文给出了虚拟化的三种特征: 同质、高效和资源受控。如果不能满足的话,就可以说这个VM是失败的,或者说VMM的骗术并不高明。为了研究可虚拟化的条件,需要从指令开始着手。

​ 大多数的现代计算机体系结构都有两个或两个以上的特权级,用来分隔系统软件和应用软件. 系统中有一些涉及管理关键系统资源的指令称为特权指令, 这些指令只能在最高特权级上能够正常运行. 如果在非最高特权级上运行, 就会触发一个异常, 处理器会陷入到最高特权级交由系统软件来处理.

​ 虚拟化世界里有类指令称为敏感指令, 即操作特权资源的指令, 包括修改虚拟机的运行模式或者下面物理机的状态. 所有的特权指令都是敏感指令, 但不是所有的敏感指令都是特权指令.

为了让VMM完全控制系统资源, 它不允许直接在VM中执行敏感指令. 所有的敏感指令必须经过VMM或者在VMM的审查下完成. 因此, 将VMM运行在系统ing的最高特权级下, 而将VM运行在非最高特权级上, 当客户机操作系统因执行敏感指令而陷入到VMM时, VMM模拟执行引起异常的敏感指令, 这种行为称为"陷入再模拟".

​ 通过"陷入再模拟"实现虚拟化的方法是有前提条件的, 所有的敏感指令都必须是特权指令, 否则虚拟化的正确性难以保证. 因此, 如果一个体系上存在敏感指令不属于特权指令, 那么其就存在虚拟化漏洞.(有些计算机体系结构是存在虚拟化漏洞的, 就是说它们不能很高效地支持系统虚拟化.)

其实这里关于为什么"敏感指令必须全是特权指令"还是有些不太理解, 但是这个小细节需要自行补充相关知识. 我觉得可能是书籍翻译的问题, 这里敏感和特权的定义没有阐述的很清楚.

虚拟化漏洞虽然可能存在, 但是可以采取一些办法来避免这些漏洞, 譬如通过模拟的方法, 每次取出一条指令, 模拟出这条指令地执行效果,再取出下一条指令, 这种方法还允许模拟不同体系结构的虚拟机,但是性能太差.

1.2 处理器模拟

处理器模拟是VMM中最核心的部分, 因为访问内存和I/O的指令本身就是敏感指令, 所以内存虚拟化和I/O虚拟化也都依赖于处理器虚拟化

1.2.1 指令的模拟:

  • 虚拟寄存器
  • 上下文
  • 虚拟处理器

在没有虚拟化的环境里, 操作系统直接访问物理处理器, 处在最高的特权级别. 当VMM接管物理处理器后, VM上的操作系统降级在非最高特权级别上运行, 此时试图访问关键资源的指令就称为了特权指令.

​ VM试图访问关键资源时, 该请求并不会真正发生在物理寄存器上, 相反VMM会模拟物理处理器的行为, 使用对应的虚拟的寄存器

1.2.2 中断和异常注入:

VMM对于异常的虚拟化需要完全遵循物理处理器对于各种异常条件的定义, 再根据虚拟处理器当时的内容, 来判断是否需要模拟出一个虚拟的异常, 并注入到虚拟环境中.

​ VMM通常会在硬件异常处理程序模拟代码中进行异常虚拟化的检查, 无论是哪一种, VMM都需要区分两种原因:

  1. 虚拟机自身对运行环境和上下文的设置违背了指令正确执行的条件
  2. 虚拟机运行在非最高特权级别, 由于虚拟化的原因触发的异常.

​ 而对于物理中断的触发来自于特定的物理中断源, 虚拟中断的触发则来自于虚拟设备的模拟程序. (包括内部中断源的模拟和外部虚拟设备的模拟)

1.3 内存虚拟化

​ 从操作系统的角度,物理内存有两个基本特点: 物理地址从0开始和内存地址连续性(或者说在一定的粒度上连续). 在虚拟化中, VMM必须对VM所访问的内存进行一定程度上的虚拟化.

​ 在虚拟环境中, 内存虚拟化面临的问题是: 物理内存要被多个客户机操作系统同时使用, 但物理内存只有一份, 物理起始地址0显然也只有一个, 无法同时满足所有VM的OS内存从0开始的要求. 由于使用了内存分区的方式, 内存的连续性要求能够得到满足, 但是内存的使用效率非常不灵活. 在这种情况下, VMM要做的就是"欺骗"VM, 让VM以为它所访问的内存是从0开始并且连续的, 这个欺骗过程就是内存虚拟化.

内存虚拟化的核心在于引入一层新的地址空间: 客户机物理地址空间

1.4 I/O虚拟化

​ 外设是通过一组I/O资源(端口I/O或者是MMIO)来进行访问的, 所以设备相关的虚拟化又被称为I/O虚拟化.

2. VMM的分类

2.1 按虚拟平台分类

  1. 完全虚拟化(Full Virtualization): 客户机操作系统察觉不到是运行在一个虚拟平台上, 虚拟的是现实存在的平台.
  2. 类虚拟化(Para-Virtualization): VMM虚拟的平台是现实中并不存在的, 需要对这类VM进行适当修改使之适应虚拟环境.

类虚拟化通过在源代码级别修改指令以回避虚拟化漏洞, 而且类虚拟化由于不是模式真实的设备, 因此可以自定义出高度优化的I/O协议, 这种I/O协议完全基于事务, 可以达到近似物理机的速度. 因为现有的系统和设备, 往往为了通用性存在很多冗余, 类虚拟化的自定义在某些时候反而能有不错的性能表现.

2.2 按VMM实现结构分类

1. Hypervisor模型

​ 在该模型中, VMM可以被看做是一个完整的操作系统,不同之处在于,VMM是为虚拟化设计的,还具有虚拟化功能。首先,所有的物理资源如处理器、内存和I/O设备都归VMM所有;其次VMM需要向上提供虚拟机用于运行客户机操作系统,因此VMM还负责虚拟环境的创建和管理。

​ Hypervisor模型的架构:

  • P(processor): 处理器管理代码(负责物理处理器的管理和虚拟化)
  • M(Memory): 内存管理代码(负责物理内存的管理和虚拟化)
  • DM(Device Model):负责I/O设备的虚拟化
  • DR(Device Driver):负责I/O设备的驱动

有得必有失,Hypervisor模型在拥有虚拟化高效率的同时也暴露出其缺点,由于VMM完全拥有物理资源,因此VMM需要进行物理资源的管理,包括设备的驱动,我们知道,设备驱动开发的工作量非常大。因此实际中,基于Hypervisor的VMM一般有选择地支持一些I/O设备。

2. 宿主模型

​ 宿主模型中,物理资源由宿主机操作系统管理。宿主机操作系统是传统的操作系统,譬如Windows和Linux,这些传统操作系统并不是为虚拟化而设计的,因此本身并不具备虚拟化功能,实际的虚拟化功能由VMM提供。VMM此时通常是宿主机操作系统独立的内核模块,有些实现包含用户态进程,如I/O虚拟化的用户态设备模型。

​ 宿主模型可以充分利用现有操作系统的设备驱动程序,VMM无需为各类I/O设备重新实现驱动程序。然而VMM需要调用宿主机操作系统提供的服务接口获取资源进行虚拟化,效率和功能都会受到影响。

3. 混合模型

​ 混合模型是上述两种模式的集合体。VMM位于最底层,拥有所有的物理资源。与Hypervisor模式不同在于,VMM会将大部分I/O设备的控制权交给一个运行在特权虚拟机中的特权操作系统来完成。处理器和内存的虚拟化依然由VMM来完成,而I/O的虚拟化则由VMM和特权操作系统共同完成。

  • DM和DR处在特权操作系统中
  • P和M则依然由VMM负责

2.3 现实案例:KVM(Kernel-based Virual Machine)

KVM最早由Qumranet公司开发, 在2006年10月出现在Linux内核的邮件列表上, 并于2007年2月集成到Linux2.6.20内核中, 成为内核的一部分

​ KVM出现之初, 有人认为KVM是宿主模式, 而随着更多的虚拟化功能加入到Linux内核中, 越来越多的人认为Linux已经是一个Hypervisor, 因此KVM是Hypervisor模型.


虚拟化(2):虚拟化概述
https://www.torch-fan.site/2022/07/16/虚拟化-2-虚拟化概述/
作者
Torch-Fan
发布于
2022年7月16日
更新于
2022年11月15日
许可协议