LWN: KVM Forum 2019的主要内容!

关注了就能看到更多这么棒的文章哦~

A recap of KVM Forum 2019

November 19, 2019

By Cornelia Huck, Pankaj Gupta, Stefan Hajnoczi, and Stefano Garzarella

原文来自:https://lwn.net/Articles/805097/

第13届KVM FOrum虚拟化会议于2019年10月在法国里昂举行。不少人以为,在2007年KVM(Kernel Virtual Machine)的代码合入Linux 2.6.20的时候,开发工作就已经结束了。而今年的会议中着重强调了当前仍在进行的开发工作,包括side-channel攻击的防护,I/O设备如何分配VFIO和mdev,采用micro virtual machines (VMs)来减少资源占用,以及在VM内部继续运行VM的能力。很多话题都牵涉到VMM (virtual machine monitor)这个用来调用KVM kernel module的用户程序,QEMU就是一个最常用到的VMM。

Side-channel attacks and memory isolation/encryption

Side-channel攻击,是指攻击者利用在常用的输入输出方法之外利用某些方式获取敏感信息的攻击方式。这种攻击近来越来越麻烦,因为跟预测执行(speculative execution)搅在了一起。KVM项目就在想办法能对这种攻击方式进行防护。

Dario Faggioli就进行了题为“Core-Scheduling for Virtualization: Where are We?”的演讲,主要着重于在scheduler调度器这个角度如何避免side-channel攻击。

在支持simultaneous multi-threading(就是Hyperthreading或者称为SMT),会有多个线程同时使用CPU核心,这样一来某些CPU资源就是公用的,例如这些线程都会共同使用cache (包括L1 cache),这样在识别出SMT功能的调度器里面可以提高性能。Core scheduling算法会对那些能在同一个CPU核心上同时执行的task打上tag标签,而调度器知会把拥有相同标签的task放在同一个CPU核上同时运行。那些属于不同security domain的task则拥有不同的标签值,从而确保他们不会在同一个CPU核心上同时运行,就能避免一些side-channel attack。Core scheduling也有助于改进云计算环境中的统计公平性,因为在同时共享同一个CPU核心的两个线程之中,更加繁忙的那个线程则会比比较空闲的线程消耗更多CPU资源。

Core scheduling也能用来把guest系统里的虚拟CPU (vCPU)跟host系统里的SMT核心对应起来,这样可以更智能地做一些调度决策。并且coer scheduling还能避免L1 Terminal Fault (L1TF)和Microarchitectural Data Sampling (MDS)这两种最主要的side-channel攻击方式。

之所以需要利用core scheduling来防护side-channel攻击,主要是希望避免彻底关闭SMT(这样会导致更多性能损失)。Hyper-V和Xen已经能支持core scheduling了。Linux的patch还没有upstream,目前一些benchmark结果看下来性能变化在不同workload之下差异很大。还需要针对某些不合理的现象来继续调查,例如有时候看到workload在打开core scheduling之后跑得会非常慢。

L1TF是一类硬件漏洞,在针对某个虚拟地址的page-table entry (PTE)中"present" bit被清零或者其他一些reserved bit被置1的时候,有一些非特权级的预测访问可以拿到L1 data cache (L1D)里面的数据。当某条指令在访问一个不存在(non-present)的PTE映射的虚拟地址的时候,直到这条指令retire之后才会产生一个page fault,而从L1D cache中拿到的预测值也就得到了,这样这条指令 会触发未授权的访问,有可能就会泄露另一个guest系统或者host系统的秘钥。

这个问题的防护办法,可以是在每次进入VM的时候就flush L1D cache,并且使用一个shadow MMU。flush L1D cache无法完全阻止在hyperthreading打开情况下的L1TF攻击,因为L1D cache在同一个CPU核之上同时运行的hyperthreads之间是公用的。Guest vCPU也可能会泄露L1D cache数据,要么是被在执行另一个VM的vCPU的兄弟hyperthread使用的cache数据,要么就是被目前正在执行VM-exit handler(这里VM会退出并把控制权交给kernel或者可以处理相应请求的user-space程序)的vCPU线程对应的兄弟hyperthread使用的cache数据。

Liran Alon和Alexandre Chartre介绍了“KVM Address Space Isolation (ASI)”,这个功能会让VM-exit handler使用一个独立的虚拟地址空间。此前的防护手段是把敏感数据从虚拟地址空间之中摘除,不过其实很难确认出来所有的敏感数据。KVM ASI就是一个白名单机制,只把那些KVM的VM-exit handler会需要用到的数据加入虚拟地址空间。

