虚拟化(Virtualization)技术最早出现在 20 世纪 60 年代的 IBM 大型机系统,在 70 年代的 System 370 系列中逐渐流行起来,这些机器通过一种叫虚拟机监控器(Virtual Machine Monitor,VMM)的程序在物理硬件之上生成许多可以运行独立操作系统软件的虚拟机(Virtual Machine)实例。如果读者对于虚拟化技术的背景不太熟悉,可以参阅笔者在 IBM DeveloperWorks 中国网站发表的《虚拟化技术漫谈》一文 [1],或维基百科上面的条目。
在硬件辅助虚拟化技术出现之前,纯软件实现的 VMM 不得不使用 Trap And Emulate 或者二进制翻译的技术解决各种挑战。这两种技术导致 VMM 的设计与实现相当复杂,并且严重地影响了虚拟机的性能。
2005 年冬天,英特尔带来了业内首个面向台式机的硬件辅助虚拟化技术 Intel VT 及相关的处理器产品,从而拉开了 IA 架构虚拟化技术应用的新时代大幕。Intel VT 技术支持两种操作模式,将 VMM 和 虚拟机自然地隔离开来,并通过特别优化过的指令集来自动控制虚拟化过程,从而极大简化 VMM 的设计,虚拟机的性能也能得到很大提高。
早期的硬件辅助虚拟化技术主要针对处理器的虚拟化,随着技术的发展与完善,Intel 和 AMD 两大厂商提出和发展一系列新技术,在简化页表管理,提高 TLB 命中率,I/O 外设访问和网络设备复用等方面提供强大的硬件支持。
内存是一种非常重要的系统资源,客户机操作系统理解的物理地址只是客户机物理地址(Guest Physical Address),并不是最终的主机物理地址(Host Physical Address)。客户机(虚拟机)中发生缺页异常时,VMM 需要知道缺页异常的原因,是 Guest 进程试图访问没有权限的地址,或是客户机线性地址(Guest Linear Address)尚未翻译成客户机物理地址,还是客户机物理地址尚未翻译成主机物理地址。常用的解决方法是 VMM 为客户机的每个进程的页表构造一个影子页表,维护客户机线性地址到主机物理地址的映射,主机 CR3 寄存器存放这个影子页表的物理内存地址。VMM 同时维护一个全局的客户机物理地址到主机物理地址的映射表。发生缺页异常的地址总是客户机线性地址,VMM 先去客户机操作系统设置的当前页表检查原因,如果页表项已经建立,即对应的客户机机物理地址存在,说明尚未建立到主机物理地址的映射,那么 VMM 分配一页物理内存,将影子页表和映射表更新;否则,VMM 返回到客户机操作系统,由其自行处理该异常。VMM 还必须将客户机操作系统使用的页表的物理地址区域设置为只读,当其更新自己的页表时,可以发生 VM exit,这样 VMM 就可以保证两个页表的一致性。由于缺页异常发生地相当频繁,影子页表的构建和维护显著地降低了虚拟机的性能。
Intel 提出扩展页表(Extended Page Tables,EPT)的技术来解决这个问题。VMM 需要为每一个客户机操作系统维护一张全局的客户机物理地址到主机物理地址的映射表,称为 EPT 页表。EPT 页表与普通页表结构基本相同,VMM 将其物理地址存于 VMCS 之中以通知内存管理单元(Memory Management Unit,MMU)。只有在 VMX non-root 操作模式下,EPT 页表才会被启用。一旦使用客户机线性地址访问内存,MMU 联合使用客户机操作系统的当前页表和 EPT 页表获得最终的主机物理地址。有了 EPT 技术,客户机操作系统设置 CR3 寄存器来切换页表的时候,无需产生 VM exit;VMM 也不用写保护它管理的页表,因为一旦在 EPT 页表中找不到对应页表项时,自动发生 VM exit 通知 VMM 处理。图 1 显示了处理器如何在把 32 位客户机操作系统中的线性地址翻译成主机物理地址的过程。EPT 技术显著地减少了 VM exit 的次数,简化了 VMM 的设计。研究表明 EPT 技术对于一般的测试程序至多有 48% 的性能提升;对于某些内存密集型的小测试程序,性能提升高达 600%。
图 1. 32 位客户机线性地址翻译成主机物理地址的过程
翻译客户机线性地址时,MMU 硬件不得不在两个页表间来回跳转访问。假定客户机操作系统的页表有 m 级,EPT 页表有 n 级,可以推算最多需要 m * n + m + n 次页表(内存)访问。如果客户机操作系统和 VMM 均为 64 位,则 m 和 n 都是 4,这个上限将达到 24,虚拟机的性能可能会受到较大影响。但是如果 VMM 使用 2 M 或更大的物理页面,虽然这并不能减少 n 的数值,却可以提高翻译后援缓冲器(Translation Lookaside Buffer,TLB)的命中率,从而减少页表的访问。
AMD 提出的解决方案叫做快速虚拟化索引(Rapid Virtualization Indexing,以前叫做嵌套页表),该技术与 EPT 极为相似,在此不再累述。
TLB 存放的是线性地址(包括客户机线性地址)到主机物理地址的映射,如果能提高 TLB 的命中率,那么翻译客户机线性地址的速度将会大大提高。早期的硬件辅助虚拟化技术并未优化 TLB 的使用,一旦 CR3 寄存器被改写(客户机操作系统切换页表,或者发生 VM entry 和 VM exit),因为 TLB 无法区分不同地址空间中相同的线性地址,于是不得不清空全部条目,以免给出错误结果。这种做法导致许多不必要的页表访问,严重影响虚拟机的性能。Intel 现在引入虚拟处理器标识符(Virtual Processor Identifier,VPID)技术,VMM 可以为每个虚拟机分配全局唯一的 16 位 ID(大于 0),自己则使用 0 号 ID。TLB 的每一项附加该 ID 信息,这样就可以区分不同客户机操作系统的线性地址,TLB 也就无需频繁自动清空,不过此时 VMM 须自行管理 TLB 条目的更新。该技术单独使用的话,可以提高 4% 的性能;如果联合 EPT 的话,至多提高 10%-15% 的性能。AMD 对应的技术称为地址空间标志符(Address Space Identifier,ASID)。
I/O 虚拟化需要考虑性能、可用性、可扩展性、可靠性和成本等多种因素。最简单的方式是 VMM 为虚拟机模拟一个常见的 I/O 设备,该设备的功能由 VMM 用软件或复用主机 I/O 设备的方法实现。例如 Virtual PC 虚拟机提供的是一种比较古老的 S3 Trio64 显卡。这种方式提高了兼容性,并充分利用客户机操作系统自带的设备驱动程序,但是虚拟的 I/O 设备功能有限且性能低下。为了提高性能,VMM 试图直接将主机 I/O 设备分配给虚拟机,这会带来三个主要挑战:
- DMA 重映射。如果客户机操作系统使用 DMA 的方式访问 I/O 设备,由于其给出的地址并不是主机物理地址,VMM 必须保证在启动 DMA 操作前将该地址正确转换。
- I/O 操作的隔离与保护。VMM 必须控制客户机操作系统对 I/O 设备的访问,使之不能干扰其他虚拟机和自己的正常运行。
- 中断重映射(例如复用 I/O 外设)。VMM 必须能够隔离和正确转发 I/O 设备或者外部中断控制器产生的中断。
应对上述难题,Intel 提出一种称为 Directed I/O 的外设直接访问技术,简称 VT-d。AMD 对应的技术称为 IOMMU。VT-d 技术允许客户机操作系统中的驱动程序直接和主机 I/O 外设通信,并提供了强大的 DMA 和中断重映射的硬件支持。
DMA 重映射和 I/O 操作的隔离与保护是通过 DMA 保护域来解决的。VMM 为 I/O 外设创建 多个 DMA 保护域,每个 DMA 保护域代表了一个被隔离的、独立的系统物理内存地址空间,使用类似页表的数据结构来管理外设对物理内存区域的访问。I/O 外设访问客户机物理内存地址时,VT-d 通过关联的 DMA 保护域自动将该地址转换成最终的本机物理内存地址,并检验该外设是否有权限访问这块内存区域。
DMA 保护域优点如下:
- 用于 DMA 的物理内存地址必须在 4G 以下(有的老设备只能访问 16 M 以内的物理内存)且比较稀缺,操作系统一般为外设使用双缓冲区的策略:外设平时使用缓冲区尽量在高端内存(4G 以上)内分配,只有在做 DMA 操作时,临时分配一个 DMA 专用缓冲区,操作系统负责在两个缓冲区间复制数据。有了 DMA 保护域,无需分配 DMA 专用缓冲区,外设可以直接使用低端内存地址,该地址随后被透明地转换到真正的缓冲区地址。
- 如果物理内存区域 M 只能被外设 A 使用,那么可以设置其它外设的 DMA 保护域,使得对区域 M 的任何访问非法。
- 如果外设 A 被多个客户机操作系统复用,VMM 只需为每个客户机操作系统分配一个不同的 DMA 保护域,于是相同的客户机物理地址被转换成不同的主机物理地址,多个客户机操作系统之间互不干扰。
在集群和数据中心这类环境中,每台主机通常同时运行大量的虚拟机。由于主机的网络设备数目有限,多个虚拟机不得不复用同一个网络设备,从而导致性能下降。Intel VT-c 技术可针对虚拟化进一步优化网络性能。VT-c 包括如下两个关键技术:
-
虚拟机设备队列(Virtual Machine Device Queues,VMDq)。收到一个数据包时,VMM 必须将其分类以确定应该转发给哪个虚拟机,这占用了大量宝贵的处理器资源。如果以太网控制器支持 VMDq 技术,VMM 可以为虚拟机使用不同的数据包队列,以太网控制器自动分类数据包并投放到相应的队列中,大大减轻 VMM 的负担,提高了 I/O 吞吐量。
图 2. VMDq 数据包分类
-
虚拟机直接连接(Virtual Machine Direct Connect,VMDc)。通俗地说,支持该技术的网络设备能够对外展现出多个虚拟功能接口(Virtual Function)。每个功能接口相当于一个网络设备,VMM 可将其直接分配给某个虚拟机,从而“避免”了网络设备的复用。例如,VMM 仅用单个英特尔万兆位服务器网卡,可为 10 个客户机操作系统分配独立受保护的 1 Gb/ 秒的专用链路,VMM 无需继续管理这些直接通信链路,进一步提升 I/O 性能并减少主机处理器的负载 。
图 3. VMDc 示意图
本文针对 x86 平台,介绍硬件辅助虚拟化技术的新进展,希望对读者的工作和学习有所裨益,更多详细信息请参阅参考资料一节。
学习
- 请参考 developerWorks 上的虚拟化文章 虚拟化技术漫谈,了解相关信息。
- http://en.wikipedia.org/wiki/Virtualization 是虚拟化入门的好地方。
- Intel Corp.,Intel® 64 and IA-32 Architectures Software Developer's Manuals 手册详细描述了 Intel 64 和 IA-32 处理器硬件辅助虚拟化技术的方方面面。
- Intel Corp.,Intel® Virtualization Technology for Directed I/O 一文详细介绍了 Intel VT-d 技术。
- http://www.intel.com/network/connectivity/solutions/virtualization.htm?iid=tech_vt_tech+vtc 提供了 Intel VT-c 技术入门介绍。
- 在 developerWorks Linux 专区寻找为 Linux 开发人员(包括 Linux 新手入门)准备的更多参考资料,查阅我们 最受欢迎的文章和教程。
- 在 developerWorks 上查阅所有 Linux 技巧和 Linux 教程。
- 随时关注 developerWorks 技术活动和 网络广播。
讨论
- 加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。
