0%

虚拟化技术简介.md

虚拟化技术概述

虚拟机特性:

  • 指令模拟 (guest 和 host 可以是不同的isa)
  • 本地指令直接执行( guest 和 host isa是相同的)

系统资源虚拟化:

  • cpu虚拟化
  • 内存虚拟化
  • io 虚拟化

常见的虚拟机软件:

  • vmware
  • virtual box
  • Parallels Desktop
  • Xen
  • linux-kvm qemu
  • Xvisor

image-20240416111454675

Hypervisor Virtual Machine Manager(VMM) 的功能

  • 控制所有的系统资源(CPU 内存 网络 存储等)
  • 创建虚拟机并分配响应的资源
  • 管理虚拟机的生命周期

VMM 调度程序和操作系统的调度进程类似, 操作系统调度的基本单位是进程/线程, VMM调度的单位是虚拟处理器. 当虚拟cpu被调度到时, VMM调度程序负责将vcpu上下文装载到物理处理器上, 然后vcpu所对应的guest os 指令开始真正被执行. 当时间片用完或虚拟处理器主动让出, 调度程序被触发. 调度程序根据调度策略, 挑选下一个vcpu继续运行.
与操作系统一样, VMM的调度策略可以有多种, 如平均时间片策略, 或按vcpu的权重分配时间片进行调度等.
虚拟机之间可以通信, VMM需要实现对应的通信机制, 并向虚拟机提供对应的api(可以是时间通知, 共享内存等), 需要严格的安全权限检查.

虚拟机环境管理包括创建/删除/暂停/查询/迁移等, 由虚拟机管理软件和VMM 管理接口组成.

物理资源的管理

  1. 处理器管理
    包括系统启动检测获取所有物理处理器, 对每个处理器进行初始化, 如设置运行模式, 设置页表, 设置中断处理函数等; 将所有的处理器纳入调度序列, 由调度程序对其进行调度. 还支持hot plug, 当有处理器插入时, vmm获得通知, 将其纳入调度序列. 当处理器拔出时, vmm 得到通知, 将该处理器上执行的任务迁移到其他处理器上, 并将其从管理队列中删除.

云服务存在多个处理器节点, 当某些节点出现故障时, 其上运行的guest os 不会宕机, 而是转移到其他正常工作的cpu节点上;
同样为了安全的扩充处理器资源, 在不断电的基础上进行cpu的扩充进而降低系统负载, 对服务器来说也是必要的;
2. 内存管理
系统启动时VMM检测并获取所有内存, 对获得的内存进行初始化, 包括分页设置页表等; 提供内存分配的接口, 给虚拟机分配内存, 并且维护虚拟机物理地址和实际物理地址的映射关系
3. 中断管理
根据中断来源, 或直接处理, 或转发给guest os 处理
4. 系统时间维护
VMM 拥有和时间相关的硬件资源, VMM 负责维护系统时间, 同时向各guest os 提供虚拟化的时间
5. 设备管理
所有的外设都属于VMM, VMM需要包含所有设备的驱动程序. 在混合模型下, 大部分的外部设备属于guest os, 少部分的设备属于VMM

虚拟化的优点:

  • 更高的系统安全性和可用性
    • VMM 作为监视层, 运行在比os更高的特权层
    • 控制过滤虚拟机的行为
    • 监控虚拟机状态, 故障快速恢复
  • 最大化硬件资源使用率
    • 在一个物理主机上创建多个虚拟机共享主机资源, 节约硬件成本
  • 系统易扩展
    • 修改虚拟机的配置来适应业务的负载变化
  • 方便的可移植性
    • 虚拟机的系统消除物理主机的硬件差异
    • 虚拟机以文件镜像的格式封装
  • 硬件级别的隔离特性
    • 通过iommu技术隔离外设

不同类型的VMM:

baremetal vmm (type1)

  • 启动时bootloader/BIOS 直接将执行权限交给hypervisor

  • 直接运行在硬件上, 不依赖基础操作系统

  • 可以控制所有的guest os

  • 交互少, 性能好, 稳定

  • 无法直接利用现有操作系统生态, 硬件兼容性差, 驱动开发工作量大

    VMM根据产品定位, 有选择的挑选一些io 设备来支持, 如面向服务器市场, 只会挑选服务器上的io设备来开发驱动, 另外调度和电源管理等的很多功能需要在VMM中重新实现

  • 典型代表: Xen
    image-20240416111459876

