searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

虚拟化隔离技术介绍

2023-07-03 06:41:21
343
0

虚拟化隔离技术介绍

虚拟机隔离是指虚拟机之间在没有授权许可的情况下,互相之间不可访问的一种技术。那虚拟机是怎样实现隔离技术的呢,以下我们以主流qemu+kvm为例简单介绍说明其原理,下面我们主要介绍指令和内存相关部分,外设部分由于可以通过软件模拟实现,不做进一步介绍。

1.1          不同虚拟机之间的虚拟CPU(vCPU)指令实现隔离

Hypervisor模拟vCPU所用到的主流技术,有Intel vmx和AMD svm等硬件辅助虚拟化技术。以Intel vmx为例,vmx操作有两种:vmx root operation和vmx non-root operation,分别对应宿主机CPU的执行和虚拟CPU的执行。通常,Hypervisor将在vmx root operation中运行,虚拟操作系统及软件将在vmx non-root operation中运行。 在宿主机(Host)端, 每个虚拟机(Guest)以一个进程的形式存在,而Guest的VCPU 对应进程中的一个线程,线程代表vCPU运行,由于线程是一个单独的调度单元,所以vCPU有自己独立的执行上下文,不同的vCPU可以在不同的物理CPU上执行,也可以在相同的物理CPU上按时间片交替执行,但不能在相同的物理CPU上同时执行,这是由Linux调度程序保证的。在Host端不同的vCPU是不同的调度实体,Guest只能调度自己拥有的vCPU线程执行,保证不同Guest之间vCPU的隔离,具体对应关系如图1-1所示。

图1-1 Guest VCPU在Hypervisor中的对应关系

 

物理CPU可以做到指令间的隔离,是因为每个物理CPU有独立的执行单元,两个物理CPU的执行不会相互干扰(除了CPU间争抢Cache,造成的对速度的影响,但Cache对执行结果是无影响的)。对虚拟机来说,不直接感知物理CPU,虚拟机的计算单元通过vCPU对象来呈现。虚拟机只看到VMM呈现给它的vCPU。在VMM中,每个vCPU对应一个VMCS(Virtual-Machine Control Structure)结构,VMCS 可以在不同物理CPU间迁移,但VMCS 与物理 CPU是一对一的绑定关系,即一个 VMCS 只能与一个物理 CPU 绑定,当VCPU被从物理CPU上切换下来的时候,与虚拟机处理器紧密相关的重要数据结构 VMCS保存在内存中,包含了虚拟CPU 的相关寄存器的内容和虚拟CPU相关的控制信息;当VCPU被切换到物理CPU上运行时,其相关信息会从对应的VMCS结构中导入到物理CPU上。通过这种方式,实现各vCPU之间的独立运行。

在宿主机看来,它只能看到Guest的vCPU被调度执行,但是vCPU具体执行什么东西,它是看不见的。vCPU对宿主机系统来说,只是一个普通的线程,当执行vCPU线程时,CPU切换到VMX non-root operation,在切换过程中会保存宿主机端的CPU的上下文信息,加载vCPU的上下文信息, 进入到Guest的世界后,vCPU的执行就像是物理主机上物理CPU的执行, vCPU运行过程中如由需要退出VMX non-root operation(如发生异常或外部中断等事件,或执行I/O 操作),会再次切换到VMX root operation(保存vCPU的上下文信息,加载宿主机的CPU上下文信息),这样就保证了vCPU间的执行不会相互干扰,vCPU和Host的执行环境也不会相互干扰。

1.2          不同虚拟机之间实现内存隔离

Guest无法直接使用Host的MMU进行地址转换。虚拟机的寻址需要经历一系列繁杂的转换:虚拟机虚拟地址(GVA)-> 虚拟机物理地址(GPA)->宿主机虚拟地址(HVA)->宿主机物理地址(HPA),为了简化这一步骤,往往有硬件和软件两种方式。

传统的内存虚拟化通过影子页表实现,但是影子页表实现复杂,而且内存开销很大,每个Guest进程都需要维护自己的影子页表,主流虚拟化技术基本不再使用。

