技术文章

PVE 8.3 直通 Tesla P40 给 Ubuntu 22.04 详细教程(含 BAR0 is 0M 根治方案)
技术文章 2026-08-28 6 阅读

PVE 8.3 直通 Tesla P40 给 Ubuntu 22.04 详细教程(含 BAR0 is 0M 根治方案)

小泥巴科技 本站 2026-08-28

1. 适用范围与环境确认

本教程针对如下环境编写(不同版本参数可能略有差异,请注意核对):


项目
宿主机Proxmox VE 8.3.0(内核 6.8.4-2-pve,QEMU 9.0.2)
CPU 平台Intel(需 VT-d;AMD 平台请将参数中的 intel_iommu 改为 amd_iommu
GPUNVIDIA Tesla P40(GP102,24GB,PCI ID 10de:1b38,Pascal 架构,Compute Capability 6.1)
虚拟机machine=q35,bios=ovmf(UEFI),内存 64GB
客户机Ubuntu 22.04.5 LTS,内核 5.15.0-generic
驱动nvidia-driver-580-server(580.173.02,DKMS)
CUDACUDA Toolkit 12.6(不可用 CUDA 13,见 §7)


关键前提:直通设备必须在独立的 IOMMU 组中(组内只有该 GPU 及其功能设备),否则无法直通或需要额外拆分策略。

2. 宿主机准备(PVE 侧)

2.1 BIOS 开启虚拟化与 IOMMU

进主板 BIOS,开启:

  • Intel Virtualization Technology (VT-x)

  • Intel VT-d (Directed I/O) / AMD IOMMU

  • 部分主板还有 "Above 4G Decoding"(影响大显存 BAR,建议开启)

2.2 内核参数启用 IOMMU

# GRUB 方式
nano /etc/default/grub
# 修改:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"

update-grub
# systemd-boot 用户则编辑 /etc/kernel/cmdline 后执行 proxmox-boot-tool refresh
reboot

重启后确认 IOMMU 已启用:

dmesg | grep -e DMAR -e IOMMU
# 期望看到:DMAR: IOMMU enabled

2.3 确认设备 BDF 与 IOMMU 组

lspci | grep -i nvidia
# 示例输出:82:00.0 3D controller: NVIDIA Corporation GP102GL [Tesla P40] [10de:1b38]

检查该设备是否独占 IOMMU 组(PVE 官方脚本):

#!/bin/bash
for d in /sys/kernel/iommu_groups/*/devices/*; do
  n=${d#*/iommu_groups/*}; n=${n%%/*}
  printf 'IOMMU Group %s  ' "$n"
  lspci -nns "${d##*/}"
done

理想结果:P40 所在组内只有 GPU 自己(有时还带 Audio Controller,需要一并直通)。

2.4 绑定 vfio-pci 并屏蔽 nouveau

# 将 GPU 绑定到 vfio-pci
echo "options vfio-pci ids=10de:1b38" > /etc/modprobe.d/vfio.conf

# 屏蔽 nouveau(若存在)
echo "blacklist nouveau" > /etc/modprobe.d/blacklist-nouveau.conf
echo "options nouveau modeset=0" >> /etc/modprobe.d/blacklist-nouveau.conf

# 保证 vfio-pci 优先加载
echo "softdep nvidia pre: vfio-pci" > /etc/modprobe.d/nvidia.conf  # 宿主机有 N 卡驱动时

update-initramfs -u
reboot

重启后确认 P40 已被 vfio-pci 接管:

lspci -k -s 82:00
# Kernel driver in use: vfio-pci
lsmod | grep -E 'vfio'
# 应看到 vfio_pci / vfio_iommu_type1

3. 创建并配置虚拟机

3.1 基础 VM 创建建议

# 以创建 VM120 为例
qm create 120 --name ubuntu22-p40 --memory 65536 --cores 16 --sockets 1 
  --net0 virtio,bridge=vmbr0 
  --scsi0 local-lvm:vmdisk,size=500G 
  --ide2 local-lvm:cloudinit,media=cdrom 
  --boot c --ostype l26 
  --machine q35 --bios ovmf --efidisk0 local-lvm:1,efitype=4m,pre-enrolled-keys=0


要点:

  • machine=q35bios=ovmf:P40 大 BAR 直通需要 UEFI;

  • 在BIOS里关闭安全启动(不然后安装驱动时会提示输入密码)

  • pre-enrolled-keys=0:避免 Secure Boot 干扰第三方驱动(NVIDIA DKMS);

  • 内存按需(本例 64GB)。内存越大,64 位 PCI 地址窗口越紧张,越需要 §5 的修复参数。



*** 以下是一个真实配置 ***

