PCI 设备直通步骤
直通把物理 PCI 设备整组交给 guest 独占使用:先在宿主开启 IOMMU,确认设备所在的 IOMMU 组,用 vfio-pci 驱动接管该组设备,再把 hostdev 片段写进域定义并重启域。直通绕过了虚拟化层,性能接近原生,代价是设备不能在宿主与虚机之间共享,宿主启动也会占用该设备。
基本信息
| 查设备 | lspci -nn 拿到 BDF 编号(如 01:00.0)与厂商设备 ID |
|---|---|
| 确认分组 | virsh nodedev-dumpxml pci_0000_01_00_0 查看 iommuGroup |
| 接管驱动 | virsh nodedev-detach pci_0000_01_00_0 把设备从宿主驱动摘到 vfio-pci |
| 宿主影响 | detach 后宿主不可再使用该设备,直到 detach 状态被撤销 |
| 生效方式 | 写入域 XML 的 hostdev 后通常需要重启域 |
典型使用场景
- 网卡直通:给虚机独占物理网卡,追求高吞吐与低时延
- 存储控制器直通:需要 guest 直接访问物理 HBA 或 NVMe 设备
- 加速卡与采集卡:GPU、视频采集、专用加速卡交给虚机独占
- 硬件加密与专用外设:需要真实设备才能工作的业务系统
- 性能对比测试:验证虚拟化开销对业务的实际影响
宿主侧准备与域内配置
宿主侧准备与域内配置
lspci -nn | grep -i 'your device' # 找到设备 BDF
virsh nodedev-dumpxml pci_0000_01_00_0 # 查看 IOMMU 组内的其它设备
virsh nodedev-detach pci_0000_01_00_0 # 交给 vfio-pci 接管
# 确认 IOMMU 已启用:dmesg | grep -i iommu
# 域 XML 片段:
# <hostdev mode='subsystem' type='pci' managed='yes'>
# <source><address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/></source>
# </hostdev>步骤与校验
| 步骤 | 关键动作 | 校验方式 |
|---|---|---|
| 开启 IOMMU | 内核参数启用 IOMMU 并重启 | 查看内核日志中的 IOMMU 信息 |
| 确认分组 | 读取设备的 IOMMU 组归属 | 组内设备是否都空闲 |
| 接管驱动 | 把设备摘到 vfio-pci | 宿主侧不再占用该设备 |
| 写入定义 | 在域 XML 中加 hostdev | 启动域后在 guest 内 lspci 能看到 |
同一 IOMMU 组内的设备要一起直通;存储控制器等关键设备直通前,务必确认宿主自身不依赖它启动。
直通设备通常不支持虚机热迁移,集群里有直通虚机时,迁移能力和维护计划都要单独考虑。
设备被 vfio-pci 接管期间,宿主不再加载它原本的驱动;需要交还宿主时用 nodedev-reattach 恢复,改完记得核对宿主侧设备是否正常。