硬件虚拟化介绍
硬件虚拟化要做的事情
体系结构支持
体系结构 | 实现功能 | 作用 |
---|---|---|
模式切换 | 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 设备透传
- 网卡透传
- 磁盘透传