赞
踩
除了CPU虚拟化技术,另一个关键的虚拟化技术是内存虚拟化技术。像Linux这种大型操作系统的内存管理的内容是很复杂的,而内存虚拟化技术也是其中一个关键技术。
所谓的内存虚拟化,即如何在多个虚拟机之间共享物理内存以及如何进行动态分配,它的本质就是将物理内存地址映射到一段线性地址空间,也有叫逻辑地址空间,应用程序访问内存物理地址是通过段页查询机制完成。而这个线性地址空间或逻辑地址空间本身就是物理内存的虚拟化呈现。
在虚拟化环境中,分配给虚拟机内存非常类似于操作系统中关于线性地址空间的实现。操作系统负责维护虚页号到实页号的映射,并将这一 映射信息保存到页表(Page Table)。在 x86架构的CPU中,内存管理单元MMU与TLB(原理参考TLB及其工作原理-CSDN博客)这两个模块就负责实现并优化虚拟内存的性能。
如上图所示,由于VMM与guest OS操作系统在对物理内存的认识上存在冲突,这使得真正拥有物理内存的VMM必须对guest OS操作系统所访问的内存进行一定程度的虚拟化。换句话说,就是VMM 负责将MMU进行虚拟化,为guest OS操作系统提供一段连续的“物理”地址空间,而操作系统本身不会意识到这种变化,仍能够将虚拟机虚拟地址(Guest Virtual Address,GVA)映射到虚拟机物理地址(Guest Physical Address,GPA),但是需要VMM将虚拟机物理地址映射到物理机物理地址(Host Physical Address,HPA)。
所以,内存虚拟化的本质就是把物理机的真实物理内存统一管理,包装成多份虚拟的内存给若干虚拟机使用。内存虚拟化的核心,在于引入一层新的地址空间---guest OS物理地址空间,guest OS以为自己运行在真实的物理地址空间中,实际上它是通过VMM访问真实的物理地址的。在VMM中保存客户机地址空间和物理机地址空间之间的映射表。
虚拟化系统中包括三层内存地址空间:虚拟机虚拟地址GVA、虚拟机物理地址GPA和物理机物理地址HPA。因此,原先由MMU完成的线性地址到物理地址的映射已经不能满足,必须由VMM接入来完成这三层地址的映射维护和转换。
Logical Pages:GVA,指GuestOS提供给其应用程序使用的线性地址空间。
Physical Pages:GPA,经VMM抽象的,虚拟机看到的伪物理地址空间。
Machine pages:HPA,真实的机器地址,即地址总线上出现的地址信号。
为了实现上述映射和转换关系,主要有软件方式实现和硬件实现两种解决方案:
软件方式:通过软件实现内存地址的翻译,比如 Shadow page table (影子页表)技术
硬件实现:基于 CPU 的辅助虚拟化功能,比如 AMD 的 NPT 和 Intel 的 EPT 技术
MMU半虚拟化的主要原理涉及虚拟机的内存管理单元(MMU)和页表的处理。当客户机操作系统(Guest OS)创建新页表时,虚拟化监控器(VMM)会从维护的空闲内存中为其分配页面并进行注册。随后,当Guest OS对该页表进行写操作时,这些操作会陷入VMM进行验证和转换。VMM会检查页表中的每一项,确保它们只映射到属于该虚拟机的机器页面,并且不包含对页表页面的可写映射。然后,VMM会根据其维护的映射关系(PA-MA),将页表项中的虚拟机逻辑地址(VA)替换为相应的机器地址(MA)。最后,VMM将修改过的页表载入MMU,这样MMU就可以根据修改过的页表直接完成虚拟地址到机器地址的转换。
MMU半虚拟化技术主要通过以下步骤实现:
通过这个过程,MMU半虚拟化技术实现了对Guest OS页表的直接管理和控制,确保了虚拟机对物理内存的访问是安全且高效的。这种技术减少了Hypervisor的工作负担,提高了虚拟化环境的整体性能。
相比较MMU半虚,大部分虚拟化厂商在VMM中还使用了一种称为影子页表(Shadow Page Table)的技术实现上述功能。对于每个虚拟机的主页表(Primary Page Table),VMM都维持一个影子页表来记录和维护GVA与HPA的映射关系。
影子页表包括以下两种映射关系,
1)GVA>>>GPA,虚拟机操作系统负责维护从虚拟机逻辑地址到虚拟机物理地址的映射关系,VMM可以从虚拟机主页表中获取这种映射关系。
2)GPA>>>HPA,VMM负责维护从虚拟机物理地址到物理机物理地址的映射关系。
通过这种两级映射的方式,VMM为Guest OS的每个页表维护一个影子页表,并将GVA-HPA的映射关系写入影子页表,Guest OS的页表内容保持不变,然后,VMM将影子页表写入MMU。同时,又对虚拟机可访问的内存边界进行了有效控制。并且,使用TLB缓存影子页表的内容可以大大提高虚拟机问内存的速度。
影子页表的维护将带来时间和空间上的较大开销。时间开销主要体现在Guest OS构造页表时不会主动通知VMM,VMM必须等到Guest OS发生缺页错误时(必须Guest OS要更新主页表),才会分析缺页原因再为其补全影子页表。而空间开销主要体现在VMM需要支持多台虚拟机同时运行,每台虚拟机的 Guest OS通常会为其上运行的每个进程创建一套页表系统,因此影子页表的空间开销会随着进程数量的增多而迅速增大。
为权衡时间开销和空间开销,现在一般采用影子页表缓存(Shadow Page Table Cache)技术,即VMM在内存中维护部分最近使用过的影子页表,只有当影子页表在缓存中找不到时,才构建一个新的影子页表。当前主要的虚拟化技术都采用了影子页表缓存技术。
内存的硬件辅助虚拟化技术是用于替代虚拟化技术中软件实现的“影子页表”的一种硬件辅助虚拟化技术,其基本原理是:GVA(客户操作系统的虚拟地址)-> GPA(客户操作系统的物理地址)-> HPA(宿主操作系统的物理地址)两次地址转换都由CPU硬件自动完成(软件实现内存开销大、性能差)。为此,各大CPU厂商相继推出了硬件辅助的内存虚拟化技术,比如Intel的EPT(Extended Page Table)和AMD的NPT(Nested Page Table),它们都能够从硬件上同时支持GVA->GPA和GPA->HPA的地址转换的技术。
GVA->GPA的转换依然是通过查找gPT页表完成的,而GPA->HPA的转换则通过查找nPT页表来实现,每个guest VM有一个由VMM维护的nPT。其实,EPT/NPT就是一种扩展的MMU(以下称EPT/NPT MMU),它可以交叉地查找gPT和nPT两个页表:
设计理念:通过在物理MMU中保存两个不同的页表,使得内存地址的两次映射都在硬件中完成,进而达到提高性能的目的。具体来说,MMU中管理管理了两个页表,第一个是GVA >>>GPA,由虚拟机决定;第二个是GPA>>>HPA,对虚拟机透明,由VMM决定。根据这两个映射页表,CPU中的page walker就可以生成最近访问过key-value键值对<GVA,HPA> ,并缓存在TLB中(类似影子页表缓存技术思路)。
另外,原来在影子页表中由VMM维持的GPA>>>HPA映射关系,则由一组新的数据结构扩展页表(Extended Page Table,也称为Nested Page Table)来保存。由于GPA >>>HPA的映射关系非常定,并在虚拟机创建或修改页表时无需更新,因此VMM在虚拟机更新页表的时候无需进行干涉。VMM也无需参与到虚拟机上下文切换,虚拟机可以自己修改GVA >>>GPA的页表。
我们以Intel EPT技术为例说明。Intel EPT是Intel VT-x 提供的内存虚拟化支持技术,其基本原理下图所示。在原有的CR3页表地址映射的基础上,EPT引入EPT页表来实现另一次映射。比如:假设客户机页表和EPT页表都是4级页表,CPU完成一次地址转换的基本过程如下:
CPU首先查找客户机CR3寄存器指向的L4页表。客户机CR3寄存器给出的是GPA,所以,CPU通过EPT页表将客户机CR3中的GPA转换为HPA:CPU 首先查找EPT TLB,如果没有相应的记录,就进一步查找EPT页表,如果还没有,CPU则抛出EPT Violation异常交给VMM处理。
CPU获得L4页表地址(指的是HPA)后,CPU根据GVA和L4页表项的内容来获取L3 页表项的GPA。如果L4页表中GVA对应的表项显示为“缺页”,那么CPU 产生Page Fault,直接交由客户机操作系统处理。获得L3 页表项的GPA后,CPU通过查询EPT页表来将L3的GPA转换为HPA。同理,CPU 会依次完成L2、L1页表的查询,获得GVA所对应的GPA,然后进行最后一次查询EPT页表获得HPA。
正如上图所示,CPU需要5次查询EPT页表,每次查询都需要4次内存访问。这样,在最坏的情况下总共需要20次内存访问。EPT硬件通过增大EPT TLB 尽量减少内存访问。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。