|
|
|
|
移动端

漫谈虚拟化之二-虚拟化面临的挑战

软件 VMM 所遇到的以上挑战从本质上来说是因为 Guest OS 无法运行在它所期望的最高特权级,传统的 Trap-And-Emulate 处理方式虽然以透明的方式基本解决上述挑战,但是带来极大的设计复杂性和性能下降。

作者:听泉Rit来源:听泉Rit|2018-03-21 11:00

技术沙龙 | 邀您于8月25日与国美/AWS/转转三位专家共同探讨小程序电商实战

在谈这部分内容之前,让我们先来了解一下常见的一些有关虚拟化的常用概念。

1. 常用概念

(1)宿主机或主机:即 Host Machine,指物理机资源,如果将一个物理机虚拟成多个虚拟机,则称该物理机为 Host Machine。

(2)客户机:即 Guest Machine,指虚拟机资源。

(3)Host OS 和 Guest OS:运行在 Host Machine 上的 OS 则为 Host OS;运行在 Guest Machine 上的 OS 为 Guest OS。

(4)Hypervisor 或 VMM:通过虚拟化层的模拟,虚拟机在上层软件看来就是一个真实的机器,这个虚拟化层一般称为虚拟机监控机(Virtual Machine Monitor,VMM)或Hypervisor。是一种运行在基础物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享硬件。

进一步理解,可以认为 Hypervisor 是一种在虚拟环境中的“元”操作系统。它可以访问服务器上包括内存和磁盘在内所有物理设备。Hypervisor 不但协调着这些硬件资源的访问,同时也在各个虚拟机之间施加防护。当服务器启动并执行 Hypervisor 时,它会加载所有虚拟机客户端的操作系统,同时会分配给每一台虚拟机适量的内存、CPU、网络和磁盘。

(5)VM:即虚拟机,是指使用虚拟化技术,通过软件模拟完整的计算机硬件系统功能,构造出的完整虚拟计算机系统。该虚拟机可以独立运行在一个完全隔离的环境中,就像使用本地计算机一样,安全可靠。

2. 虚拟化面临的挑战

在通过软件手段设计 VMM 的时候,需要解决很多问题,我们来看一下:

(1)确保 VMM 控制所有的系统资源

x86 处理器有 4 个特权级别,Ring 0 ~ Ring 3,只有运行在 Ring 0 ~ 2 级时,处理器才可以访问特权资源或执行特权指令;运行在 Ring 0 级时,处理器可以访问所有的特权状态。x86 平台上的操作系统一般只使用 Ring 0 和 Ring 3 这两个级别,操作系统运行在 Ring 0 级,用户进程运行在 Ring 3 级。为了满足上面的第一个充分条件-资源控制,VMM 自己必须运行在 Ring 0 级,同时为了避免 Guest OS 控制系统资源,Guest OS 不得不降低自身的运行级别,运行在 Ring 1 或 Ring 3 级(Ring 2 不使用)。

(2)特权级压缩(Ring Compression)

VMM 使用分页或段限制的方式保护物理内存的访问,但是 64 位模式下段限制不起作用,而分页又不区分 Ring 0, 1, 2。为了统一和简化 VMM 的设计,Guest OS 只能和 Guest 进程一样运行在 Ring 3 级。VMM 必须监视 Guest OS 对 GDT(Global Descriptor Table 全局描述符表)、IDT(Interrupt Descriptor Table,即中断描述符表)等特权资源的设置,防止 Guest OS 运行在 Ring 0 级,同时又要保护降级后的 Guest OS 不受 Guest 进程的主动攻击或无意破坏。

(3)特权级别名(Ring Alias)

特权级别名是指 Guest OS 在虚拟机中运行的级别并不是它所期望的。VMM 必须保证 Guest OS 不能获知正在虚拟机中运行这一事实,否则可能打破等价性条件。例如,x86 处理器的特权级别存放在 CS(Code Segment 代码段) 代码段寄存器内,Guest OS 可以使用非特权 push 指令将 CS 寄存器压栈(栈是存储的系统,压栈是写入数据,用 push 表示,每压栈一次减 2,出栈是输出数据,用 pop 表示,每出栈一次加 2;遵循先进后出,后进先出的顺序),然后 pop 出来检查该值。又如,Guest OS 在低特权级别时读取特权寄存器 GDT、LDT(Local Descriptor Table 局部描述符表)、IDT 和 TR(Task Rigister 任务寄存器),并不发生异常,从而可能发现这些值与自己期望的不一样。为了解决这个挑战,VMM 可以使用动态二进制翻译的技术,例如预先把 “push %%cs” 指令替换,在栈上存放一个影子 CS 寄存器值;又如,可以把读取 GDT 寄存器的操作“sgdt dest”改为“movl fake_gdt, dest”。

(4)地址空间压缩(Address Space Compression)

