1. 理论知识:内存虚拟化
应用程序获取到的内存空间即线性虚拟地址空间,而真正用于数据交互的是底层的物理地址空间。MMU(Memory Management Unit)内存管理单元,负责虚拟内存空间VA到真实物理内存MA的映射,这种映射关系的组合称为页表。
对于虚拟机来说,虚拟机中的应用程序申请的空间也是虚拟地址空间,然后映射成虚拟机中的物理地址空间GPA(Guest Physical Address),而虚拟机中运行的操作系统(即客户机操作系统Guest OS)相对于VMM(虚拟机通过程序VMM来创建)来说就是一个应用程序,因此要从GPA通过VMM映射成真实的物理地址MA。
1、 内存全虚拟化技术(也称影子页表虚拟化)
VMM为每个虚拟机维护一张影子页表,该页表维护了VA与MA的映射关系,而虚拟机维护VA到GPA的映射关系(即客户机页表)。
当VMM捕捉到客户机页表的修改后,会相应进行查找,找到与该GPA对应的MA,再将新的MA修改到真正在硬件中起作用的影子页表中,从而形成VA到MA的映射关系。
2. 内存半虚拟化技术
半虚拟化技术中,Guest OS中的创建的页表(客户机页表)自身不具备写权限,而是把写权限交给VMM来维护。当Guest OS需要更新页表映射关系,会把写请求交给VMM,VMM会通过查找它维护的影子页表,将写请求中的物理地址替换成真正的物理地址,最后再把修改过的映射关系(VA-MA)载入虚拟机的MMU中,这样虚拟机通过MMU中维护的页表对应关系就可直接访问到底层真实的硬件资源。
3. 内存硬件辅助虚拟化技术
该技术把影子页表中依靠软件实现的过程改为硬件实现,所以性能大大提升、
在内存硬件辅助虚拟化中,Guest OS完成VA到GPA的转换,再由硬件帮忙完成GPA到HPA(宿主机物理内存地址)的转换。第二次转换对于Guest OS来说是透明的,这种技术(GPA-MA)在Intel处理器中称为扩展页表Extended Page Tables(EPT),在AMD处理器中称为Neseted Page Tables(NPT)。
首先,VMM会把客户机物理地址GPA与机器MA地址的映射关系EPT页表设置到CPU中,这样以后客户机无论如何调整客户机页表(VA-GPA)都不再需要VMM的接入,因为CPU会自动查找客户机页表(VA-GPA)和扩展页表(GPA-MA)完成客户虚拟地址VA到机器地址MA的转换。
此外,Intel还引入了转换寻址缓冲区TLB(Translation Lookaside Buffer)技术,用来帮助缓存CPU中的MMU进行地址转换。有个问题,就是当发生VM entry和VM exit时都会强制CPU刷新TLB,导致全部TLB条目失效。因此提出了VPID。
虚拟处理器标识VPID(VirtualProcessor Identifiers)是在硬件上对TLB资源管理的优化,通过在硬件上为每个TLB项增加一个标识(tagged,即打标签),用于不同的虚拟处理器的地址空间,从而能够区分开不同虚拟处理器的TLB,避免了每次进行VM–Entry和VM-Exit时都让TLB全部失效,提高了VM切换的效率。
2. 在VMware中使虚拟机能够使用KVM
3. 查看服务器上CPU对ETP和VPID的支持情况
[root@rebekk ~]# grep -o 'ept vpid' /proc/cpuinfo
ept vpid
# 加载kvm_intel模块
[root@rebekk ~]# modprobe kvm_intel
# 查看该模块信息
[root@rebekk ~]# modinfo kvm_intel
filename: /lib/modules/3.10.0-957.el7.x86_64/kernel/arch/x86/kvm/kvm-intel.ko.xz
license: GPL
author: Qumranet
retpoline: Y
rhelversion: 7.6
srcversion: 376D2B495997A14FEAD763F
alias: x86cpu:vendor:*:family:*:model:*:feature:*0085*
depends: kvm
intree: Y
vermagic: 3.10.0-957.el7.x86_64 SMP mod_unload modversions
signer: CentOS Linux kernel signing key
sig_key: B7:0D:CF:0D:F2:D9:B7:F2:91:59:24:82:49:FD:6F:E8:7B:78:14:27
sig_hashalgo: sha256
parm: vpid:bool
parm: flexpriority:bool
parm: ept:bool
parm: unrestricted_guest:bool
parm: eptad:bool
parm: emulate_invalid_guest_state:bool
parm: vmm_exclusive:bool
parm: fasteoi:bool
parm: enable_apicv:bool
parm: enable_shadow_vmcs:bool
parm: nested:bool
parm: pml:bool
parm: preemption_timer:bool
parm: ple_window:uint
parm: ple_window_grow:uint
parm: ple_window_shrink:uint
parm: ple_window_max:uint
# 检查对EPT和VPID的支持(可通过修改这两个值,来调整对EPT与VPID的支持情况)
[root@rebekk ~]# cat /sys/module/kvm_intel/parameters/ept
Y
[root@rebekk ~]# cat /sys/module/kvm_intel/parameters/vpid
Y