PCIe 设备直通

张开发
2026/4/20 22:03:27 15 分钟阅读

分享文章

PCIe 设备直通
PCIe 设备直通是一种虚拟化技术将物理 PCIe 设备GPU、网卡、NVMe、HBA 等直接独占分配给虚拟机绕过 Hypervisor 模拟层让 VM 以接近原生性能直接访问硬件。关键硬件依赖IOMMU输入输出内存管理单元IntelVT-dVirtualization Technology for Directed I/OAMDAMD-Vi / IOMMU作用地址重映射隔离 Guest/Host 物理地址、DMA 隔离、中断重映射防止设备越权访问内存。ACSAccess Control ServicesPCIe 规范用于拆分 IOMMU 分组避免同组设备必须一起直通。MSI-X 中断支持硬件中断重映射直通必备。BIOS/UEFI必须开启IOMMU、VT-d/AMD-Vi、Above 4G Decoding等。工作流程VFIO 模式Linux/KVM/QEMU硬件隔离Host 内核将设备从原生驱动解绑绑定到VFIOVirtual Function I/O驱动接管设备控制权。IOMMU 配置IOMMU 为 VM 创建独立地址空间将设备的 PCI 地址、BAR 空间、DMA 地址映射到 VM 的物理地址空间。中断直通MSI-X 中断经 IOMMU 重映射直接注入 VM减少 VM Exit。VM 直接访问VM 加载设备原生驱动读写 PCI 配置空间、BAR、DMA完全绕过 Hypervisor 模拟。VFIO的工作原理VFIO 是 Linux 内核提供的一套用户态驱动框架核心目标只有两个把物理 PCIe 设备安全地暴露给用户态程序QEMU、DPDK、SPDK 等。配合IOMMU实现硬件级隔离让用户态可以安全直接操作设备不会破坏系统。它替代了早年不安全的uio框架是PCIe 设备直通Passthrough的标准内核基础。VFIO 是一套配合 IOMMU 实现硬件级隔离的用户态设备驱动框架它把 PCIe 设备的寄存器、DMA、中断安全地暴露给 QEMU 等用户态程序让虚拟机可以直接控制物理设备实现近乎原生的性能。前置依赖没有 IOMMUVFIO 毫无意义VFIO 本身不负责隔离它只是把设备 “交出去”。真正的安全和地址翻译靠IOMMU。IOMMU 做两件关键事DMA 重映射设备想写内存 → 不是直接写物理地址而是 IOMMU 翻译后再写。中断重映射设备发中断 → IOMMU 重定向到指定 vCPU / 内核不允许乱发。没有 IOMMUVFIO 也能运行但完全不安全设备可以 DMA 任意内存瞬间搞崩内核。VFIO 整体架构用户态QEMU / 应用程序 ↑ ↓ (ioctl, mmap, read/write) VFIO 子系统 ↓ VFIO-PCI 驱动vfio-pci.ko ↓ PCI 核心子系统 ↓ IOMMU 驱动intel-iommu / amd-iommu ↓ 硬件PCIe 设备 IOMMU 控制器VFIO 对外暴露三类接口容器container对应一个 IOMMU 域domain组group对应硬件 IOMMU 分组最小隔离单元设备device具体 PCI 功能0000:01:00.0VFIO核心工作原理1. 设备绑定 vfio-pci所有权移交当你执行echo 0000:01:00.0 /sys/bus/pci/drivers/vfio-pci/bind内核做的事让原生驱动nvidia、igb、nvme 等解绑该设备。vfio-pci 接管设备禁用设备 DMA保存配置空间屏蔽原有中断把设备标记为被 VFIO 托管。从此内核不再碰这个设备。2. 创建 VFIO 容器 → 绑定 IOMMU 域用户态QEMU打开/dev/vfio/container后VFIO 创建一个IOMMU domain。所有加入这个容器的设备共享同一个 IOMMU 地址空间。相当于给虚拟机划了一个独立的硬件地址空间。3. 将 IOMMU 组加入容器关键隔离点IOMMU 分组是硬件决定的同组设备必须一起直通。VFIO 强制必须把整个组加入容器不允许只加组内一个设备这是为了防止设备通过 PCIe P2P 绕过 IOMMU 互相攻击。4. 用户态映射设备资源BAR 空间、配置空间PCIe 设备有BAR0~BAR5MMIO 寄存器空间ROM 空间PCI 配置空间DMA 能力中断INTx/MSI/MSI-XVFIO 允许用户态通过mmap映射 BAR 为可直接读写的虚拟地址ioctl读写 PCI 配置空间read/write访问 IO 端口如果有内核只做权限检查不参与数据路径。5. IOMMU 建立虚拟机物理地址 → 主机物理地址映射这是 VFIO 最核心的魔术。QEMU 管理着虚拟机的 GPAGuest Physical Address。当虚拟机给设备下达 DMA设备发出 GPA 地址到达 IOMMUIOMMU 根据 VFIO 配置的页表翻译成 HPAHost Physical Address最终访问真实内存整个过程内核不参与、零拷贝、无切换。6. 中断直通MSI/MSI-XVFIO 处理中断为设备分配中断向量通过 IOMMU 重映射中断直接注入虚拟机 vCPU完全绕过主机内核中断子系统延迟极低几乎和物理机一致。7. 设备完全由用户态驱动控制虚拟机内部装上真实驱动NVIDIA、ixgbe 等后写寄存器 → 直接写物理 BAR发 DMA → IOMMU 翻译收中断 → 直接注入 vCPUHost 内核完全看不见设备行为。VFIO 三个核心抽象概念1. IOMMU Group硬件分组最小隔离单位。同一组内设备可以互相 P2P DMA所以必须整体分配。2. VFIO Group软件封装对应一个 IOMMU Group是 VFIO 暴露给用户态的最小单元。3. VFIO ContainerIOMMU Domain一个容器 一个独立的 IOMMU 地址空间。一个 VM 通常一个容器。VFIO 数据通路VM 驱动 → GPA → IOMMU → HPA → 设备 DMA 设备中断 → IOMMU 重映射 → 直接注入 vCPU全程无虚拟机退出VM Exit无内核转发无 QEMU 模拟无拷贝这就是直通性能接近物理机的原因。VFIO 在内核里的结构vfio.c核心框架容器、组管理vfio_iommu_type1.cIOMMU 绑定、GPA→HPA 映射vfio_pci.cPCIe 设备专用逻辑配置空间模拟 / 透传MSI/MSI-X 管理BAR 映射vfio_group.cIOMMU group 安全检查LinuxKVM/QEMU配置步骤1. 启用 IOMMUGRUB# Intel CPU GRUB_CMDLINE_LINUXintel_iommuon iommupt pcie_acs_overridedownstream # AMD CPU GRUB_CMDLINE_LINUXamd_iommuon iommupt pcie_acs_overridedownstreamiommupt直通模式减少 Host 介入pcie_acs_override强制拆分 IOMMU 分组谨慎使用更新 GRUB 并重启update-grub # Debian/Ubuntu grub2-mkconfig -o /boot/grub2/grub.cfg # RHEL/CentOS2. 检查 IOMMU 分组关键同一 IOMMU 组内设备必须一起直通否则无法隔离。for d in /sys/kernel/iommu_groups/*/devices/*; do n${d#*/iommu_groups/*}; n${n%%/*} printf IOMMU Group %s: $n lspci -nns ${d##*/} done | sort -V3. 解绑原生驱动 绑定 VFIO# 1. 黑名单原生驱动如NVIDIA、igb、nvme echo blacklist nvidia /etc/modprobe.d/blacklist.conf # 2. 加载VFIO模块 modprobe vfio modprobe vfio-pci # 3. 解绑设备BDF格式0000:xx:xx.x echo 0000:01:00.0 /sys/bus/pci/devices/0000:01:00.0/driver/unbind # 4. 绑定到vfio-pcivendor:device echo 10de:1e04 /sys/bus/pci/drivers/vfio-pci/new_id4. QEMU 启动参数直通 GPU / 网卡qemu-system-x86_64 \ -enable-kvm \ -m 16G \ -smp 8 \ -device vfio-pci,host0000:01:00.0 \ # 直通PCIe设备 -drive filevm.img,ifvirtio \ -vga none # 禁用虚拟显卡GPU直通时优缺点✅ 优点极致性能性能损耗 5%接近物理机低延迟。完整功能支持设备所有原生特性CUDA、光追、RDMA 等。强隔离设备独占Host / 其他 VM 无法访问安全隔离。❌ 缺点资源独占一个设备只能给一个 VM无法共享。配置复杂依赖 IOMMU、分组、驱动绑定易踩坑。迁移受限VM 热迁移基本不可用设备绑定物理机。不支持热插拔VM 需关机才能释放设备。典型应用场景GPU 直通虚拟机玩 3A 游戏、AI 训练、专业图形渲染SolidWorks/Blender。高速网卡直通10G/25G/100G 网卡低延迟网络、RDMA、DPDK 场景。NVMe / 存储直通高性能存储、数据库、IO 密集型应用。专用硬件FPGA、加密卡、视频采集卡等特殊设备。SR-IOVSR-IOV Single Root I/O Virtualization单根 I/O 虚拟化是 PCI-SIG 定义的硬件级虚拟化扩展让单个物理 PCIe 设备在硬件层面虚拟出多个独立的虚拟设备供多个虚拟机同时共享使用且性能接近直通。SR-IOV 是硬件级的设备虚拟化技术通过在物理设备内部虚拟出多个轻量级 VF配合 IOMMU 与 VFIO实现多虚拟机安全共享硬件同时保持接近物理机的性能。核心概念一个支持 SR-IOV 的设备会分成两部分1. PFPhysical Function物理功能真正的物理设备拥有完整配置权限管理 VF、设置队列、复位、固件升级等由宿主机驱动管理例如 ixgbe、mlx5_core2. VFVirtual Function虚拟功能硬件虚拟出来的轻量级 PCIe 功能只有数据面能力无配置权限不能自己管理硬件只能收发包 / 做计算每个 VF 独立独立的中断、独立的队列、独立的 MAC 等可以直接通过 VFIO 直通给 VM一个 PF 可以虚拟出多个 VF网卡一般 64/128 个。硬件工作原理SR-IOV不是软件模拟是硬件原生支持的虚拟化。1. 硬件内部做 “流量分发”设备内部有硬件逻辑接收方向根据 MAC/VLAN/ 队列号 → 分发到对应 VF发送方向VF 发出的数据 → 硬件直接转发到物理端口全程不需要宿主机内核参与转发。2. 共享硬件资源但严格隔离共享PCIe 链路、物理端口、缓存、DMA 引擎隔离每个 VF 有独立的 DMA 上下文每个 VF 有独立的中断MSI-X硬件保证 VF 之间不能互相访问内存3. IOMMU SR-IOV 配合每个 VF 会被系统识别为独立的 PCIe 设备拥有独立的 BDF 号。IOMMU 为每个 VF 建立独立的地址映射实现硬件级隔离。整体架构宿主机内核 ↓ PF 驱动ixgbe/i40e/mlx5 等 ↓ 物理 NIC硬件 ├─ 管理逻辑负责创建/销毁 VF ├─ 交换逻辑硬件分发流量到 VF └─ 多个 VF硬件虚拟设备 ↓ 每个 VF → 被 IOMMU 隔离 → VFIO 直通 → 虚拟机数据流虚拟机发包VM 驱动 → 写 VF 的队列描述符设备硬件直接 DMA 读取数据硬件直接从物理口发出宿主机内核完全不参与虚拟机收包物理口收到包硬件根据流表匹配 → 送入对应 VF 队列硬件发 MSI-X 中断直接给 VMVM 直接 DMA 读取数据零宿主机介入、零拷贝、无 VM Exit性能几乎等同于 PCIe 直通远强于 virtio 模拟 / 内核桥转发。SR-IOV 与普通 PCIe 直通Passthrough区别PCIe 直通PassthroughSR-IOVVF 直通设备数量1 个物理设备 → 1 个 VM1 个 PF → 多个 VF → 多个 VM资源利用独占浪费严重共享高密度性能接近原生略低于直通但远高于模拟热迁移不支持部分厂商支持需配合硬件管理简单粗暴需要 PF 驱动管理 VF适用AI GPU、高性能独占设备网卡、存储 HBA、高密度场景硬件要求仅需 IOMMU设备必须支持 SR-IOV隔离最强硬件级隔离适用场景极致性能、专用设备高密度、多 VM 共享加速SR-IOV 与 VFIO 的关系SR-IOV 是硬件能力VFIO 是软件通道。典型使用流程硬件支持 SR-IOV宿主机加载 PF 驱动创建若干 VF系统识别出多个 VF 设备使用vfio-pci绑定 VFQEMU 使用vfio-pci将 VF 直通给 VM一句话SR-IOV 负责 “变出” 多个虚拟设备VFIO 负责安全地把它们交给虚拟机。GPU SR-IOVvGPU与网卡 SR-IOV网卡 SR-IOVI/O 通道型设备核心是数据包转发VF 是 “虚拟网口”只做收发。无状态 / 轻量VF 仅需独立队列、中断、DMA 上下文几乎无复杂状态。VF 数量多单 PF 可出64–128 个 VF如 ConnectX、Intel 800 系列。GPU SR-IOVvGPU计算 / 渲染型设备核心是并行计算 显存 图形管线VF 是 “虚拟 GPU 实例”。有状态 / 重资源VF 需独占显存切片、计算单元SM/CU、指令上下文、MMU 页表。VF 数量极少单 PF 通常仅1–8 个 VF如 NVIDIA A100 最多 7 个AMD MI 系列 4–8 个。VF 资源与能力维度网卡 VFGPU VFvGPU核心资源TX/RX 队列、MSI-X、DMA 上下文、独立 MAC/VLAN独占显存切片、独占 SM/CU 切片、独立 MMU、独立指令上下文、独立中断权限仅数据面收发包、配置自身队列 / 中断仅数据面执行 CUDA / 图形指令、访问自身显存不可改全局硬件配置隔离粒度队列级、流级隔离硬件上下文级 地址空间级强隔离VF 间无法互相访问显存 / 寄存器资源共享共享 PCIe 链路、物理端口、缓存、DMA 引擎共享 PCIe、显存控制器、全局缓存计算 / 显存严格切片独占VF 轻量化极轻仅几百 KB 硬件资源极重需完整 GPU 执行环境硬件开销大网卡 SR-IOV 数据路径纯硬件转发收包物理口 → 硬件流表MAC/VLAN/ 队列→ 直接送入对应 VF 队列 → 硬件发 MSI-X 中断给 VM → VM 直接 DMA 读包。发包VM 写 VF 队列 → 硬件直接 DMA 取数据 → 从物理口发出。全程宿主机内核 / Hypervisor 零参与无 VM Exit零拷贝。GPU SR-IOV 数据路径硬件上下文隔离 调度VM 提交任务VM 内驱动写 VF 寄存器 → 提交指令 / 显存访问请求。硬件隔离GPU 硬件识别 VF 上下文 → 仅允许访问该 VF 绑定的显存 / 计算单元。执行与中断硬件执行指令 → 完成后发 MSI-X 中断直接注入 VM。关键差异GPU 需硬件上下文切换保存 / 恢复 VF 状态网卡无此步骤。GPU 存在计算资源竞争即使切片仍共享指令发射 / 缓存网卡几乎无竞争。显存访问必须经IOMMU GPU MMU 双重翻译网卡仅 IOMMU 翻译。与 VFIO 配合方式两者都用 VFIO 做安全直通但绑定与使用不同网卡VF 绑定vfio-pci即可VM 用标准网卡 VF 驱动如ixgbevf、mlx5_vf。GPUVF 绑定vfio-pci但需厂商专用 vGPU 驱动NVIDIA vGPU Manager、AMD MxGPU。部分 GPU SR-IOV 需 Hypervisor 层配合管理如 NVIDIA vGPU 依赖主机 vGPU 软件栈并非纯硬件直通。网卡 SR-IOV 限制VF 功能受限不支持混杂模式、抓全量流量、部分高级卸载如 GRE 封装。热迁移困难VF 与物理端口强绑定动态迁移需特殊硬件 / 软件支持。单 PF VF 上限受队列 / 中断资源限制通常 64–128。GPU SR-IOV 限制硬件门槛极高仅专业卡支持NVIDIA A/H100、AMD MI 系列消费级 GPU 几乎不支持。VF 数量极少单 PF 最多 7–8 个远少于网卡。资源固定切片VF 显存 / 算力创建后不可动态调整弹性差。功能阉割VF 不支持完整 GPU 特性如部分 NVLink、高级图形渲染、硬件视频编解码全功能。热迁移几乎不支持GPU 状态复杂VF 迁移几乎不可行。厂商锁定依赖专用 vGPU 驱动与管理软件开源生态差。总结核心区别网卡 SR-IOV轻量通道型虚拟化VF 是虚拟网口多实例、纯硬件转发、无状态、高密度。GPU SR-IOVvGPU重资源计算型虚拟化VF 是完整虚拟 GPU 实例少实例、硬件上下文隔离、有状态、高性能但弹性差。

更多文章