2. 虚拟化基础
设备直通并不是孤立技术,它建立在虚拟化这座“地基”之上。要理解 IOMMU 为什么出现、VFIO 为什么这样设计,必须先看清虚拟机监视器(VMM,也称 Hypervisor)如何虚拟化 CPU、内存和 I/O 这三类核心资源。本节沿着“谁在虚拟化—虚拟化什么—如何演进”的脉络展开,为后续 IOMMU 与设备直通打下概念基础。
一、VMM 的两种类型:Type 1 与 Type 2
VMM 的核心职责是创建并管理虚拟机(VM),为每个 VM 提供一套看似独占的虚拟硬件。按运行位置可分为两类:
- Type 1(裸金属型):直接运行在物理硬件之上,如 Xen、VMware ESXi、KVM(严格说 KVM 是 Linux 内核模块,常与 QEMU 组合成 Type 1 形态)。性能高、延迟低,是数据中心与云平台的主流。
- Type 2(宿主型):运行在宿主操作系统之上,如 VirtualBox、VMware Workstation。部署方便,但多了一层 OS,I/O 路径更长。
无论哪种类型,VMM 都要解决同一个问题:让 Guest OS 以为自己独占 CPU、内存和外设。这三者的虚拟化难度依次递增,也决定了 I/O 虚拟化成为最复杂、演进最活跃的领域。
二、CPU 虚拟化:特权级与陷入-模拟
CPU 虚拟化的本质是处理“敏感指令”。Guest OS 执行特权指令时,不能真正操作硬件,必须被 VMM 截获。经典方案是陷入-模拟(Trap-and-Emulate):VMM 让 Guest 运行在较低特权级,敏感指令触发异常,VMM 捕获后模拟执行并返回结果。
x86 早期缺乏虚拟化支持,VMware 用二进制翻译动态改写敏感指令。直到 Intel VT-x / AMD-V 引入根模式与非根模式,CPU 虚拟化才真正硬件化:Guest 直接运行在非根模式,VM Exit 与 VM Entry 由硬件完成,开销大幅降低。这也是 KVM 高性能的根基。
三、内存虚拟化:从影子页表到 EPT/NPT
Guest OS 维护自己的页表,把 Guest 虚拟地址(GVA)映射到 Guest 物理地址(GPA);但 GPA 并非真实物理地址(HPA),还需第二层映射。传统做法是影子页表(Shadow Page Table):VMM 把 GVA→GPA 与 GPA→HPA 合并成一张 GVA→HPA 表,供 MMU 直接使用。缺点是每建一个 Guest 页表都要同步,维护成本高。
硬件辅助方案引入二级地址转换:Intel EPT(Extended Page Tables)与 AMD NPT(Nested Page Tables)。MMU 先查 Guest 页表得到 GPA,再查 EPT 得到 HPA,两次翻译由硬件完成,VMM 不再需要影子页表。这为设备直通中的 DMA 重映射提供了同源思路——IOMMU 正是 I/O 侧的“EPT”。
四、I/O 虚拟化:四种模型与演进脉络
I/O 虚拟化要解决设备如何被多个 VM 共享或独占。按性能与隔离性递增,主流模型如下:
| 模型 | 核心机制 | 性能 | 典型代表 |
|---|---|---|---|
| 全虚拟化 | VMM 截获 MMIO/PIO,纯软件模拟设备 | 低 | QEMU 模拟 e1000 |
| 半虚拟化 | Guest 装前端驱动,与后端协作 | 中 | VirtIO |
| 设备直通 | 设备直接分配给 VM,IOMMU 做地址隔离 | 高 | VFIO + VT-d |
| SR-IOV | 物理功能虚拟出多个虚拟功能,硬件级隔离 | 很高 | 网卡 PF/VF |
演进脉络可概括为:软件模拟 → 半虚拟化 → 硬件直通 → 硬件虚拟化(SR-IOV)。每一步都在减少 VMM 介入、缩短数据路径,同时把隔离责任逐步下沉到硬件。
五、案例场景:一块网卡如何被 VM 使用
假设一台服务器运行 KVM,需要给 VM 提供网络:
# 全虚拟化:QEMU 模拟网卡
qemu-system-x86_64 -netdev user,id=n0 -device e1000,netdev=n0
# 半虚拟化:VirtIO
qemu-system-x86_64 -netdev tap,id=n0 -device virtio-net-pci,netdev=n0
# 设备直通:VFIO 绑定物理网卡
qemu-system-x86_64 -device vfio-pci,host=0000:03:00.0
前两种方式中,每个数据包都要经过 VMM 或后端驱动,CPU 开销大、延迟高。直通方式下,VM 直接操作物理网卡寄存器,DMA 通过 IOMMU 完成 GPA→HPA 翻译,数据路径几乎与裸机一致。这正是 IOMMU 存在的直接价值。
六、常见误区与复盘
- 误区一:直通一定比 VirtIO 快。 小包、高连接数场景下,VirtIO 的批处理与 vhost 加速可能更优;直通胜在低延迟与高吞吐。
- 误区二:有了 EPT 就不需要 IOMMU。 EPT 只管 CPU 侧地址翻译,设备 DMA 不走 CPU 页表,必须由 IOMMU 单独保护。
- 误区三:SR-IOV 等于直通。 SR-IOV 是硬件把 PF 切分成多个 VF,仍需 IOMMU 做 VF 的地址隔离与中断重映射。