hosted vmm (type2)

  • 启动时bl/BIOS 先启动host os, hypervisor/VMM 相当于host os中跑的一个应用
  • 需要通过host os 来访问硬件资源
  • vmm 只能控制guest os, 不能控制host os中的其他部分
  • guest os 和 host os 交互调用链长, 影响性能
  • 攻击窗口多, 安全性差
  • 可以直接利用现有操作系统生态, 硬件兼容性好
  • 典型代表: linux kvm
    image-20240416111504708

KVM的思想是在Linux内核的基础上添加虚拟机管理模块,重用Linux内核中已经完善的进程调度、内存管理、IO管理等代码,使之成为一个可以支持运行虚拟机的Hypervisor

image-20240416111508288

混合模型

上述两种模式的集合体, VMM依然位于最底层, 拥有所有的物理资源, 与type1 模式不同的是, VMM会让出大部分io设备的控制权, 将它们交给guest os 控制, 相应的, VMM虚拟化的职责被分担, 处理器和内存的虚拟化仍由VMM 完成, 而IO虚拟化则由VMM和guest os 合作完成.

Hypervisor 的实现

半虚拟化:

  • 将guest os 降权, 使其无法直接访问系统特权资源
  • vmm 提供访问系统特权资源的hyper call api
  • 修改guest os, 用hyper call api 访问系统特权资源
  • 高效轻量, 性能好
  • guest os 修改量大, 使用不便

全虚拟化:

  • 将guest os 运行在vmm 创建的独立环境里
  • vmm 将内核特权访问操作翻译成一系列对vmm 的请求 (软件方案)
  • guest os对虚拟化环境不感知, 不需要修改guest os
  • vmm 实现复杂
  • vmm和guest os 之间翻译产生的负载比较大, 性能差

硬件虚拟化在半虚拟化和全虚拟化基础上提供了硬件辅助

用来简化VMM实现, 提高性能

  • intel VT-x VT-d
  • AMD svm iommu
  • ARM hypervisor层 smmu
  • riscv h-extension层 iommu

CPU 虚拟化

虚拟CPU上下文

  • 类似于进程上下文的概念,当虚拟机发生退出时,需要保存虚拟CPU中各寄 存器的状态
  • 发生虚拟CPU调度时,需要保存当前虚拟CPU的上下文并加载待调度虚拟 CPU上下文

image-20240416111513395

软件方案

x86 虚拟化技术早期, 没有cpu虚拟化的硬件支持, VMM 运行在特权级, guest os运行在非特权级(用户态), 这种方式称为特权级压缩(Ring Compression). guest os 上内核运行特权指令时, 通常会触发异常, 进入特权级, 由VMM 截获异常并进行处理, 但是有一些非特权敏感指令并不会触发异常, 这种状态下, VMM就需要扫描guest os的内核的所有的这些不会触发异常的敏感指令, 将其翻译成支持虚拟化的指令(会触发异常的指令), vmm 再去处理这些翻译后指令触发的异常.

修改系统资源的,或者在不同模式下行为有不同表现的,都属于敏感指令

硬件辅助方案

软件方案是非常低效的, 且vmm 实现过于复杂, Intel VT-x、AMD SVM、ARM EL2、RISC-V H-Extension, 加入了一层特权级别, guest os 运行在这一层上, 这一层上所有特权指令均会触发异常, 可以被VMM截获处理

image-20240416111517531

中断虚拟化

虚拟化系统中, 设置中断处理流程

1. 设备产生一个水平/边缘触发中断信号
2. 中断控制器响应该信号, 让cpu 进入VMM host 内核态的 中断异常模式
3. CPU 调用VMM 中断服务程序, 通过IRQ number 找到对应的guest os, 通过`中断注入程序`向guest os 注入virtual irq
4. guest os cpu进入guest 内核态的中断异常模式
5. guest os 调用中断服务程序, 通过virtual irq number 找到对应的驱动中断处理函数
6. 完成中断处理 

image-20240416111521451

内存虚拟化

常见的内存虚拟化技术

  1. 地址空间分区
    • 简单, 但不灵活
  2. 半虚拟化 shadow page table
    • 虚拟地址模拟物理地址, 性能好, 需要修改guest os

硬件虚拟化- 二级地址翻译

实际上是扩展了影子页表技术, 硬件辅助化的措施: 新增寄存器,供硬件MMU读取, 由硬件mmu 完成二级页表翻译, 避免由软件翻译, 运行时无需vmm 介入.

  1. IPA (intermediate physical address) guest 物理地址
  2. 虚拟机物理地址空间由IPA 描述, 不直接指向真实物理地址
  3. 每个VM的IPA地址独立, 可以相同, 可以重叠, 也可以完全不同
  4. 通过两级地址翻译找到真实物理地址
    1. VA->IPA (guest os)
      arm64 使用TTBRn_EL1寄存器和页表, riscv 使用stap寄存器
    2. IPA->PA (VMM)
      arm64 使用VTTBR_EL2寄存器和stage2 页表, riscv 使用hgatp 寄存器

