KVM虚拟化基本原理介绍(以ARM64架构为例)
⼀、虚拟化基本概念
最近学习KVM,做了些代码分析,把学习的过程(主要是基于4.15版本内核arm64架构kvm的代码分析)形成⼏个技术⽂档。初步计划分为guest os退出处理分析、内存虚拟化分析和guest以及host之前切换分析等⼏个部分,如果后期有时间的话,补充初始化、中断虚拟化和时钟虚拟化的内容。本⽂先做⼀些ARM64架构虚拟化的基本原理的介绍。
系统级虚拟化
系统级虚拟化是指将⼀台物理计算机虚拟成⼀台或多台虚拟计算机系统,每个虚拟计算机系统有⾃⼰的虚拟硬件(内存、CPU和外设),来提供⼀个独⽴的计算机执⾏环境,能够运⾏完整的操作系统。
虚拟机可以看做是物理机的⼀种⾼效隔离的复制。它有三个特性:
同质:虚拟机的执⾏环境与物理机在本质上是相同的,除了表现上的⼀些差异(属于同⼀套ISA架构)
⾼效:虚拟机中运⾏的软件需要有接近在物理机上直接运⾏的性能。
资源受控:VMM拥有对资源完全的管理权限⽽不是虚拟机上的操作系统。
系统虚拟化好处
封装性
多实例:虚拟机⼀般会有多个实例
隔离:虚拟机之间相互隔离,从⽽提供较⾼的安全性
硬件⽆关性: 与封装性类似,虚拟机与物理环境解耦,从⽽提供了很⾼的灵活性和可维护性。
虚拟化漏洞
可虚拟化架构:并不是所有的CPU架构都是可虚拟化的。其中不可虚拟化的CPU架构就存在虚拟化漏洞。
在虚拟化环境中,VMM管理所有的硬件资源及特权操作。管理硬件资源和执⾏特权操作的指令称作敏感指令。在没有VMM之前,由操作系统来执⾏特权指令和操作硬件资源,在出现VMM之后,操作系统不再有执⾏敏感指令的权限,因此它的敏感指令必须能够⾃陷到特权级别被VMM截获,从⽽对其进⾏虚拟化。CPU⼀般都分为多个执⾏模式,所有敏感指令都能⾃陷到特权级别执⾏的架构称为可虚拟化架构。
不可虚拟化架构,则称为存在虚拟化漏洞。arm/arm64/x86架构都存在虚拟化漏洞。
辅助虚拟化
为了避免虚拟化漏洞,需要借助⼀些⼿段对虚拟化进⾏⼀些辅助,⼀般有两种⽅式:
软件辅助虚拟化:解释执⾏(⼆进制翻译):这种效率较低。
硬件辅助虚拟化:Intel VT技术和AMD-V技术,arm64架构也⽀持硬件辅助虚拟化。KVM就是硬件辅助虚拟化技术。
arm64硬件辅助虚拟化架构
x86架构和arm架构区别ARM64 CPU虚拟化
ARM64 CPU架构如图所⽰,⾥⾯包括了虚拟化⽀持,主要有⼀下特点:
增加了⼀个特权模式EL2。VMM运⾏在EL2层,guest os运⾏在EL1层,应⽤程序运⾏在EL0层。
EL2的VMM负责管理硬件资源和调度虚拟机执⾏。
在EL2打开的模式下,EL1和EL0下的⼀些特权操作会陷⼊到EL2模式下(CPU⾃动检测),VMM可以模拟这些特权操作骗过guest OS。
可以说EL2的出现主要是为了解决虚拟化漏洞,从⽽使ARM64编成可虚拟化架构。
ARM64架构为⼀部分寄存器提供虚拟寄存器,guest os读取虚拟寄存器,从⽽加快虚拟机的切换过程。
中断路由,⼀个中断的⽬标可以配置为hypervisor或者current guest os或者not running gutest os。从⽽为中断虚拟化提供⽀持。
HVC指令,增加了HVC指令,从⽽让guest os必要时可以主动的进⼊EL2执⾏,类似于系统调⽤。
ARM64内存虚拟化
arm64在不考虑安全模式的情况下,存在三种内存地址转换⽅式:
1. EL1 & EL0 VA --> PA :E1和EL0执⾏模式下的虚拟地址直接转换为物理地址。
2. EL2 VA --> PA :EL2下的虚拟地址转为为物理地址。
3. EL1 & EL0 VA --stag1–> IPA --stag2–> PA:EL1/EL0下的虚拟地址转换为中间地址,中间地址再经过⼀次转换转为
物理地址。
上述每个阶段都有单独的页表。
1中是在没有开启EL2模式的stag2转换时,host os(运⾏在EL1)执⾏的地址转换。
2是EL2下的VMM执⾏的地址转换。
3是开启虚拟机时的地址转换.分为两个阶段。stag1:guest os把进程的虚拟地址转换为IPA,stag2: VMM把IPA转换为真正的物理地址PA。这样,为guest os提供了虚假的物理内存,从⽽让guest os能够像管理物理内存⼀样管理⾃⼰的虚拟内存,从⽽骗过了guest os,同时真实的物理内存资源由VMM管理。
arm64 KVM
ARM64下KVM虚拟化的系统的总体结构
其中hyperis(VMM)or由KVM + host Linux共同担任
在ARM 64下分为两种情况,根据CPU是否⽀持VHE特性:
1. 如果CPU⽀持VHE特性,则Linux内核和KVM都在EL2执⾏,这样可以减少EL1和EL2之间模式切换的次数,性能更⾼。
2. 在不⽀持VHE的CPU上(飞腾是这种情况),KVM部分必须在EL2执⾏的代码(⽐如捕获guset OS退出异常)在EL2执⾏,其他
的KVM代码和host Linux都在EL1模式执⾏,这样Hypervisor在进⾏资源管理和虚拟机调度时需要在EL1和EL2之间进⾏
切换,效率⽐1要低。
KVM虚拟化系统的执⾏流
这张图是在⽹上的图,⾮常形象的反应了KVM虚拟化系统的总体执⾏流程。
1. 当位于应⽤层的qemu创建好虚拟机,准备为虚拟机执⾏代码时,调⽤ioctl进⼊内存层的KVM,然后KVM负责从host切换到
guest(VMEntry)模式执⾏虚拟机代码。
2. 虚拟机正常执⾏代码,当执⾏到敏感指令或者要进⾏IO操作时,会⾃陷到EL2模式,进⼊VMM,这就是VMEXIT。
3. kvm(VMM)处理guest的退出原因,⽐如模拟敏感指令,如果是IO操作,得进⼊⽤于层qemu就⾏设备模拟。
4. qemu模拟完IO操作再此ioctl进⼊kvm,如此循环执⾏。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。