Thomas Lendacky则在题为“Improving and Expanding SEV Support"的演讲中介绍了AMD Secure Encrypted Virtualization (SEV) 这个CPU功能。SEV可以对VM进行保护,避免被不可信的hypervisor(例如在一个共有云上部署VM的时候)攻击。Guest系统里的内存会被加密,这样hypervisor就没法查看、修改这些内存内容了。Lendacky讨论了当前SEV相关的开发工作,例如消除memory pinning,live migration,以及支持encrypted state的SEV (SEV-ES)。

SEV live migration会对source和destination这两个VM使用不同的加密秘钥,秘钥并不会随着迁移。firmware里面需要持有一份加密过的内存内容,并利用特别的传输秘钥来在两个host之间移动page。

为了能让SEV性能更好,目前guest memory都是固定的(pinned)。固定的mmeory不是太好,因为这样swapping和overcommitting(指并不提前预留足够空间)功能就没法用了。要想避免guest-memory被固定下来,可以想法阻止page移动(migration/swapping),或者用SEV firmware来进行加密page的复制,目前有一些方向在调查。后面还需要利用SEV-ES支持VM寄存器的加密以及SEV-SNP(Secure Nested Paging)。

近来s390架构也开始实现对虚拟机的加密或保护了。在Claudio Imbrenda题为“Protected Virtual Machines for s390x”的演讲中包含了这一架构的概况。因为hypervisor被认为是不可信的,那么系统里唯一的可信实体就是通过硬件和固件实现的“ultravisor”。在需要确保guest是可靠的场景里,ultravisor会对启动镜像文件进行解密和验证,还要作为hypervisor和guest之间的交互代理。hypervisor就没法访问受保护的guest memory了,只能访问guest共享出来和它进行I/O操作的memory。s390的方案能够重用很多现有针对AMD SEV引入的代码。

VFIO and mdev

Linux里的VFIO驱动程序会把真实的PCI扩展卡以及其他一些设备暴露给应用程序。VFIO用在软件定义的网络应用程序里面所访问到的user-space设备驱动,也会用在VMM(例如QEMU)里面来把真实PCI卡传递给guest系统。目前基于VFIO已经有不少额外驱动可用了,大家正在推动更多的应用场景。

Kevin Tian题为“Toward a Virtualization World Built on Mediated Pass-Through”的演讲中就介绍了一下这套基于VFIO和mdev (mediated device framework)驱动的生态环境。VFIO可以把物理设备暴露给user space,mdev framework则可以些一些纯软件的设备,或者把软硬件功能结合起来。这样就可以用于在硬件之上增加一些软件逻辑,例如绕过一些硬件限制,或者作为硬件的一部分提供一些功能子集。

Xin Zeng和Yi Liu在他们的演讲“Bring a Scalable IOV Capable Device into Linux World”中,就介绍了一种基于VFIO/mdev的新应用。在数据中心里,PCI适配器有时候需要支持PCI single-root I/O virtualization (SR-IOV),这个功能可以把一个PCI卡分割成多个虚拟功能(VF, virtual function)的子设备,分别传递给不同的guest系统。这样多个虚拟机里面就可以安全的共享使用这块PCI卡,尽管其实每个VF里面只能访问一部分资源。最新的可扩展的I/O虚拟化方案(scalable I/O virtualization)则替换掉了这个硬件提供SR-IOV功能,而是利用一个mdev软件驱动来决定把哪些硬件资源传递给guest系统、哪些需要用软件来模拟。

Thanos Makatos和Swapnil Ingle的"muser: Mediated User Space Device"演讲里面介绍了mediated device的另一方面。Muser是一个mdev kernel驱动程序,还有相关的libmuser是一个user-space库,帮助在user space实现设备模拟。应用程序可以利用libmuser API来用软件实现出一个可以支持VFIO的PCI设备。QEMU或者其他的VMM就可以把这个设备传递给guest系统了。user space实现这个基于软件的PCI设备的时候,可以利用C或者Python接口,都能支持。这套API包括注册一个PCI device description,然后处理对设备的访问,既支持callback访问方式也支持polling mmap()过的寄存器空间的访问方式,后者性能更好一些。这种模拟了一个设备的程序可以定义PCI Base Address Register (BAR),configuration space,以及其他的PCI功能,这样就能模拟出一个现有的PCI设备,或者一个完全定制的新PCI设备。

Micro VMs and new VMMs

在过去几年中,容器(container)和微服务(micro-service)越来越流行。云服务用户以及供应商都在看如何利用虚拟机来增加安全性,对各个workload进行更好的隔离,因此有多个演讲都是基于KVM的方案。