args: -global q35-pcihost.pci-hole64-size=96G -fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=65536
bios: ovmf
boot: order=scsi0;ide2;net0
cores: 10
cpu: x86-64-v2-AES
efidisk0: GreatWall:vm-120-disk-0,efitype=4m,pre-enrolled-keys=1,size=4M
hostpci0: 0000:82:00,pcie=1
ide2: local:iso/ubuntu-22.04.5-live-server-amd64.iso,media=cdrom,size=2086842K
machine: q35
memory: 65536
meta: creation-qemu=9.0.2,ctime=1787823223
name: ubuntu22-p40
net0: virtio=BC:24:11:67:54:94,bridge=vmbr0,firewall=1
numa: 1
onboot: 1
ostype: l26
scsi0: GreatWall:vm-120-disk-1,iothread=1,size=500G,ssd=1
scsihw: virtio-scsi-single
smbios1: uuid=d8a818f2-41e3-403f-bdeb-48c51d010364
sockets: 2
vmgenid: 3829d72e-6451-4352-9816-896d2bdea67f

3.2 添加 GPU 直通

qm set 120 --hostpci0 '0000:82:00,pcie=1'
  • pcie=1:以 PCIe 端点方式直通(P40 首选,避免降级传统 PCI 导致性能/兼容问题);

  • 若 GPU 还带独立 Audio Controller,另加一行 hostpci1

3.3 先不加 args,完成系统安装

安装 Ubuntu 22.04 到虚拟磁盘,配置好静态 IP(本例 192.168.8.24),SSH 可达后继续。



4. 客户机驱动安装(Ubuntu 22.04)

4.1 安装 580-server 驱动(apt + DKMS)

sudo apt update
sudo apt install -y nvidia-driver-580-server
sudo reboot

4.2 确认驱动编译与加载

dkms status
# 期望:nvidia-srv/580.173.02, 5.15.0-190-generic: installed

lsmod | grep nvidia            # 应能看到 nvidia 模块
ls -l /dev/nvidia*             # nvidia0/nvidiactl/nvidia-uvm 等节点
nvidia-smi                     # 若正常则直接跳到 §6

注意:不要用 NVIDIA 官网 runfile 安装(容易覆盖 DKMS 链路、与 apt 包冲突)。


5. 核心排障:NVRM: BAR0 is 0M @ 0x0 根治

5.1 症状

  • nvidia-smiNVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver

  • dmesg

NVRM: This PCI I/O region assigned to your NVIDIA device is invalid:
NVRM: BAR0 is 0M @ 0x0 (PCI:0000:01:00.0)
nvidia: probe of 0000:01:00.0 failed with error -1

5.2 快速定位(不要先重装驱动)

# guest 内:看 BAR 是否分配(全 0 即为未分配)
cat /sys/bus/pci/devices/0000:01:00.0/resource

# guest 内:确认设备 BDF 与 BAR 声明
lspci -v -s 01:00.0 | grep -E 'Memory at|Region'

# host 内:核对 VM 配置与生成的 QEMU 命令行
cat /etc/pve/qemu-server/120.conf
qm showcmd 120

排障经验:先看 dmesg | grep NVRM 是否有 BAR 报错,再核对宿主机直通参数,而不是盲目卸载重装驱动。若 DKMS installed、nvidia.ko 存在、nouveau 已屏蔽、Secure Boot 已关,问题几乎都在 PCI BAR 分配层。

5.3 根因

P40 的 BAR 布局为:BAR0=16M(32 位非预取)、BAR1=32G(64 位预取)、BAR3=32M。当 guest 内存大(本例 64GB)且显存 BAR 大时,需要两层地址空间都足够:

  1. QEMU 底层 64 位 PCI hole:默认 32G,被 64GB 内存 + 32GB BAR 挤爆;

  2. OVMF 固件内的 64 位 MMIO 窗口:默认仅 32GB(对应 edk2 的 opt/ovmf/X-PciMmio64Mb),同样装不下。

只修一层不够(实测仅扩 QEMU hole 后 BAR1/3 恢复,但 BAR0 仍为 0M);改 pcie=0 传统 PCI 直通同样无效。

5.4 修复(在宿主机执行,两步合一)

qm set 120 --hostpci0 '0000:82:00,pcie=1'   # 保持 PCIe 直通
qm set 120 --args '-global q35-pcihost.pci-hole64-size=96G -fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=65536'
qm start 120

最终 /etc/pve/qemu-server/120.conf 关键三行:

machine: q35
hostpci0: 0000:82:00,pcie=1
args: -global q35-pcihost.pci-hole64-size=96G -fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=65536

参数含义:

