3. 设备直通概述
设备直通(Device Passthrough)是指把宿主机上一块真实的物理设备,例如网卡、GPU、NVMe SSD 或 FPGA 加速卡,直接分配给某个虚拟机独占使用,使虚拟机内的驱动能够像访问本地硬件一样访问它。与虚拟磁盘、虚拟网卡这类由 VMM 模拟出来的设备不同,直通设备在虚拟机看来就是一块真实的 PCIe 设备,拥有自己的配置空间、BAR 空间、中断和 DMA 能力。
理解设备直通的关键在于 DMA 与中断。设备发起 DMA 时使用的是物理地址,如果虚拟机直接操作设备,就必须保证设备只能访问该虚拟机被授权的内存区域,这正是 IOMMU 存在的意义。IOMMU 通过 DMA 重映射把设备发出的地址翻译并限制在指定域内,同时配合中断重映射把设备中断安全地投递到目标虚拟机。因此,设备直通可以概括为:把物理设备的所有权交给虚拟机,由 IOMMU 负责地址翻译与隔离,由 VFIO 负责设备的安全暴露与生命周期管理。
全虚拟化与半虚拟化对比
在设备虚拟化层面,常见路线有全虚拟化、半虚拟化和直通三类。全虚拟化由 VMM 完全模拟设备寄存器行为,客户机无需修改驱动,但每次寄存器访问都会触发陷入与模拟,性能开销大;半虚拟化则要求客户机安装特定前端驱动,通过共享内存与后端驱动通信,减少陷入次数,典型代表是 virtio;直通则把真实设备交给虚拟机,性能接近原生,但牺牲了设备的共享性与可迁移性。
| 对比维度 | 全虚拟化 | 半虚拟化(virtio) | 设备直通(VFIO) |
|---|---|---|---|
| 客户机驱动 | 原生驱动即可 | 需安装前端驱动 | 使用设备原生驱动 |
| 性能 | 较低,陷入频繁 | 较高,批量提交 | 接近原生 |
| 设备共享 | 可多虚拟机共享 | 可多虚拟机共享 | 通常单虚拟机独占 |
| 依赖硬件 | 无特殊要求 | 无特殊要求 | 需 IOMMU/VT-d 或 SMMU |
| 典型场景 | 兼容性优先 | 通用 I/O 虚拟化 | 高性能网卡、GPU、NVMe |
VFIO 与 VFIO-pci
VFIO(Virtual Function I/O)是 Linux 内核提供的用户态设备访问框架,它把设备的安全暴露抽象为容器(container)、IOMMU 组(group)和设备(device)三层结构。容器代表一个 IOMMU 地址空间,组是 IOMMU 隔离的最小单位,设备则挂载在组内。只有当一个组内的所有设备都被绑定到 VFIO 时,该组才能被安全地交给虚拟机,否则会出现 DMA 隔离漏洞。
VFIO-pci 是 VFIO 框架下针对 PCI 设备的驱动实现。它并不真正驱动硬件,而是接管设备的配置空间、BAR 映射和中断,把设备以文件描述符的形式暴露给用户态,由 QEMU 等 VMM 通过 ioctl 完成访问。使用前通常需要开启内核参数并绑定设备:
# 开启 IOMMU
# Intel: intel_iommu=on iommu=pt
# AMD: amd_iommu=on iommu=pt
# 查看设备所属 IOMMU 组
for d in /sys/kernel/iommu_groups/*/devices/*; do
echo "Group $(basename $(dirname $(dirname $d))): $(basename $d)"
done
# 将设备绑定到 vfio-pci
echo 0000:01:00.0 > /sys/bus/pci/devices/0000:01:00.0/driver/unbind
echo vfio-pci > /sys/bus/pci/devices/0000:01:00.0/driver_override
echo 0000:01:00.0 > /sys/bus/pci/drivers/vfio-pci/bind
在 QEMU 命令行中,直通设备通过 -device vfio-pci 挂载,并可用 host= 指定 BDF、用 rombar=0 控制 ROM 映射。若设备支持 SR-IOV,还可以把虚拟功能(VF)单独直通给不同虚拟机,从而在保持隔离的同时实现一定程度的共享。
PCIe 设备直通典型场景
直通最典型的场景是高性能网络。把物理网卡直通给虚拟机后,虚拟机内的 DPDK 或内核协议栈可以直接操作网卡队列,绕过虚拟交换层,获得接近裸机的包处理能力,常用于 NFV、防火墙和负载均衡。第二个场景是 GPU 直通,用于 AI 推理、图形工作站和云游戏,虚拟机独占 GPU 显存与计算单元,避免虚拟 GPU 的兼容性与性能损耗。第三个场景是 NVMe SSD 直通,为数据库或高性能存储节点提供低延迟、高 IOPS 的本地盘访问。此外,FPGA 加速卡、采集卡和专用加密卡也常通过直通方式交付给租户。
实践提示:直通前先用 lspci -nnk 确认设备驱动与 IOMMU 组,用 dmesg | grep -i iommu 确认 IOMMU 已启用。若设备与宿主机关键设备同组,可考虑开启 ACS 重定向或调整 PCIe 插槽位置。
常见误区与复盘
- 误区一:只要绑定 vfio-pci 就能直通。实际上 IOMMU 未开启、设备与宿主机驱动冲突、组内存在其他设备,都会导致直通失败或隔离失效。
- 误区二:直通设备可以随意热插拔。多数平台对直通设备的热拔支持有限,强行操作可能造成虚拟机崩溃或宿主机 IOMMU 域异常。
- 误区三:直通一定比 virtio 快。对于小包、低频或共享型负载,virtio 的批量与共享优势可能更合适,直通更适合高吞吐、低延迟、独占型负载。
- 误区四:忽略中断亲和与 NUMA。设备所在 NUMA 节点与 vCPU 不匹配时,跨节点 DMA 与中断会显著拉高延迟。
排障顺序建议:先确认 IOMMU 已启用并识别到设备,再确认设备已绑定 vfio-pci 且组内无其他设备,然后检查 QEMU 命令行与虚拟机 XML 中的 host 地址是否正确,最后观察 dmesg 与虚拟机内 lspci 是否识别到设备。多数直通失败都集中在 IOMMU 未开启、组隔离不完整和驱动抢占这三类原因上。
综上,设备直通是虚拟化中性能与隔离之间的一种权衡方案。它以 IOMMU 为安全底座,以 VFIO 为暴露框架,以 VFIO-pci 为 PCI 设备的具体实现,把物理设备的所有权安全地转移给虚拟机。理解容器、组、设备三层结构,理解 DMA 重映射与中断重映射的作用,是后续配置直通、排查故障和评估性能的前提。