Andreea Florescu和Alexandra Iordache在名为“Firecracker: Lessons from the Trenches”的演讲中,介绍了利用Rust写的一个轻量级VMM “Firecracker”。这是用在多租户(multi-tenant)云任务上的,例如容器或者功能即服务(FaaS)。它的核心优势是启动耗时最小,占用很小内存,并且可以多报 (over-subscription) CPU和内存。每个Firecracker进程可以处理一个micro-VM,利用chroot(),control groups, seccomp来界定安全边界(security boundaries)。用Rust写代码可以写出可靠性更高的代码,不过Florescu和Iordache碰到了它内部一些隐藏的bug,例如一个整数溢出问题,导致Firecracker可能会跑出各种异常现象。

还有其他人也在用Rust来做类似的事情,Alibaba, AWS, CloudBase, Google, Intel, Red Hat合作建立了rust-vmm,这是一组Rust库(术语叫Rust crate)专用于虚拟化软件。Florescu和Samuel Ortiz在名为“Playing Lego with Virtualization Components”的演讲中介绍了rust-vmm。他们解释说,Rust的关键特性(memory safety, safe concurrency, great performance)非常吻合VMM的需求。rust-vmm提供的一些样例模块包括API binding (KVM, VirtIO, VFIO),a memory model,a kernel loader,以及一些工具函数库。

Xiao Guangrong和Zhang Yulei在名为“Bring QEMU to Micro Service World”的演讲中介绍了他们如何利用QEMU来极速运行微服务。他们的方案名为QEMU basepoint,会跳过QEMU和guest系统初始化。它利用了QEMU现存的migration(迁移)功能,当VM启动起来之后就马上把它的状态保存到一个template file(模板文件)里面,然后就利用这个basepoint来启动新的VM。为了节省QEMU初始化的时间,新的VM会直接从base QEMU进程这里fork出来。这个方案可以节省启动时间,不过还是有一些局限,例如无法支持内核地址空间分布随机化功能(address-space layout randomization),今后会继续改进。

Nested virtualization

嵌套虚拟化,是指在虚拟机里面继续再运行新的虚拟机,无论是用相同还是不同的hypervisor。在很流行的云端基础设置中,通常都会利用虚拟化,kernel本身通常已经是在另一个hypervisor的基础上运行的了,因此嵌套虚拟化对KVM很重要。嵌套虚拟化因此在开发、持续集成(CI)、云端生产环境等场景下都很重要。有KVM Forum有两个演讲是关于这方面的话题的。

在Marc Hartmayer名为“Managing Matryoshkas: Testing Nested Guests”的演讲中,他介绍了利用现有的基于Python的Avacado测试架构,如何测试多层嵌套(高达7层嵌套)的环境。他利用了Mitogen库来在远端guest系统上执行Python代码,这样就重用了嵌入到内部的guest的线程的虚拟化测试条件。他快速演示了一下,这个方法很容易扩展,测试结果也很容易获取,多深的嵌套层级都不怕。Hartmayer的实验里面利用了Avocado-vt插件,不过也可以比较容易的集成到更简单的Avocado-QEMU架构里面(QEMU的acceptance test suite里面已经包含),只要等Mitogen相关改动upstream即可。

在Vitaly Kuznetsov的"Nesting&testing"演讲中,他介绍了一下x86目前是如何测试这种嵌套虚拟化的。有两个测试架构互相补充:kvm-unit-tests会利用QEMU来运行测试,kvm-selftests则会利用客制化的user-space工具来测试一些边边角角场景不过这种测试写起来比较复杂。更进一步地,测试可以利用那些专用于测试嵌套功能的测试程序,也可以直接在hypervisor之下运行那些已有的虚拟化测试程序,后者就是KVM在Hyper-V中的测试方式。

目前已有的测试中,Intel CPU的VMX已经有很多测试了,Kuznetsov在kvm-unit-test里面对他们标记为了正确性、功能性、回归测试等类别。不过AMD CPU的SVM测试则很少,大多数都在功能性测试类别。对kvm-selftests来说,AMD CPU的情况则更加糟一些,因为目前完全没有SVM的支持。SVM还是需要更多工作。

除了增加更多测试之外,还需要把现有的测试集集成到一些持续集成系统里面,尤其是这样就可以在嵌套环境里面运行这些程序了,例如Hyper-V/Azure,这种环境通常大家并不容易获得。

Conclusion

上面就是KVM Forum 2019最主要的一些话题了。还有其他 一些 有趣的演讲,可以在线观看,也提供了演示文稿。看起来明年爱尔兰都柏林的KVM Forum 2020会议上side-channel attack防护还会时一个热点话题,VFIO/mdev生态系统则会继续增长,因为硬件供应商和软件都可以借助它的能力。诸如Amazon, Google, Microsoft, Tencent, Huawei这些公司的出席就充分证明了KVM在云主机领域已经多么重要,并且今后可见的时间内会继续快速成长。

全文完

LWN文章遵循CC BY-SA 4.0许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注LWN深度文章以及开源社区的各种新近言论~

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章