基于硬件支持的内存虚拟化技术能较好的解决影子页表带来的问题,Intel CPU 提供 EPT 技术支持内存虚拟化,AMD 提供 NPT 技术支持内存虚拟化。以Intel CPU的EPT为例,在Guest中的内存需要经过两次地址翻译最终实现GVA到HPA的映射。如图1-2所示

图1-2 Intel CPU硬件地址翻译过程

EPT 在原有虚拟机页表对GVA到GPA映射的基础上,又引入了 EPT 页表来实现GPA到HPA的映射,这两次地址映射都是由硬件自动完成。虚拟机运行时,虚拟机页表被载入 CR3,而 EPT 页表被载入专门的 EPT 页表指针寄存器 EPTP。 EPT 页表对地址的映射机理与虚拟机页表对地址的映射机理相同。与影子页表相比Hypervisor只需为每个虚拟机维护一套 EPT 页表,也大大减少了内存的额外开销并提高了性能,EPT页表可以使用前就建立,也可以使用中建立,由缺页、写权限不足等原因导致虚拟机退出,产生 EPT 异常来建立。对于EPT 缺页异常,Hypervisor首先根据引起异常的虚拟机物理地址,映射到对应的宿主机虚拟地址,然后为此虚拟地址分配新的物理页,最后 Hypervisor再更新 EPT 页表,建立起引起异常的虚拟机物理地址到宿主机物理地址之间的映射。对 EPT 写权限引起的异常,Hypervisor则通过更新相应的 EPT 页表来解决。

Host上的普通进程和虚机进程使用的地址映射机制在Host上是不一样的,普通进程只需要MMU的地址翻译,虚机的进程需要使用vMMU 和EPT的地址翻译,那么两种进程是怎么和平相处,不相互影响呢?

首先对于运行在Host的普通进程,则继续沿用之前的MMU地址翻译过程,内存地址使用之前,由Host上的内存管理单元统一分配,并建立Page Table后使用。

而Guest的进程在Host端作为普通进程存在,在维护EPT页表的同时,也会建立Host端的普通Page Table,所有分配给Guest的HPA,不但需要在EPT中建立页表映射,也需要通过Host端内存管理单元在Host端的进程中建立页表映射,并建立起两个页表的一一对应关系。即EPT建立页表为虚机分配HPA之前,需要先以普通进程的身份在Host上分配内存,再把此内存经由EPT分配给Guest, 这样就保证了在Host上HPA的分配统一化,不同的Guest分配不同的HPA地址,Guest和Host上普通进程也分配不同HPA地址,最好实现了内存的隔离(明确共享的页面除外,比如KSM(Kernel Samepage Merging)或某些只读共享页)。

从虚拟机角度看其自身拥有的内存就是真实的物理内存。实际上,虚拟机是 Host 上的一个普通进程,在为虚拟机指定内存时,Host 上并没有分配该内存给虚拟机,而是需要使用内存时,由 Hypervisor 分配内存给它。虚拟机的物理地址空间并不一定是连续的,虚拟机物理地址空间有可能映射在若干个不连续的宿主机地址区间,如下图 1-2 所示:

图1-3 Guest内存映射

 

1.3          虚拟机的内存被释放或再分配给其他虚拟机前得到完全释放。

在虚拟机中分配内存时,其实并没有分配真实的内存,在真正使用到内存时,退出到Host由Hypervisor 分配,对于Hypervisor 分配来说,给虚机分配内存只是给虚机的进程分配内存,给进程分配的内存空间对应于HVA, 最终映射到哪个HPA上,由Host上的内存管理子系统负责, Host上的内存管理子系统统一分配Host上的所有物理内存(HPA),对于给一个进程分配的HPA内存空间,会在内存管理子系统中作已分配标记,另一个进程再分配时就会分配不一样的HPA(除非进程显示释放后再分配,或显示共享),当Host上HPA不足时,Host可能会回收部分分配给Guest的内存并在EPT 中作页面不存在标记,Guest后续再次访问已回收的内存时,会引发EPT Violation异常,EPT Violation异常会重新为Guest分配新的HPA地址空间。从而保证了虚拟机的物理内存不会重复分配给不同的虚拟机。