参数作用
-global q35-pcihost.pci-hole64-size=96G把 QEMU 底层 64 位 PCI hole 扩到 96GB(容纳 64G 内存后的大 BAR)
-fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=65536把 OVMF 固件的 64 位 MMIO 窗口扩到 65536MB=64GB(关键

说明:PVE 的 machine 配置项只接受白名单内的选项,直接写 q35,pci-hole64-size=96G 会被拒绝;因此这类参数统一走 args 透传给 QEMU。修改前建议先备份 cp /etc/pve/qemu-server/120.conf /root/120.conf.bak,改后用 qm showcmd 120 校验参数已生效。

窗口大小经验值:X-PciMmio64Mb 取 ≥ 内存 + 最大 BAR 对齐值,64GB 内存给 65536 即可;更大组合(128GB 内存)可给 131072。重启后即可恢复到 §4 的驱动状态,若此前驱动已装好则直接 nvidia-smi 应正常。


6. 验证清单

# guest 内
lspci -v -s 01:00.0 | grep -E 'Memory at'
# 期望:BAR0(16M)、BAR1(32G)、BAR3(32M) 均为有效地址,不再是 <ignored>/0x0

cat /sys/bus/pci/devices/0000:01:00.0/resource   # 前三行含非零地址

nvidia-smi
# 期望输出 Tesla P40、Driver 580.173.02、显存 23040MiB 全部可见

7. CUDA 安装(注意版本限制)

兼容性关键点:CUDA 13.0 已移除对 Pascal 架构的支持,Tesla P40 只能使用 CUDA 12.x 工具链。

驱动 580.173.02 向下兼容 CUDA 12.x(12.x 最低要求驱动 ≥ 525),所以组合为:驱动 580 + CUDA Toolkit 12.6

# guest 内(官方 apt 仓库路线,只装工具链、不覆盖现有驱动)
cd /tmp
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt-get update
sudo apt-get install -y cuda-toolkit-12-6

# 环境变量
echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc

# 验证
nvcc --version

编译运行样例验证计算可用:

# 编译 deviceQuery(nvcc 自带样例需单独装 cuda-samples,或直接 nvcc 编译测试内核)
cat > /tmp/t.cu <<'EOF'
#include <cstdio>
__global__ void k(int *a){ *a = 42; }
int main(){
  int h=0, *d; cudaMalloc(&d, sizeof(int));
  k<<<1,1>>>(d); cudaMemcpy(&h,d,sizeof(int),cudaMemcpyDeviceToHost);
  printf("CUDA OK, result=%d
", h); return 0;
}
EOF
nvcc -o /tmp/t /tmp/t.cu && /tmp/t
# 期望:CUDA OK, result=42

8. 常见问题速查表

现象排查方向处理
BAR0 is 0M @ 0x0 / probe -1guest dmesg + qm showcmd按 §5 加 pci-hole64-size + X-PciMmio64Mb 并重启 VM
宿主机 vfio-pci 0000:82:00.0: BAR 3: can't reserve宿主机显存占用宿主机内核加 video=efifb:off
Secure Boot 拦截 DKMS固件设置关 Secure Boot 或给模块签名
nouveau 抢占设备lspci -k 看驱动确认 blacklist + update-initramfs -u
VM 无法启动qm start 报错检查 IOMMU 组是否独立、设备是否被其他 VM 占用
大显存 BAR 仍分配异常确认内存配置视内存大小把 X-PciMmio64Mb 调到 131072 或更大


9. 命令速查(宿主机)

# 诊断
lspci -k -s 82:00                       # 设备驱动接管情况
cat /etc/pve/qemu-server/120.conf       # VM 配置
qm showcmd 120                          # 实际生成的 QEMU 命令行
qm status 120

# 修改与重启
qm set 120 --hostpci0 '0000:82:00,pcie=1'
qm set 120 --args '-global q35-pcihost.pci-hole64-size=96G -fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=65536'
qm shutdown 120 && qm start 120         # 或 qm stop 强制


10. 总结

  • 直通链路共三层:宿主 IOMMU/vfio → QEMU 地址空间 → OVMF 固件窗口,P40 这类大显存 GPU 三处都要配到位;

  • 排障优先级:dmesg 定位 BAR → 核对 VM 直通参数 → 必要时加 pci-hole64-size + X-PciMmio64Mb → 再考虑驱动层;

  • 版本红线:Pascal(P40) 不支持 CUDA 13,工具链固定用 CUDA 12.x;

  • 一切修改先备份 120.conf,重启前用 qm showcmd 校验。(内容由小泥巴根据一次实际经历整理)


相关标签: pve p40 AI 本地模型

发表评论:

评论记录:

未查询到任何数据!
QQ咨询
回电话
回拨通话

我们稍后回拨您的电话

座机请加区号

微信联系
微信扫一扫
微信二维码

扫码加微信