硬件虚拟化介绍
硬件虚拟化要做的事情
体系结构支持
体系结构 | 实现功能 | 作用 |
---|---|---|
模式切换 | Host CPU <-> Guest CPU 切换 | CPU 资源隔离 |
二阶段地址转换 | GVA-> GPA | |
GPA-> HPA | 内存资源隔离 | |
中断控制器支持 | 中断注入和透传 | 中断资源隔离 |
IOMMU | DMA Remapping | DMA 和设备访问内存隔离 |
相应的硬件实现
x86 架构
AMD 架构
RISC-V 架构
相关软件支持
软件 | 举例 |
---|---|
Firmware | OpenSBI、BIOS |
Hypervisor | KVM,XEN |
I/O 用户态 | qemu |
OS | Linux |
CPU 虚拟化
CPU 支持模式切换:硬件支持
-
Host CPU <-> Guest CPU:CPU 运行环境的隔离,CPU 虚拟化的基础
模式切换
-
vm entry:从 Host CPU 进入到 Guest CPU,由特殊指令实现;
-
vm exit:从 Guest CPU 退出到 Host CPU,执行特定指令;中断;异常
切换过程的上下文的保存和恢复
由于 guest CPU 看不到 Host CPU state,故都是在 Host CPU 模式下操作
-
vm entry 前:保存 Host CPU State,恢复 Guest CPU state
-
vm exit 后:保存 Guest CPU state,恢复 Host CPU State
vCPU:一个 Linux 线程
x86 架构
VMX Operation Mode
只有在 VMX Operation Mode 下才可以实现:
-
VMX root mode:Host CPU
-
VMX non-root mode: Guest CPU
使用 VMXON 和 VMXOFF 开启和关闭。
模式切换方法
-
vm entry: vmlaunch/vmresume 指令
-
vm exit:执行指令;发生异常或中断
上下文状态:VMCS,Virtual Machine Control Structure
Notions:
-
一个 vCPU 对应一个 VMCS 状态;
-
只有 x86 支持在 vm-entry 和 vm exit 的时候,VMCS 由硬件进行保存和恢复。
-
虚拟化优化方向:减少
vm emtry
和vm exit
过程。
ARM 架构
Exception Level
-
EL0
- Host App: Host CPU
- Guest App:Guest CPU
-
EL1:Guest CPU
-
EL2: Host CPU
-
EL3
模式切换方法
-
vm entry: eret 指令
-
vm exit: 指令或异常
上下文状态
上下文状态自定义,由软件来实现保存和恢复。
RISC-V 架构
Privilege Level
-
U(User Mode,用户态): Host CPU
-
VU(Virtualized User Mode,虚拟化用户态):Guest CPU
-
VS(Virtual Supervisor Mode,虚拟化监管态):Guest CPU
-
HS(Host Supervisor Mode,宿主机监管态):Host CPU
-
M(Machine Mode,机器态)
模式切换方法
-
vm entry: sret 指令
-
vm exit: 指令或异常
上下文状态
上下文状态自定义,由软件来实现保存和恢复。
内存虚拟化
基本概念
GVA:Guest Virtual Address
GPA:Guest Physical Address
HVA:Host Virual Address,主机虚拟地址
HPA:Host Physical Address,主机物理地址
转换关系和维护
-
GVA ->GPA:Guest OS 维护
-
HVA -> HPA: Host OS 维护
-
GPA <-> HVA: qemu/KVM
-
GPA <-> HPA: 硬件支持 EPT/NPT
内存虚拟化目标:如何让 Guest 的访问地址(GVA/GPA)转换成 HPA,且由硬件实现。
软件实现——影子页表
能够直接完成 GVA->HPA 的转换。被 Hpyervisor 载入到物理 MMU 中的页表是影子页表。缺陷:
-
需要为 Guest OS 的每个进程维护一个影子页表,资源消耗大;
-
Guest OS 在读写 CR3、执行 INVLPG 指令或客户页表不完整等情况下均会导致 vm exit,内存虚拟化效率很低;
-
Guest OS 的页表和和影子页表的同步也比较复杂;
x86 架构
EPT/NPT
-
Intel:EPT,Extended Page Table
-
AMD:NPT
二阶段地址转换,完成内存虚拟化
-
GVA -> GPA:CR3 指向 Guest OS 页表,完成第一阶段转换,由硬件 MMU 完成;
-
GPA -> HPA:EPTP,指向 EPT 表,完成第二阶段转换,由硬件自动完成。
相对影子页表,只需要一张表即可完成 Guest OS 的内存虚拟化。
ARMv8 架构
VTTBR
VTTBR:Virtualization Translation Table Base Register
二阶段地址转换
-
GVA -> GPA(IPA):TTBRn_EL1
-
GPA -> HPA:VTTBR0_EL2
RISC-V 架构
vsatp&hgatp
vsatp:Virtual Supervisor Address Translation and Protection Register
hgatp:Hypervisor Guest Address Translation and Protection Register
二阶段地址转换
-
GVA -> GPA(IPA):vsatp
-
GPA -> HPA:hgatp
中断虚拟化
基本概念
IPI:Inter-Processor Interrupt,处理器间中断
MSI:Message Signaled Interrupt,消息信号中断
中断处理流程
-
中断触发:中断源发生中断事件,向 CPU 发送中断信号
-
检测中断:CPU 检测到中断,停止当前执行流程,跳转到中断向量
-
处理中断:CPU 保存上下文,调用和执行中断处理函数,然后返回原有执行流程
中断来源不同,导致虚拟化方式不同:
-
IPI:inter-processor interrupt
-
timer 中断
-
external 中断:包括 MSI
虚拟化方法一:发生 vm exit 和中断注入
-
如果中断发生在当前 pCPU 上:如果 vCPU 处于运行状态,Guest CPU 不会发生 vm exit,中断直接投递给 vCPU;
-
如果 vCPU 处于等待状态,调用 kvm_kick_cpu, 唤醒 vCPU 的线程,把中断信息投递到 Guest CPU State,让 vCPU 进入 Guest CPU 模式
-
如果中断发生在其他 pCPU,需要向当前 pCPU 发送 IPI
-
vCPU 在 Guest CPU 模式下完成处理中断
特点
-
中断发生时,vCPU 会发生 vm exit,效率低
-
在没有中断控制器的特殊支持时,大多数硬件都支持此种中断虚拟化
虚拟化方法二: 中断直接投递给 vCPU
-
如果中断发生在当前 pCPU 上:
- 如果 vCPU 处于运行状态,Guest CPU 不会发生 vm exit,中断直接投递给 vCPU;
- 如果 vCPU 处于等待状态,调用 kvm_kick_cpu, 唤醒 vCPU 的线程,把中断信息投递到 Guest CPU State,让 vCPU 进入 Guest CPU 模式;
-
如果中断发生在其他 pCPU,需要向当前 pCPU 发送 IPI
-
vCPU 在 Guest CPU 模式下完成处理中断;
特点
-
需要中断控制器的特殊支持;
-
vCPU 不需要产生 vm exit,效率高;
x86 架构
中断控制器:LAPIC、IOAPIC
每个 CPU 接一个 Local APIC,通过地址总线接 IOAPIC,IPAPIC 完成外部中断的投递,Local APIC 完成 IPI 或者 Timer 的处理。
Posted Interrupt
外部中断到来时,中断直接投递到 VCPU 的 Posted Descriptor,Posted Descripter 利用事件通知 pCPU。详细解释:
ARMv8 架构
中断控制器:中断注入——GICv3
中断控制器:中断透传——GICv4
RISC-V 架构
中断控制器:PLIC
-
不支持 MSI
-
不支持中断虚拟化
AIA 定义的两个控制器
RISC-V Advanced Interrupt Architecture:AIA,定义了两个控制器:
-
Incoming Message Signaled Interrupt Controller (IMSIC):支持 MSI;支持 IPI 虚拟化;
-
Advanced Platform Level Interrupt Controller (APLIC):支持 Wired Interrupt;
例子:KVM 通过 IMSIC 注入中断
-
HART0 的 KVM 写 MMIO 到某 HVA
-
HVA 通过 SATP 和转换变为 HPA
-
写入 HARTx 的 IMSIC 的寄存器
-
发送信号给 HARTx 的 CSR
-
注入中断到 HARTx 的 Guest_A 的 vCPU B
例子:Guest_A vCPU_A 发送到 Guest_A vCPU_B 的 IPI 中断
-
HART0 的 Guest_A 的 vCPU A 写 MMIO 到某 GVA
-
GVA 通过 VSATP 和 HGATP, 经过两次转换变为 HPA
-
写入 HARTx 的 IMSIC 的寄存器
-
发送信号给 HARTx 的 CSR
-
触发 HARTx 的 Guest_A 的 vCPU B 的 IPI
设备虚拟化
基本概念
IOMMU:Input-Output Memory Management Unit
-
MMU:CPU 通过 VA 访问内存
-
IOMMU:设备通过 IO VA 访问内存
IOMMU 作用
-
DMA 设备的虚拟地址转换。完成 IOVA -> HPA 的转换。把设备发送的 IOVA 转换成 HPA。
-
DMA 设备的内存写保护
-
Interrupt remapping 和虚拟化
-
IO 设备可以共享页表
IOMMU 地址转换
-
X86 IOMMU:包括 dma remapping 和 interrupt remapping
- Intel:VT-D
- AMD:AMD IOMMU
-
ARMv8:SMMUv3
-
RISC-V:RISC-V IOMMU
设备透传
VFIO:Virtual Function I/O 是 Linux 下利用 IOMMU 构建设备直通方案。用户态进程可以使用 VFIO 驱动直接访问硬件,并且由于整个过程是在 IOMMU 的保护下进行因此十分安全, 而且非特权用户也是可以直接使用。实现了 VM 中的 GPA 映射到 HPA,并且使用 DMA-remapping 将设备中断发送回 VM。
设备透传的作用
-
透传 GPU/网络设备给虚拟机
-
虚机的 GPU/网络驱动,不需要做任何修改就可以直接使用透传设备
-
性能损耗最小
设备透传的应用
-
GPU 设备透传
-
网卡透传
-
磁盘透传