0条评论
0 / 1000
刘强
6文章数
2粉丝数
刘强
6 文章 | 2 粉丝
原创

虚拟化隔离技术介绍

2023-07-03 06:41:21
343
0

虚拟化隔离技术介绍

虚拟机隔离是指虚拟机之间在没有授权许可的情况下,互相之间不可访问的一种技术。那虚拟机是怎样实现隔离技术的呢,以下我们以主流qemu+kvm为例简单介绍说明其原理,下面我们主要介绍指令和内存相关部分,外设部分由于可以通过软件模拟实现,不做进一步介绍。

1.1          不同虚拟机之间的虚拟CPU(vCPU)指令实现隔离

Hypervisor模拟vCPU所用到的主流技术,有Intel vmx和AMD svm等硬件辅助虚拟化技术。以Intel vmx为例,vmx操作有两种:vmx root operation和vmx non-root operation,分别对应宿主机CPU的执行和虚拟CPU的执行。通常,Hypervisor将在vmx root operation中运行,虚拟操作系统及软件将在vmx non-root operation中运行。 在宿主机(Host)端, 每个虚拟机(Guest)以一个进程的形式存在,而Guest的VCPU 对应进程中的一个线程,线程代表vCPU运行,由于线程是一个单独的调度单元,所以vCPU有自己独立的执行上下文,不同的vCPU可以在不同的物理CPU上执行,也可以在相同的物理CPU上按时间片交替执行,但不能在相同的物理CPU上同时执行,这是由Linux调度程序保证的。在Host端不同的vCPU是不同的调度实体,Guest只能调度自己拥有的vCPU线程执行,保证不同Guest之间vCPU的隔离,具体对应关系如图1-1所示。

图1-1 Guest VCPU在Hypervisor中的对应关系

 

物理CPU可以做到指令间的隔离,是因为每个物理CPU有独立的执行单元,两个物理CPU的执行不会相互干扰(除了CPU间争抢Cache,造成的对速度的影响,但Cache对执行结果是无影响的)。对虚拟机来说,不直接感知物理CPU,虚拟机的计算单元通过vCPU对象来呈现。虚拟机只看到VMM呈现给它的vCPU。在VMM中,每个vCPU对应一个VMCS(Virtual-Machine Control Structure)结构,VMCS 可以在不同物理CPU间迁移,但VMCS 与物理 CPU是一对一的绑定关系,即一个 VMCS 只能与一个物理 CPU 绑定,当VCPU被从物理CPU上切换下来的时候,与虚拟机处理器紧密相关的重要数据结构 VMCS保存在内存中,包含了虚拟CPU 的相关寄存器的内容和虚拟CPU相关的控制信息;当VCPU被切换到物理CPU上运行时,其相关信息会从对应的VMCS结构中导入到物理CPU上。通过这种方式,实现各vCPU之间的独立运行。

在宿主机看来,它只能看到Guest的vCPU被调度执行,但是vCPU具体执行什么东西,它是看不见的。vCPU对宿主机系统来说,只是一个普通的线程,当执行vCPU线程时,CPU切换到VMX non-root operation,在切换过程中会保存宿主机端的CPU的上下文信息,加载vCPU的上下文信息, 进入到Guest的世界后,vCPU的执行就像是物理主机上物理CPU的执行, vCPU运行过程中如由需要退出VMX non-root operation(如发生异常或外部中断等事件,或执行I/O 操作),会再次切换到VMX root operation(保存vCPU的上下文信息,加载宿主机的CPU上下文信息),这样就保证了vCPU间的执行不会相互干扰,vCPU和Host的执行环境也不会相互干扰。

1.2          不同虚拟机之间实现内存隔离

Guest无法直接使用Host的MMU进行地址转换。虚拟机的寻址需要经历一系列繁杂的转换:虚拟机虚拟地址(GVA)-> 虚拟机物理地址(GPA)->宿主机虚拟地址(HVA)->宿主机物理地址(HPA),为了简化这一步骤,往往有硬件和软件两种方式。

传统的内存虚拟化通过影子页表实现,但是影子页表实现复杂,而且内存开销很大,每个Guest进程都需要维护自己的影子页表,主流虚拟化技术基本不再使用。

