============== 虚拟化 ============== .. meta:: :description: 介绍了虚拟化的基本概念,包括模拟(emulation)、经典虚拟化、软件虚拟化、MMU 虚拟化、影子页表、延迟影子同步、I/O 仿真、部分虚拟化以及 Intel VT-x 等内容,给出了相关的原理和实现细节。这对于理解操作系统中虚拟化技术的基础知识很有帮助。 :keywords: 虚拟化, 模拟, 经典虚拟化, 软件虚拟化, MMU 虚拟化, 影子页表, 延迟影子同步, I/O 仿真, 部分虚拟化, Intel VT-x `查看幻灯片 `_ .. slideconf:: :autoslides: False :theme: single-level 课程目标: =================== .. slide:: 虚拟化 :inline-contents: True :level: 2 * 模拟基础知识 * 虚拟化基础知识 * 半虚拟化基础知识 * 对虚拟化的硬件支持 * Xen 虚拟机监视器(hypervisor)概述 * KVM 虚拟机监视器概述 模拟(emulation)基础知识 ================ .. slide:: 模拟基础知识 :inline-contents: True :level: 2 * 指令被模拟(每次执行时都会模拟) * 其他系统组件也被模拟: * MMU * 物理内存访问 * 外围设备 * 目标架构——被模拟的架构 * 主机架构——模拟器运行所基于的架构 * 如果是模拟,目标架构和主机架构可以不同 虚拟化(virtualization)基础知识 ===================== .. slide:: 虚拟化基础知识 :inline-contents: True :level: 2 * 由 Popek 和 Goldberg 在 1974 年的一篇论文中定义 * 保真度 * 性能 * 安全性 .. ditaa:: +----+ +----+ +----+ | VM | | VM | ... | VM | +----+ +----+ +----+ +-------------------------+ | Virtual Machine Monitor | +-------------------------+ +-------------------------+ | Hardware | +-------------------------+ 经典虚拟化 ====================== .. slide:: 经典虚拟化 :inline-contents: True :level: 2 * 捕获(trap)和模拟 * 主机和目标使用相同的架构 * 大多数目标指令可以直接执行 * 目标操作系统在主机上以非特权模式运行 * 特权指令被捕获和模拟执行 * 有两种机器状态:主机和客户机 软件虚拟化 ======================= .. slide:: 软件虚拟化 :inline-contents: True :level: 2 * 并非所有架构都可以被虚拟化;例如 x86 架构: * CS 寄存器编码当前特权级(CPL) * 一些指令不会引发捕获(例如 popf 指令) * 解决方案:使用二进制翻译来模拟指令 MMU 虚拟化 ================== .. slide:: MMU 虚拟化 :inline-contents: True :level: 2 * “虚假”的虚拟机物理地址由主机转换为实际的物理地址 * 客户机虚拟地址 -> 客户机物理地址 -> 主机物理地址 * 主机硬件不直接使用客户机页表 * 虚拟机页表经过验证后,在主机上被翻译成一组新的页表(影子页表) 影子页表 ------------------ .. slide:: 影子页表 :inline-contents: True :level: 2 |_| .. ditaa:: PGD PMD PT +----------+ +----------+ +----------+ | | | | | | Guest Physical Page +----------+ +----------+ +----------+ +----------+ | | | | | |----+ | | +-----+ +----------+ +----------+ +----------+ | | | | CR3 | | |----+ | |---+ | | | | | +-----+ +----------+ | +----------+ | +----------+ +--->+----------+ | | | | | | | | | +---------> +----------+ +------>+----------+ +---->+----------+ Write Protected Write Protected Write Protected | | Guest (VM) | | trap access | ---------------------+------------------------------------------------------------------------------ | | check access, transform GPP to HPP | v Shadow PGD Shadow PMD Shadow PT +----------+ +----------+ +----------+ | | | | | | Host Physical Page +----------+ +----------+ +----------+ +----------+ | | | | | |----+ | | +----------+ +----------+ +----------+ | | | | |----+ | |---+ | | | | | +----------+ | +----------+ | +----------+ +--->+----------+ | | | | | | | | +----------+ +------>+----------+ +---->+----------+ 延迟影子同步 ---------------- .. slide:: 延迟影子同步 :inline-contents: True :level: 2 * 客户机页表的更改通常通过批处理进行 * 为了避免重复的捕获、检查和转换,将具有写访问权限的客户机页表条目进行映射 * 在以下情况下更新影子页表: * 刷新 TLB * 在主机页面故障(page fault)处理程序中 I/O 仿真(emulation) ============= .. slide:: I/O 仿真 :inline-contents: True :level: 2 |_| .. ditaa:: +---------------------+ | Guest OS | | +---------------+ | | | Guest Driver | | | +---------------+ | | | ^ | | | | | +----+-----------+----+ | trap | | access | +---+-----------+----+ | | VMM | | | v | | | +----------------+ | | | Virtual Device | | | +----------------+ | | | ^ | | | | | +--+------------+----+ | | v | +-----------------+ | Physical Device | +-----------------+ .. slide:: 示例:qemu SiFive UART 仿真 :inline-contents: True :level: 2 .. literalinclude:: ../res/sifive_uart.c :language: c 部分虚拟化 ================== .. slide:: 部分虚拟化 :inline-contents: True :level: 2 * 修改客户机操作系统以与虚拟机监视器(VMM)合作 * CPU 部分虚拟化 * MMU 部分虚拟化 * I/O 部分虚拟化 * VMM 提供超级调用(hypercalls)用于: * 激活/停用中断 * 更改页表 * 访问虚拟化外设 * VMM 使用事件触发虚拟机中的中断 Intel VT-x ========== .. slide:: Intel VT-x :inline-contents: True :level: 2 * 硬件扩展,将 x86 架构转换为可以进行经典虚拟化的状态 * 新的执行模式:非根模式(non-root mode) * 每个非根模式实例使用虚拟机控制结构(VMCS)来存储其状态 * VMM 在根模式(root mode)下运行 * 通过 VM-entry 和 VM-exit 在两种模式之间进行切换 虚拟机控制结构 --------------------------------- .. slide:: 虚拟机控制结构 :inline-contents: True :level: 2 * 客户机信息:虚拟 CPU 的状态 * 主机信息:物理 CPU 的状态 * 保存的信息: * 可见状态:段寄存器、CR3、IDTR 等 * 内部状态 * 不能直接访问 VMCS,但可以使用特殊指令访问某些信息 虚拟机进入和退出 --------------- .. slide:: 虚拟机进入和退出 :inline-contents: True :level: 2 * 虚拟机进入——使用新指令将 CPU 切换到非根模式,并从 VMCS 加载虚拟机状态;主机状态保存在 VMCS 中 * 允许在客户机中注入中断和异常 * 根据 VMCS 的配置,虚拟机退出将自动触发 * 当虚拟机退出时,主机状态从 VMCS 加载,客户机状态保存在 VMCS 中 虚拟机执行控制字段 --------------------------- .. slide:: 虚拟机执行控制字段 :inline-contents: True :level: 2 * 选择触发虚拟机退出的条件;示例: * 如果生成外部中断 * 如果生成外部中断并且 EFLAGS.IF 被设置 * 如果修改了 CR0-CR4 寄存器 * 异常位图——选择生成虚拟机退出的异常 * IO 位图——选择生成虚拟机退出的 I/O 地址(IN/OUT 访问) * MSR 位图——选择生成虚拟机退出的 RDMSR 或 WRMSR 指令 扩展页表 ================== .. slide:: 扩展页表 :inline-contents: True :level: 2 * 减少 MMU 虚拟化的复杂性,提高性能 * 不再需要通过虚拟机退出来访问 CR3、INVLPG 和页面故障 * EPT 页表由 VMM 控制 .. ditaa:: +-----+ +-----+ | CR3 | | EPT | +-----+ +-----+ | +------------------+ | +----------------+ | | | | | | +--------> | Guest Page Table | +-------> | EPT Page Table | ---------------> | | | | ------------> +------------------+ ------------> +----------------+ Guest Virtual Guest Physical Host Physical Address Address Address VPID ---- .. slide:: VPID :inline-contents: True :level: 2 * 虚拟机进入和退出会强制 TLB 刷新——丢失 VMM / VM 的转换信息 * 为了避免这个问题,每个虚拟机(VPID 0 保留给 VMM)关联一个 VPID(虚拟处理器 ID)标签 * 所有 TLB 条目都被标记 * 在虚拟机进入和退出时,只刷新与标签相关的条目 * 在搜索 TLB 时,只使用当前的 VPID I/O 虚拟化 ================== * 以受控的方式从虚拟机直接访问硬件 * 将主机的 MMIO 直接映射到客户机 * 转发中断 .. slide:: I/O 虚拟化 :inline-contents: True :level: 2 .. ditaa:: +---------------------+ +---------------------+ | Guest OS | | Guest OS | | +---------------+ | | +---------------+ | | | Guest Driver | | | | Guest Driver | | | +---------------+ | | +---------------+ | | | ^ | | | ^ | | | | | | | | | +----+-----------+----+ +----+-----------+----+ | traped | | mapped | | access | | access | +---+-----------+----+ +---+-----------+-----+ But how do we deal with DMA? | | VMM | | | | VMM | | | v | | | | | | | +----------------+ | | | +---------+ | | | Virtual Device | | | | | IRQ | | | +----------------+ | | | | Mapping | | | | ^ | | | +---------+ | | | | | | | | | +--+------------+----+ +---+-----------+-----+ | | | | v | v | +-----------------+ +-----------------+ | Physical Device | | Physical Device | +-----------------+ +-----------------+ 相比于模拟设备时的陷阱 MMIO,我们可以通过映射到客户机的页表,允许客户机直接访问 MMIO。 设备产生的中断由主机内核处理,并向 VMM 发送信号,VMM 将中断注入到客户机中,就像对于模拟设备一样。 .. slide:: I/O MMU :inline-contents: True :level: 2 VT-d 使用 I/O MMU(DMA 重映射)来保护和转换虚拟机物理地址。 .. ditaa:: +------+ +------+ | | | | | CPU | | DMA | | | | | +------+ +------+ | | v +-----+ +-----+ | CR3 | | EPT | +-----+ +-----+ | +------------------+ | +----------------+ | | | | | | +--------> | Guest Page Table | +-------> | EPT Page Table | ---------------> | | | | ------------> +------------------+ ------------> +----------------+ Guest Virtual Guest Physical Host Physical Address Address Address .. slide:: 中断投递 :inline-contents: True :level: 2 * 消息传递中断(MSI)= DMA 写入 IRQ 控制器的主机地址范围(例如 0xFEExxxxx) * 地址的低位和数据指示要发送到哪个 CPU 的哪个中断向量 * 中断重映射表指向应该接收中断的虚拟 CPU(VMCS) * I/O MMU 将捕获 IRQ 控制器的写入并在中断重映射表中查找 * 如果该虚拟 CPU 当前正在运行,则直接接收中断 * 否则,在一个表中设置一个位(发布的中断描述符表),下次运行该 vCPU 时将注入中断 .. slide:: I/O 虚拟机 :inline-contents: True :level: 2 .. ditaa:: +---------------------+ +---------------------+ +---------------------+ | Guest OS | | Guest OS | | Guest OS | | +---------------+ | | +---------------+ | | +---------------+ | | | Guest Driver | | | | Guest Driver | | | | Guest Driver | | | +---------------+ | | +---------------+ | | +---------------+ | | | ^ | | | ^ | | | ^ | | | | | | | | | | | | | +----+-----------+----+ +----+-----------+----+ +----+-----------+----+ | traped | | mapped | | mapped | interrupt | access | | access | | access | posting +---+-----------+----+ +---+-----------+-----+ +---+-----------+-----+ | | VMM | | | | VMM | | | | VMM | | | v | | | | | | | | | | | +----------------+ | | | +---------+ | | | | | | | Virtual Device | | | | | IRQ | | | | | | | +----------------+ | | | | Mapping | | | | | | | | ^ | | | +---------+ | | | | | | | | | | | | | | | | | +--+------------+----+ +---+-----------+-----+ +---+-----------+-----+ | | | | | | v | v | v | +-----------------+ +-----------------+ +-----------------+ | Physical Device | | Physical Device | | Physical Device | +-----------------+ +-----------------+ +-----------------+ .. slide:: SR-IOV :inline-contents: True :level: 2 * 单根——输入输出虚拟化 * 具有多个以太网端口的物理设备将显示为 PCI 总线上的多个设备 * 物理功能用于控制且能配置 * 呈现自身为新的 PCI 设备 * 使用哪个 VLAN * 新的虚拟功能在总线上枚举,并可以分配给特定的客户机 qemu ==== .. slide:: qemu :inline-contents: True :level: 2 * 通过 Tiny Code Generator(TCG)使用二进制翻译进行高效的模拟 * 支持不同的目标和主机体系结构(例如,在 x86 上运行 ARM 虚拟机) * 进程级和完全系统级的仿真 * MMU 仿真 * I/O 仿真 * 可与 KVM 一起用于加速虚拟化 KVM === .. slide:: KVM :inline-contents: True :level: 2 .. ditaa:: VM1 (qemu) VM2 (qemu) +---------------------+ +---------------------+ | +------+ +------+ | | +------+ +------+ | | | App1 | | App2 | | | | App1 | | App2 | | | +------+ +------+ | | +------+ +------+ | | +-----------------+ | | +-----------------+ | | | Guest Kernel | | | | Guest Kernel | | | +-----------------+ | | +-----------------+ | +---------------------+ +---------------------+ +----------------------------------------------------+ | +-----+ | | | KVM | Host Linux Kernel | | +-----+ | +----------------------------------------------------+ +----------------------------------------------------+ | Hardware with virtualization support | +----------------------------------------------------+ .. slide:: KVM :inline-contents: True :level: 2 * 用于硬件虚拟化的 Linux 设备驱动程序(例如 Intel VT-x、SVM) * 基于 IOCTL 的接口,用于管理和运行虚拟 CPU * VMM 组件在 Linux 内核中实现(例如中断控制器、定时器) * 如果存在,使用影子页表或 EPT * 使用 qemu 或 virtio 进行 I/O 虚拟化 类型 1 和类型 2 的 Hypervisor ============================ .. slide:: Xen :inline-contents: True :level: 2 * 类型1 = 裸机 Hypervisor * 类型2 = 嵌入在现有内核/操作系统中的 Hypervisor Xen === .. slide:: Xen :inline-contents: True :level: 2 .. image:: ../res/xen-overview.png