对于一般 RISC 处理器,如 MIPS,PowerPC 以及 SPARC,敏感指令肯定是特权指令,唯 x86 例外。
2.1 经典的虚拟化方法
经典的虚拟化方法主要使用“特权解除” (Privilege deprivileging) 和“陷入-模拟” (Trap-and-Emulation) 的方式。即:将 Guest OS 运行在非特权级(特权解除),而将 VMM 运行于最高特权级(完全控制系统资源)。解除了 Guest OS 的特权后,Guest OS 的大部分指令仍可以在硬件上直接运行,只有当执行到特权指令时,才会陷入到 VMM 模拟执行(陷入-模拟)。其早期的代表系统是 IBM VM/370
关于这些指令的详细分析可以参见:"Analysis of the Intel Pentium's Ability to Support a Secure Virtual Machine Monitor"
2.3 x86 虚拟化方法
鉴于 x86 本身的局限,长期以来对 x86 的虚拟化都是通过软件方式实现,后来 Intel 和 AMD 都引入各自的硬件虚拟化技术来弥补处理器的缺陷。
2.3.1 基于二进制翻译 (BT) 的全虚拟化 (Full virtualization)
其主要思想是在执行时将 VM 上执行的 Guest OS 之指令,翻译成 x86 ISA 的一个子集,其中的敏感指令被替换成陷入指令。翻译过程与指令执行交叉进行。不含敏感指令的用户态程序可以不经翻译直接执行。该技术为 VMWare Workstation,VMWare ESX Server 早期版本,Virtual PC 以及 QEMU 所采用。
该技术为 Xen 所采用。其基本原理是:当 Guest OS 创建一个新的页表时,会从它所维护的空闲内存中分配一个页面,并向 Xen 注册该页面,Xen 会剥夺 Guest OS 对该页表的写权限,之后 Guest OS 对该页表的写操作都会陷入到 Xen 加以验证和转换。Xen 会检查页表中的每一项,确保他们只映射了属于该虚拟机的机器页面,而且不得包含对页表页面的可写映射。后,Xen 会根据自己所维护的映射关系 g,将页表项中的物理地址替换为相应的机器地址,最后再把修改过的页表载入 MMU。如此,MMU 就可以根据修改过页表直接完成虚拟地址到机器地址的转换。
3.3.2 影子页表
类虚拟化需要修改 Guest OS。对全虚拟化,则使用影子页表 (Shadow Page Table) 技术来实现。 VMWare Workstation, VMWare ESX Server 和 KVM for x86 都是使用该技术。
与类虚拟化类似,影子页表技术也是采用将复合映射 fg 直接写入 MMU 的思路。不同在于类虚拟化技术直接将 fg 更新到 Guest OS 的页表项中,而影子页表则是 VMM 为 Guest OS 的每个页表维护一个“影子页表“,并将合成后的映射关系写入到”影子“中,Guest OS 的页表内容则保持不变。最后 VMM 将影子页表写入 MMU
影子页表的实现挑战在于其时间和空间的开销很大。 时间:由于 Guest OS 构造页表时不会主动通知 VMM,VMM 必须等到 Guest OS 发生缺页时通过分析缺页原因,再为其补全影子页表。 空间:VMM 需要支持多个虚拟机同时运行,而每个虚拟机的 Guest OS 通常会为其上运行的每个进程都创建一套页表系统,因此影子页表的空间开销会随着进程数量的增多而迅速增大。
该结构的 VMM,物理资源由 Host OS (Windows, Linux etc.) 管理 实际的虚拟化功能由 VMM 提供,其通常是 Host OS 的独立内核模块(有的实现还含用户进程,如负责 I/O 虚拟化的用户态设备模型) VMM 通过调用 Host OS 的服务来获得资源,实现 CPU,内存和 I/O 设备的虚拟化 VMM 创建出 VM 后,通常将 VM 作为 Host OS 的一个进程参与调度
如上图所示,VMM 模块负责 CPU 和内存虚拟化,由 ULM 请求 Host OS 设备驱动,实现 I/O 设备的虚拟化。
优点:可以充分利用现有 OS 的设备驱动,VMM 无需自己实现大量的设备驱动,轻松实现 I/O 设备的虚拟化。 缺点:因资源受 Host OS 控制,VMM 需调用 Host OS 的服务来获取资源进行虚拟化,其效率和功能会受到一定影响。