基于硬件支持的内存虚拟化技术能较好的解决影子页表带来的问题,Intel CPU 提供 EPT 技术支持内存虚拟化,AMD 提供 NPT 技术支持内存虚拟化。以Intel CPU的EPT为例,在Guest中的内存需要经过两次地址翻译最终实现GVA到HPA的映射。如图1-2所示

图1-2 Intel CPU硬件地址翻译过程

EPT 在原有虚拟机页表对GVA到GPA映射的基础上,又引入了 EPT 页表来实现GPA到HPA的映射,这两次地址映射都是由硬件自动完成。虚拟机运行时,虚拟机页表被载入 CR3,而 EPT 页表被载入专门的 EPT 页表指针寄存器 EPTP。 EPT 页表对地址的映射机理与虚拟机页表对地址的映射机理相同。与影子页表相比Hypervisor只需为每个虚拟机维护一套 EPT 页表,也大大减少了内存的额外开销并提高了性能,EPT页表可以使用前就建立,也可以使用中建立,由缺页、写权限不足等原因导致虚拟机退出,产生 EPT 异常来建立。对于EPT 缺页异常,Hypervisor首先根据引起异常的虚拟机物理地址,映射到对应的宿主机虚拟地址,然后为此虚拟地址分配新的物理页,最后 Hypervisor再更新 EPT 页表,建立起引起异常的虚拟机物理地址到宿主机物理地址之间的映射。对 EPT 写权限引起的异常,Hypervisor则通过更新相应的 EPT 页表来解决。

Host上的普通进程和虚机进程使用的地址映射机制在Host上是不一样的,普通进程只需要MMU的地址翻译,虚机的进程需要使用vMMU 和EPT的地址翻译,那么两种进程是怎么和平相处,不相互影响呢?

首先对于运行在Host的普通进程,则继续沿用之前的MMU地址翻译过程,内存地址使用之前,由Host上的内存管理单元统一分配,并建立Page Table后使用。

而Guest的进程在Host端作为普通进程存在,在维护EPT页表的同时,也会建立Host端的普通Page Table,所有分配给Guest的HPA,不但需要在EPT中建立页表映射,也需要通过Host端内存管理单元在Host端的进程中建立页表映射,并建立起两个页表的一一对应关系。即EPT建立页表为虚机分配HPA之前,需要先以普通进程的身份在Host上分配内存,再把此内存经由EPT分配给Guest, 这样就保证了在Host上HPA的分配统一化,不同的Guest分配不同的HPA地址,Guest和Host上普通进程也分配不同HPA地址,最好实现了内存的隔离(明确共享的页面除外,比如KSM(Kernel Samepage Merging)或某些只读共享页)。

从虚拟机角度看其自身拥有的内存就是真实的物理内存。实际上,虚拟机是 Host 上的一个普通进程,在为虚拟机指定内存时,Host 上并没有分配该内存给虚拟机,而是需要使用内存时,由 Hypervisor 分配内存给它。虚拟机的物理地址空间并不一定是连续的,虚拟机物理地址空间有可能映射在若干个不连续的宿主机地址区间,如下图 1-2 所示:

图1-3 Guest内存映射

 

1.3          虚拟机的内存被释放或再分配给其他虚拟机前得到完全释放。

在虚拟机中分配内存时,其实并没有分配真实的内存,在真正使用到内存时,退出到Host由Hypervisor 分配,对于Hypervisor 分配来说,给虚机分配内存只是给虚机的进程分配内存,给进程分配的内存空间对应于HVA, 最终映射到哪个HPA上,由Host上的内存管理子系统负责, Host上的内存管理子系统统一分配Host上的所有物理内存(HPA),对于给一个进程分配的HPA内存空间,会在内存管理子系统中作已分配标记,另一个进程再分配时就会分配不一样的HPA(除非进程显示释放后再分配,或显示共享),当Host上HPA不足时,Host可能会回收部分分配给Guest的内存并在EPT 中作页面不存在标记,Guest后续再次访问已回收的内存时,会引发EPT Violation异常,EPT Violation异常会重新为Guest分配新的HPA地址空间。从而保证了虚拟机的物理内存不会重复分配给不同的虚拟机。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
1
1