地址空间压缩是指 VMM 必须在 Guest OS 的地址空间中保留一部分供其使用。例如,中断描述表寄存器(IDT Register)中存放的是中断描述表的线性地址,如果 Guest OS 运行过程中来了外部中断或触发处理器异常,必须保证运行权马上转移到 VMM 中,因此 VMM 需要将 Guest OS 的一部分线性地址空间映射成自己的中断描述表的主机物理地址。VMM 可以完全运行在 Guest OS 的地址空间中,也可以拥有独立的地址空间,后者的话,VMM 只占用 Guest OS 很少的地址空间,用于存放中断描述表和全局描述符表(GDT)等重要的特权状态。无论如何哪种情况,VMM 应该防止 Guest OS 直接读取和修改这部分地址空间。

(5)处理 Guest OS 的缺页异常

内存是一种非常重要的系统资源,VMM 必须全权管理,Guest OS 理解的物理地址只是客户机物理地址(Guest Physical Address),并不是最终的主机物理地址(Host Physical Address)。当 Guest OS 发生缺页异常时,VMM 需要知道缺页异常的原因,是 Guest 进程试图访问没有权限的地址,或是客户机线性地址(Guest Linear Address)尚未翻译成 Guest Physical Address,还是客户机物理地址尚未翻译成主机物理地址。

一种可行的解决方法是 VMM 为 Guest OS 的每个进程的页表构造一个影子页表,维护 Guest Linear Address 到 Host Physical Address 的映射,主机 CR3 寄存器存放这个影子页表的物理内存地址。VMM 同时维护一个 Guest OS 全局的 Guest Physical Address 到 Host Physical Address 的映射表。发生缺页异常的地址总是 Guest Linear Address,VMM 先去 Guest OS 中的页表检查原因,如果页表项已经建立,即对应的 Guest Physical Address 存在,说明尚未建立到 Host Physical Address 的映射,那么 VMM 分配一页物理内存,将影子页表和映射表更新;否则,VMM 返回到 Guest OS,由 Guest OS 自己处理该异常。

(6)处理 Guest OS 中的系统调用 

系统调用是操作系统提供给用户的服务进程,使用非常频繁。最新的操作系统一般使用 SYSENTER/SYSEXIT 指令对来实现快速系统调用。SYSENTER 指令通过IA32_SYSENTER_CS,IA32_SYSENTER_EIP 和 IA32_SYSENTER_ESP 这 3 个 MSR(Model Specific Register)寄存器直接转到 Ring 0 级;而 SYSEXIT 指令不在 Ring 0 级执行的话将触发异常。因此,如果 VMM 只能采取 Trap-And-Emulate 的方式处理这 2 条指令的话,整体性能将会受到极大损害。

(7)转发虚拟的中断和异常 

所有的外部中断和主机处理器的异常直接由 VMM 接管,VMM 构造必需的虚拟中断和异常,然后转发给 Guest OS。VMM 需要模拟硬件和操作系统对中断和异常的完整处理流程,例如 VMM 先要在 Guest OS 当前的内核栈上压入一些信息,然后找到 Guest OS 相应处理例程的地址,并跳转过去。VMM 必须对不同的 Guest OS 的内部工作流程比较清楚,这增加了 VMM 的实现难度。同时,Guest OS 可能频繁地屏蔽中断和启用中断,这两个操作访问特权寄存器 EFLAGS,必须由 VMM 模拟完成,性能因此会受到损害。 Guest OS 重新启用中断时,VMM 需要及时地获知这一情况,并将积累的虚拟中断转发。

(8)Guest OS 频繁访问特权资源

Guest OS 对特权资源的每次访问都会触发处理器异常,然后由 VMM 模拟执行,如果访问过于频繁,则系统整体性能将会受到极大损害。比如对中断的屏蔽和启用,cli(Clear Interrupts)指令在 Pentium 4 处理器上需要花费 60 个时钟周期(cycle)。又如,处理器本地高级可编程中断处理器(Local APIC)上有一个操作系统可修改的任务优先级寄存器(Task-Priority Register),IO-APIC 将外部中断转发到 TPR 值最低的处理器上(期望该处理器正在执行低优先级的线程),从而优化中断的处理。TPR 是一个特权寄存器,某些操作系统会频繁设置(Linux Kernel 只在初始化阶段为每个处理器的 TPR 设置相同的值)。

3. 总结

软件 VMM 所遇到的以上挑战从本质上来说是因为 Guest OS 无法运行在它所期望的最高特权级,传统的 Trap-And-Emulate 处理方式虽然以透明的方式基本解决上述挑战,但是带来极大的设计复杂性和性能下降。早期比较先进的虚拟化软件结合使用二进制翻译和半虚拟化的技术,核心思想是动态或静态地改变 Guest OS 对特权状态访问的操作,尽量减少产生不必要的硬件异常,2005 年随着硬件辅助虚拟化技术的出现,进一步简化了 VMM 的设计,VMM 的性能也能得到很大提高。

【编辑推荐】

  1. 云存储的核心技术:虚拟化存储
  2. 虚拟化平台迁移转换 4 个典型问题
  3. 漫谈虚拟化之一虚拟化综述
  4. 基础知识:虚拟机的构成和CPU虚拟化
  5. 我们来谈谈虚拟化备份
【责任编辑:武晓燕 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

C语言核心技术

在这本书中,C 语言专家 Peter Prinz和Tony Crawford为你提供大量的编程参考信息。全书叙述清晰,语句简洁,分析深刻。本书主题包括: ...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