IO 模拟

image-20240416111526004

  • type2 类 用户态设备模型:

    • QEMU/KVM

    • 用户态设备模型, 运行库生态健壮, 可复用性高

    • 多次上下文切换

  • type1 类 baremental 设备模型:

    • xvisor xen

    • 减少了多次上下文切换

    • 缩短io模拟路径

    • 移植性差

设备类型

  1. MMIO (Memory-mapped I/O)
    特定物理内存区域映射了设备的寄存器, os通过页表以访问内存的方式访问设备寄存器, RISCV 仅支持MMIO
  2. DMA
    无需CPU控制, DMA控制器接管地址总线

IO 虚拟化基本任务

  • 访问截获
  • 提供设备接口
    • 虚拟设备接口, 如暴露虚拟pci 设备
    • 直通设备接口, 如intel VT-d 技术
    • 对虚拟机完全“透明”
  • 实现设备功能
    • type1 类baremental VMM 需要实现设备驱动, 设备模型;
    • type2 类需要实现用户态设备模型 运行库等

MMIO模拟过程

虚拟机陷入过程

  • 访存指令,非特权指令
  • 页表不存在相应页表项 -> 缺页异常 -> 陷入VM

Hypervisor中的处理

  • 为MMIO区域注册一个MMIO处理函数
  • 处理函数定位到需要访问的I/O端口

DMA 模拟

  • guest 驱动程序配置DMA 相关寄存器, 源地址 目的地址 (GPA) 及 长度
  • 陷入VMM, 设备模型用VMM 提供的内存管理功能 将源地址目的地址 (GPA) 翻译为 HPA, 配置物理DMA 的地址寄存器为HPA, 同时需要建立HPA 与 HVA的映射关系, 对其进行占位, 防止别的进程或vcpu把这块物理内存给抢走. 这个地方纯软件实现比较复杂, 涉及到映射给 guest 的虚拟设备地址与真实设备地址之间的转换, 如果为memory->memory, 会简单一些
  • guest 客户机驱动程序通过配置虚拟DMA的 命令控制寄存器发起 DMA操作
  • 陷入VMM, 设备模型截获这个操作后, 配置物理DMA命令控制寄存器
  • DMA 自行在HPA 间搬运数据
  • DMA 搬运完毕后, 通过中断通知vmm 设备模型, vmm设备模型返回到guest os中, DMA 请求结束

硬件io虚拟化辅助-设备直通

软件实现I/O虚拟化的技术中,所有的虚拟机都共享物理平台上的硬件设备。如果物理条件好,有足够的硬件,就可以考虑让每个虚拟机独占一个物理设备,这样无疑会提高系统的性能。把某一个设备直接分配给一个虚拟机,让虚拟机可以直接访问该物理设备而不需要通过VMM或被VMM截获,这就是设备直通技术。

intel 的 VT-d与AMD的IOMMU技术 arm的smmu 技术。SMMU 与 IOMMU 提供了外设的中断重映射和DMA重映射功能, 使guest os使用该外设同host os 使用外设一样, 在使用过程中不需要陷入VMM.

中断重映射会将来自外部设备的中断拦截下来, 通过查询中断映射表找到真正的中断路由信息然后发送给真正的CPU。 guest 可以直接收到中断, 处理流程同物理主机处理中断的流程一样.

ARM 硬件虚拟化技术:

CPU 特权层扩展

  • EL2 层(arm64) / HYP (arm32) 模式下运行vmm
  • guest os 运行在原有的特权模式, 不需要修改guest os
  • vmm所在层权限更高, 可以控制guest os 访问硬件的权限

image-20240416111531638

模式切换

虚拟机 → Hypervisor

  • EL1 → EL2
  • 敏感指令触发(可通过HCR_EL2寄存器细粒度 控制)

Hypervisor → 虚拟机

  • EL2 → EL1
  • eret指令触发

上下文切换

  • EL1与EL2各自有一套系统寄存器
  • 虚拟CPU调度时,需要将原虚拟CPU系统寄 存器保存至内存并从内存中加载目标虚拟 CPU寄存器

因为有了硬件虚拟化的支持,所以hypervisor的实现 基本是基于硬件的 trap 和 软件的emulator 来实现的。guest os 访问一些特权寄存器或者指令,会进到 hypervisor ,然后会调用特权寄存器的访问函数来访问特权寄存器。如果是要访问硬盘,或者网络,会通过io 模拟器,来访问具体的模拟器。

