大数跨境

硬件辅助虚拟化实战:基于 VFIO-PCI 与 QEMU 物理透传 8 卡 NVIDIA A800 指南

硬件辅助虚拟化实战:基于 VFIO-PCI 与 QEMU 物理透传 8 卡 NVIDIA A800 指南 AI和HPC
2026-09-29
3
导读:硬件辅助虚拟化(Hardware-Assisted Virtualization)允许虚拟机绕过宿

      硬件辅助虚拟化(Hardware-Assisted Virtualization)允许虚拟机绕过宿主机的软件模拟层,直接控制底层物理硬件,从而获得几乎等同于裸机的性能(Near-native performance)。

      在 Linux 生态中,vfio-pci扮演着核心角色。它是一个安全的内核驱动程序,利用 IOMMU(输入输出内存管理单元)保护机制,将物理 PCI 设备(如 GPU、NVMe 驱动器、网卡)从宿主机内核空间隔离,并直接透传给虚拟机或用户空间应用程序。
      本文将基于实验环境(宿主机已识别到 8 张 NVIDIA A800-SXM4-80GB),提供一套可以直接复制执行的 vfio-pci 绑定与 qemu-system-x86_64 启动脚本,实现 8 卡 GPU 的直通(Passthrough)。

步骤一:开启系统 IOMMU 支持

      要使用 vfio-pci,必须在宿主机的 BIOS/UEFI 中开启虚拟化支持(Intel VT-d 或 AMD-Vi),并在 Linux 内核参数中启用 IOMMU。
编辑 GRUB 配置文件(以 CentOS/RHEL/Ubuntu 为例):
vi /etc/default/grub
在 GRUB_CMDLINE_LINUX一行中追加 intel_iommu=on iommu=pt(如果是 AMD 平台则替换为 amd_iommu=on iommu=pt)。
更新 GRUB 并重启宿主机:
# Ubuntu / Debian update-grub # CentOS / RHEL (BIOS 模式) grub2-mkconfig -o /boot/grub2/grub.cfg # CentOS / RHEL (UEFI 模式) grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg  reboot
重启后,可通过
dmesg | grep -e DMAR -e IOMMU
确认 IOMMU 是否已成功激活。

步骤二:解绑 NVIDIA 驱动并绑定 VFIO-PCI

根据提供的 nvidia-smi 输出,8 张 A800 的 PCI 总线地址(Bus-Id)分别为 49:00.0, 54:00.0, 5E:00.0, 65:00.0, 89:00.0, B0:00.0, C4:00.0, D9:00.0。
在启动虚拟机前,我们需要将这些 GPU 从宿主机的 nvidia 驱动上剥离,并交由 vfio-pci 驱动接管。
你可以直接复制并运行以下 Shell 脚本:
#!/bin/bash# 加载 vfio-pci 内核模块modprobe vfio-pci# 定义你的 8 张 A800 对应的 PCI 地址 (注意 sysfs 中字母需要小写)GPUS=(    "0000:49:00.0"    "0000:54:00.0"    "0000:5e:00.0"    "0000:65:00.0"    "0000:89:00.0"    "0000:b0:00.0"    "0000:c4:00.0"    "0000:d9:00.0")for dev in "${GPUS[@]}"; do    echo "Processing GPU at $dev..."        # 1. 解绑当前驱动 (NVIDIA)    if [ -e /sys/bus/pci/devices/$dev/driver ]; then        echo $dev > /sys/bus/pci/devices/$dev/driver/unbind    fi        # 2. 获取厂商和设备 ID (Vendor & Device ID)    vendor=$(cat /sys/bus/pci/devices/$dev/vendor)    device=$(cat /sys/bus/pci/devices/$dev/device)        # 3. 绑定至 vfio-pci    echo "$vendor $device" > /sys/bus/pci/drivers/vfio-pci/new_id        echo "GPU $dev successfully bound to vfio-pci."done# 验证绑定结果lspci -nnk -s 0000:49:00.0 | grep "Kernel driver in use"

验证绑定结果

lspci -nnk -s 0000:49:00.0 | grep "Kernel driver in use"
执行完毕后,这些 A800 将在宿主机上“隐身”(nvidia-smi 将无法再看到它们),进入待命状态,准备分配给虚拟机。

步骤三:使用 QEMU 启动 8 卡透传虚拟机

接下来,使用 qemu-system-x86_64 命令拉起虚拟机。通过 -device vfio-pci,host=... 参数,我们可以将刚刚隔离出来的 8 张 GPU 1:1 映射给 Guest 操作系统。
直接复制执行以下启动命令(请根据实际情况修改镜像路径-drive file=...):
qemu-system-x86_64 \  -enable-kvm \  -m 256G \  -smp cores=32,threads=2,sockets=1 \  -cpu host,kvm=off \  -nodefaults \  -vga none -nographic \  -serial stdio \  -drive file=/path/to/your/ubuntu_guest.qcow2,format=qcow2,if=virtio \  -netdev user,id=net0,hostfwd=tcp::2222-:22 \  -device virtio-net-pci,netdev=net0 \  -device vfio-pci,host=0000:49:00.0,multifunction=on \  -device vfio-pci,host=0000:54:00.0 \  -device vfio-pci,host=0000:5e:00.0 \  -device vfio-pci,host=0000:65:00.0 \  -device vfio-pci,host=0000:89:00.0 \  -device vfio-pci,host=0000:b0:00.0 \  -device vfio-pci,host=0000:c4:00.0 \  -device vfio-pci,host=0000:d9:00.0
命令关键参数解析:
-enable-kvm:激活 KVM 硬件加速,这是实现接近裸机性能的基础。
-cpu host,kvm=off:将宿主机 CPU 特性完全暴露给虚拟机,并隐藏虚拟化特征(kvm=off 通常有助于绕过某些显卡驱动在虚拟机环境下的安全限制,如 Error 43)。
-netdev user...,hostfwd=tcp::2222-:22:设置了端口转发,虚拟机启动后,你可以从宿主机通过 ssh -p 2222 user@localhost 登录到虚拟机。
-device vfio-pci,host=xxxx:核心透传参数,将宿主机的 PCI 地址直接映射到虚拟机的 PCI 总线上。
进入虚拟机后,只需像配置普通物理机一样安装 NVIDIA 驱动和 CUDA Toolkit,运行 nvidia-smi 即可看到 8 张火力全开的 A800-SXM4。

【声明】内容源于网络
0
0
AI和HPC
聚焦 AI HPC 前沿,为科研人员、工程师、技术爱好者深度剖析领域核心知识与实战技术。从算法优化到硬件架构,精准推送一手资讯,助您紧跟行业脉搏,解锁高效创新密码。
内容 9
粉丝 0
AI和HPC 聚焦 AI HPC 前沿,为科研人员、工程师、技术爱好者深度剖析领域核心知识与实战技术。从算法优化到硬件架构,精准推送一手资讯,助您紧跟行业脉搏,解锁高效创新密码。
总阅读98
粉丝0
内容9