如果没有新的虚拟化扩展,x86 架构上运行多个客户操作系统非常困难:有的指令只能从最高优先级 ring 0 执行,这样的访问不可能在不影响系统上的其他操作系统的操作的前提下给到每个操作系统。此外,一些指令在低优先级执行时不会引发陷阱——尽管他们要求更高的优先级以正确发挥作用——所以在 ring 0 上运行“hypervisor(运行其他操作系统的操作系统)”,而在低优先级的环上运行其它操作系统也不是解决方案。
VMX 和 SVM 指令给 x86 架构引入了一个新的优先级 ring -1。这是虚拟机监视程序(VMM),或 hypervisor 运行的优先级。VMM 仲裁访问硬件的各种操作系统,这样它们可以在常规 x86 环境中持续正常运行。
从一开始,Kivity 就想要写可以提交到上游的代码。KVM 模型的目标之一是尽可能重用已经存在的功能:让 Linux 多干活, KVM 仅作为用来控制硬件所提供的新虚拟化指令的驱动。这让 KVM 能获得 Linux 开发者添加到系统其它部分的任何新特性,比如 CPU 调度器、内存管理、电源管理等等的改进。
该模型对于 Linux 生态系统的其它部分也工作地很好。以只有虚拟化开始这样的特性开始变得更加用途更多,并且也广泛适用于通用用途,如透明巨页[10]。社区并没有对于 OS 和 VMM 分成两个;每个部件都作为一个项目整体的一部分。
而且,VM的管理将会更容易,每个 VM 都可以作为常规进程监控,——像 top 和 ps 这样的工具可以直接拿来用。近来,perf可以从宿主机上用来监控客户机活动和识别瓶颈,如果有的话。未来的的芯片集改进将能从宿主机上检测客户机的进程性能。
KVM 的另一边是用户空间,即构建呈现给客户操作系统的机器的地方。kvm-userspace 是 QEMU[11] 项目的一个分支。QEMU 是一个机器模拟器,可以运行它所支持的各种架构的未修改的操作系统镜像,并且在它运行其上的宿主机架构模拟这些架构的指令。这当然非常缓慢,但 QEMU 项目的优势是它已经仿真了 x86 架构的很多设备——比如芯片集,网卡,显示适配器,等等。
kvm-userspace 所做的是短路仿真代码,只允许 x86-on-x86 ,并使用 KVM API 在宿主机 CPU 上实际运行客户机操作系统。客户机操作系统执行特权操作时,CPU 将退出到 VMM 代码。由 KVM 接管;如果它自己可以服务请求,它就服务请求,并将控制交还客户机。这是“轻量级退出”。对于 KVM 不能处理的请求,像设备模拟,它会交给 QEMU。这意味着从主机 Linux 内核退出到用户空间,因此这称为“重量级退出”。
Xen 也使用 QEMU 的一个分支为它的 HVM 模式进行设备模拟(Xen 使用新硬件虚拟化指令的模式)。此外,QEMU 对于 x86-on-x86 有自己的非上游 Linux 内核加速器模块(KQEMU),消除了模拟层,使 x86 客户机在 x86 硬件上运行得更快。整合所有这些需要一个理解所有项目的各种需求的维护者。Anthony Liguori 是 QEMU 项目的一个维护者,他信任 Xen 和 KVM 的社区。随着时间的推移,这些非上游分支逐渐被淘汰,现在 KVM 和 Xen 都使用上游 QEMU 仿真设备模型。
“做一件事,做到正确”的咒语,和“一切皆文件”的理念,发挥到了极致。KVM API 允许在 Linux 系统上创建 VM——或者,沙盒,然后可在其内部运行操作系统,或者任何代码,而不会干扰正在运行的系统。这也意味着可以有其它的用户空间实施方案,不像 QEMU 那么重量级或者功能丰富。可以快速启动小型应用程序或者特定 OS 的 KVM 虚拟机的工具开始出现——kvmtool 是最流行的一个。