image-20240416111535749

CPU的虚拟化,就是让多个Guest os 分时的运行在同一个CPU上,都有自己独立的物理地址空间,让 hypervisor在EL2 层来帮助多个VM 来进行上下文的切换,这个和linux 进程的概念非常的相似,不过保存的上下文寄存器不一样,这里有两个重要的寄存器,HCR_EL2ESR_EL2。HCR_EL2 是用来配置VM的参数,就是产生trap的条件,什么情况下会产生trap陷入到hypervisor ,右边是一个运行两个VM的例子。WFI指令是说明自己工作做完了,是idle状态了。

image-20240416111539904

ARM CPU虚拟化通过硬件trap和软件模拟完成

  1. HCR_EL2 hyper配置寄存器
    1. 配置vm产生硬件trap的条件, 如TLB/cache的操作, 一些特殊指令
  2. ESR_EL2 异常寄存器
    1. 当trap发生时, 确定vm产生硬件trap的原因

执行特权指令示例:

与特权级无关的一般的指令和通用寄存器在任何特权级都可以任意执行。而每个特权级都对应一些特殊指令和 控制状态寄存器 (CSR, Control and Status Register) ,来控制该特权级的某些行为并描述其状态。当然特权指令不只是具有有读写 CSR 的指令,还有其他功能的特权指令。

如果低优先级下的处理器执行了高优先级的指令,会产生非法指令错误的异常,于是位于高特权级的执行环境能够得知低优先级的软件出现了该错误, 进而陷入到高特权级处理该指令

image-20240416111543865

访问特定寄存器示例:

image-20240416111547192

使用陷入来虚拟化操作需要大量计算。比如功能寄存器ID_AA64MMFR0_EL1(用来报告处理器内存相关特性的,操作系统可能会读取该寄存器来决定在内核中开启或关闭某些特性),不经常被操作系统访问。当将对这些寄存器的访问捕获到虚拟机监控程序中以模拟读取时,计算是可以接受的。
但是对于访问频率高的寄存器,比如MPIDR_EL1,或者在性能关键代码中,需要尽可能地优化陷入,对这些寄存器,ARM提供了其它策略,hypervisor可以在进入VM时先配置好这些寄存器的值。例如,当VM中读到MPIDR_EL1(在多处理器系统中,为进程调度提供一个额外的PE(process element)识别机制)时会自动返回VMPIDR_EL2的值而不发生陷入

MMU虚拟化支持

  • LPAE(arm32 大地址拓展技术) , stage2 translation

img

中断虚拟化

Hypervisor对虚拟中断的处理比较复杂,Hypervisor本身需要机制来在EL2处理中断,还需要机制来将外设的中断信号发送到目标虚拟机VM(或vCPU)上,为了使能这些机制,ARM体系架构包含了对虚拟中断的支持(vIRQs,vFIQs,vSErrors);

处理器只有在EL0/EL1执行状态下,才能收到虚拟中断,在EL2/EL3状态下不能收到虚拟中断;

Hypervisor通过设置HCR_EL2寄存器来控制向EL0/EL1发送虚拟中断,比如为了使能vIRQ,需要设置HCR_EL2.IMO,设置后便会将物理中断发送至EL2,然后使能将虚拟中断发送至EL1;

有两种方式可以产生虚拟中断:

1)在处理器内部控制HCR_EL2寄存器产生虚拟中断, hypervisor还需要为VM模拟中断控制器的操作

2)通过GIC中断控制器(v2版本以上);

image-20221020105426023

如果一个PE上运行了多个guest os, 即一个PE上绑定了多个vcpu, 同时每个vcpu上跑的os是不同的.

发送虚拟中断则需要在安装中断时绑定vcpu 与 中断号.

虚拟CPU接口直接访问

  • 为虚拟CPU接口提供专用寄存器,区别于物理CPU接口
  • 运行在EL1中的Guest OS对CPU接口系统寄存器的访问可以被重定向到相应的寄存器而不会触发虚拟机陷入

arch_timer 虚拟化

  • hypervisor timer, virtual timer

无需陷入VMM, 防止引入不确定性的时延. 对于os 来说, timer tick 涉及到任务调度, 越精确越好.

