6. 推荐
根据我们构建KVM/ARM的经验,我们为硬件设计人员提供了一些建议,以简化和优化未来的hypervisor实现
共享内核模式内存模型。运行hypervisor的硬件模式应该与运行操作系统内核的硬件模式使用相同的内存模型。这样软件设计人员在决定如何紧密地将hypervisor与现有操作系统内核集成方面具有更大的灵活性。不幸的是,ARM HYP模式并没有做到这一点,这使得KVM/ARM不能简单地在HYP模式下重用内核的页表。这种重用将简化实现,并允许性能关键的模拟代码以HYP模式运行,在某些情况下可避免world的切换。有些人可能会认为,这个建议使得独立的hypervisor实现更加复杂,但这并不是真的。例如,ARM内核模式已经提供了一个简单的选项,可以使用一个或两个页表基寄存器来统一或分割地址空间。我们建议与x86虚拟化方法不同,x86虚拟化方法没有独立的、更有特权的hypervisor CPU模式。拥有独立的CPU模式可能会提高独立hypervisor的性能和实现,但是不共享内核内存模型会使与主机内核集成的hypervisor的设计更复杂化。
使VGIC状态访问快速,或至少不频繁。VGIC的支持可以提高性能,特别是在多核系统上。我们的测量还显示,访问VGIC状态会增加world切换时的开销。这是由于在关键路径中对VGIC控制接口的访问速度慢造成的。改进MMIO访问时间可能会提高虚拟机的性能,但如果这是不可能的或成本效益不高,至少可以减少对VGIC的MMIO访问频率。例如,可以引入一个摘要寄存器来描述每个虚拟中断的状态。当执行从虚拟机到hypervisor的world切换时,可以读取这些信息,以获取当前只能通过读取每个world切换上的所有list寄存器(请参阅3.5节)才能获得的信息。
完全避免IPI trap操作。如果硬件支持在直接从虚拟机发送虚拟IPIs到另外一个虚拟CPU时不需要陷入到hypervisor,这样将会改善执行效率。硬件设计人员可能低估了IPIs在现代多核操作系统上的频率,我们的测量结果显示,发送IPIs会为某些工作负载增加大量开销。当前的VGIC设计需要陷入到hypervisor来模拟分发服务器中IPI寄存器的访问,并且这种模拟访问必须在虚拟内核之间使用软件锁定机制进行同步,这将增加IPIs的大量开销。当前的ARM硬件支持接收虚拟IPI,它可以在没有trap的情况下被ACK和EOI,但不幸的是,它没有解决发送虚拟IPI的重要问题。
7. 相关工作
虚拟化已经有很长的历史了,但是从20世纪90年代末开始,它又重新流行起来。大多数工作几乎都集中在虚拟化x86体系结构上。在引入x86硬件虚拟化支持之前,VMware和Xen等系统最初都是基于纯软件的方法来实现的,而现在所有x86虚拟化平台、VMware、Xen和KVM都利用了x86硬件虚拟化支持来实现的。由于x86硬件虚拟化支持与ARM在以与内核相同的模式完全运行hypervisor的能力上有很大的不同,x86虚拟化方法本身并不能直接利用ARM硬件虚拟化支持。
一些x86方法还利用主机内核为hypervisor提供功能,VMware工作站的hypervisor创建了一个与主机内核分离的VMM,这种做法在许多重要方面不同于KVM/ARM。首先,VMware VMM没有集成到主机内核源代码中,因此不能重用现有的主机内核代码,例如,无法填充与VM相关的页表。其次,由于VMware VMM是专门针对x86的,所以它不会运行在不同的特权CPU模式上,因此不使用类似于KVM/ARM的设计。第三,运行VM所需的大多数模拟和错误处理代码都在VMM内的最特权级别上执行。KVM/ARM在特权较少的内核模式下执行这段代码,并且在特权最多的模式下只执行很少的代码。相比之下,KVM得益于与Linux内核的集成,比如x86设计依赖于能够以相同的硬件hypervisor模式同时运行内核和hypervisor,这在ARM上是有问题的。
ARM架构的全系统虚拟化是一个相对未开发的研究领域。多数实现方案都是纯软件的。目前已经开发了许多独立hypervisor,但是这些hypervisor并没有广泛使用,它们是专门针对嵌入式市场开发的,必须进行修改并移植到每个主机硬件平台,这就限制了其被广泛使用。ARM的一个废弃的XEN端口需要对客户内核进行全面的修改,而且从未完全开发过。ARM上的KVM的早期原型使用了一种自动化的轻量级半虚拟化方法来自动修补内核源代码,使之作为guest内核运行,但是性能很差。VMware Horizon Mobile使用托管虚拟化来利用Linux对各种硬件平台提供支持,但需要对客户操作系统进行修改,其性能尚未得到证实。这些半虚拟化方法都不能运行未经修改的客户操作系统。
早期的一项研究层试图使用一种软件仿真来评估对ARM硬件虚拟化的支持,但一个简单的hypervisor缺少一些重要的特性,比如SMP支持,以及多个存储和网络设备。由于缺乏硬件或周期精确的模拟器,无法进行真正的性能评估。与此相反,我们首次评估了使用真实硬件的ARM虚拟化扩展,提供了与x86的直接比较,并介绍了使用ARM虚拟化扩展(包括SMP支持)的完整hypervisor的设计和实现。
正在使用ARM硬件虚拟化支持开发一个专门针对服务器的新版本Xen。由于Xen是一个不利用内核功能的单独hypervisor,因此可以将其架构为完全在HYP模式下运行,而不是使用分裂模式进行虚拟化。同时,这需要大量的商业工程工作。由于Xen是一个独立的hypervisor,将Xen从x86移植到ARM非常困难,部分原因是所有与ARM相关的代码都必须从头编写。即使让Xen在一个ARM平台上工作之后,它也必须手动移植到每个不同的ARM设备上。由于Xen的自定义I/O模型使用虚拟机中的hypercall进行ARM上的设备模拟,因此Xen并不能运行guest操作系统,除非它们被配置为包含Xen的hypercall层并包含对XenBus半虚拟化驱动程序的支持。相比之下,KVM/ARM使用标准Linux组件支持更快的开发,完全支持SMP,以及可运行未经修改的操作系统的能力。在支持Linux的新设备上很容易支持KVM/ARM,而且我们也很容易的在ARM的通用Express板、Arndale板和硬件模拟器上支持KVM/ARM。虽然Xen可以潜在地减少两个world切换开销,这是因为Xen可以在hypervisor中处理直接处理,但是其切换到Dom0用于I/O支持或切换到其他虚拟机将涉及到与KVM/ARM相同状态的上下文切换。
用于hypervisor的微内核方法已用于减少hypervisor对TCB的访问,并在用户模式下运行hypervisor服务。这些方法在设计和原理上与分裂模式虚拟化不同,分裂模式虚拟化将hypervisor功能跨特权模式分离,以便利用虚拟化硬件支持。分裂模式虚拟化还提供了不同的hypervisor功能分割。KVM/ARM的lowvisor是一个更小的代码库,它只实现最低级别的hypervisor机制。它不包括在这些其他方法中使用的hypervisor TCB中提供的更高级别的功能。
8. 结论
KVM/ARM是Linux ARM hypervisor的主线,也是第一个可以在ARM多核硬件上运行未经修改的guest操作系统的系统。KVM/ARM的分裂模式虚拟化即利用Linux内核机制和硬件支持也利用了ARM硬件虚拟化扩展。我们的实验结果表明,1. KVM/ARM由分裂模式虚拟化引起的额外trap对性能的影响最小。2. 对于真实的应用程序工作负载,在多核硬件上比直接本地执行的功耗和效率提高了10%左右。3. 与广泛使用的KVM x86虚拟化相比,KVM/ARM在多核硬件上实现类似或更低的虚拟化开销和电力成本。基于我们将KVM/ARM集成到主流Linux内核的经验,我们提供了一些关于获得开源社区采用的研究思路和代码的提示,并为硬件设计人员提供了改进未来hypervisor实现的建议。
9.致谢
Marc Zyngier帮助开发,实现了VGIC和vtimer支持,并帮助我们开发硬件。Rusty Russell负责协处理器用户空间界面的开发,并协助上传。Deacon和Avi Kivity会提供大量有用的代码评审。Peter Maydell在QEMU支持和调试方面提供了帮助。Gleb Natapov帮助我们更好地理解KVM x86性能。Marcelo Tosatti和Nicolas Viennot帮助解决了voodoo bug.Keith Adams, Hani Jamjoom和Emmett对本文的早期草稿提出了有益的评论。这项工作部分得到了ARM和NSF赠款的支持。