smmu

  • stage2 translation for DMA

  • 一种DMA重映射机制

  • 扩大设备DMA寻址范围, 当系统无法提供大块连续物理内存时,也可以通过SMMU转换让设备可以访问分散物理内存

  • IOMMU在ARM-V8架构下的解决方案,与VT-d类似

  • SMMU与MMU共用一套阶段-2页 表

  • 设备直通

    • 虚拟机直接接管设备,虚机可以直接访问MMIO空间,VMM配置好SMMU之后,设备DMA读写请求也无需VMM介入
  • 为每个虚拟机划定可用的设备, 起到隔离保护作用

虚拟机网卡如何进行DMA?

image-20240416111555905

  • 网卡驱动将数据的guest 物理地址填入网卡DMA 寄存器
  • SMMU 硬件将发给DMA的guest 物理地址转换为真实设备物理地址

SMMU 为系统除CPU 之外的任何具有DMA 能力的设备提供地址翻译服务和保护功能

  • PCIE DMA 设备
  • platform DMA 设备
  • GPU/VE 加速器

image-20240416111559481

RISCV 虚拟化技术

已有的RISC-V虚拟化方案实现

目前已有的实现有Xvisor和KVM,Xvisor是1类虚拟化软件,而KVM属于2类。

RISC-V规范定义了RISC-V H-extension,在原来的3级特权架构的基础上,对原有的Supervisor模式进行了扩展,引入了Hypervisor-Extended Supervisor mode (HS)

image-20240416111603241

虚拟化H扩展定义了一个硬件状态位,称作V状态,可以为0或1,V状态不同,定义和访问的CSR寄存器也不同。

  • 当V为0时
    • 以“s”开头的CSR寄存器表示当前操作系统的状态
    • “h”开头的用于支持和实现虚拟化软件
    • “vs”开头的代表运行在虚拟化技术上的系统状态。
  • 当V为1时
    • “s”开头的寄存器指向了前文以“vs”开头的寄存器。

image-20240416111606294

image-20240416111610806

模式切换

  • 虚拟机 → Hypervisor
    • VS mode → HS mode(先进入M mode,再由M mode 转发给HS mode)
    • 敏感指令触发
  • Hypervisor → 虚拟机
    • HS mode → VS mode
    • sret指令触发

上下文切换

  • 为VS-mode提供VS CSR
  • 虚拟CPU调度时,同样需要从内存中保存和加载相应的寄存器

2级mmu 地址转换

使用stap 与hgatp 寄存器完成2级 地址转换, 原理一样
va->ipa (guest os) satp
ipa -> pa (host os) hgatp

中断

hedeleg 虚拟异常代理寄存器

hideleg 虚拟中断代理寄存器

默认状态下, 在各级代理寄存器未设置时, 所有的trap 和 中断都被指向到 M 模式的trap (即mtvec 指定的入口函数处), 在指定了 medelegmdieleg后, 相应bit位的trap 和 中断 指向到 HS 模式的trap (即stvec 指定的入口函数处), 进一步, 在指定了 hedeleghideleg 后, 相应bit位的trap 和 中断指向到 VS 模式下的trap(即vstvec 指定的入口函数处)

image-20240416111616014

hedeleg 中, 9-11 bit, 20-23 bit 是readonly的, 只能是0

第0, 3, 8, 12, 13, 15 为推荐设置bit

image-20240416111619570

hideleg 中, 0-15 中, 只有10, 6, 2 能被设置. 当hideleg中, bit 10被设置后, 10号中断来了后, 被代理到VS-mode后, code 10 会被自动转换为 code 9; 同样的 6号中断被自动转换为 5, 2号中断被自动转换为 1号. 这样做的目的是为guest os 中的 kernel 不用进行额外的修改来适配虚拟机.

除此之外, HS模式可以使用hvip寄存器,来向VS模式注入虚拟的中断。

timer

提供htimedelta htimedeltah 寄存器, 在VS VU 模式下访问timer 寄存器会返回真实的time与htimedelta的和. 通过hideleg 代理实现guest timer的中断, 不需要陷入VMM.

io模拟

为了虚拟数据吞吐,HS模式可以使用“陷入-模拟”法。即在访问内存映射外设对应的地址时,产生相应的中断,通过模拟外设的运行来实现后续的过程。这种方式可以模拟PLIC外设、VirtIO外设和其它一些软件模拟的吞吐外设。

iommu 同 ARM SMMU 技术一样提供了设备直通能力, 提供了DMA 重映射和中断重映射机制, 某个外设可以被guest 独占, guest os 访问外设的流程如host os 一样, 无需陷入VMM.

RISCV iommu 最近才有正式的文档发布, 距离开源实现还需要一些时间.

image-20240416111624137

​ no-iommu

image-20240416111627418

​ with iommu

ARM Vs RISCV 硬件虚拟化辅助

image-20240416111631093