文章与记录

NVIDIA RTX 5090D v2 显卡直通故障排查总结

折腾 RTX 5090D v2 直通时,我遇到了虚拟机黑屏、显卡可识别但 nvidia-smi 找不到设备的问题。这篇文章记录完整排查思路,以及最终定位到的 Open Kernel Module 兼容性问题。

最近为了在虚拟机里跑 CUDA 和 AI 模型,我开始折腾 RTX 5090D v2 的 PCIe 直通。原本以为照着以前的经验配置好 IOMMU、绑定 vfio-pci,再把设备挂进虚拟机就能收工,结果却遇到了一组很容易让人误判的问题:

  • PVE 显示虚拟机已经启动,但 noVNC 一片黑;
  • Ubuntu 能看到显卡,驱动也确实绑定上了;
  • 可一运行 nvidia-smi,只得到一句 No devices were found

最开始我怀疑是直通根本没有成功,后来顺着 PCIe 枚举、驱动绑定和内核日志逐层检查,才发现真正的问题并不在 VFIO,而在 NVIDIA 内核模块的类型上。

这篇文章记录一下完整的排查过程,也给遇到类似问题的人留一条可以参考的思路。

我的硬件与软件环境

这次使用的环境如下:

  • 虚拟化平台:Proxmox VE 8
  • 虚拟机编号:VM 101
  • 虚拟机系统:Ubuntu 24.04.4
  • 虚拟机内核:Linux 6.8.0-124-generic
  • 虚拟机固件:OVMF / UEFI
  • 虚拟机类型:Q35
  • 显卡型号:NVIDIA GeForce RTX 5090D v2
  • GPU 设备 ID:10de:2b8c
  • 音频设备 ID:10de:22e8
  • NVIDIA 驱动版本:580.159.03

直通配置:看起来一切正常

在 PVE 宿主机上,显卡和它自带的音频设备都能正常识别。两个 PCIe 设备位于有效的 IOMMU Group 中,也已经成功绑定到了 vfio-pci

宿主机使用的 IOMMU 启动参数是:

intel_iommu=on iommu=pt initcall_blacklist=sysfb_init

虚拟机使用 OVMF 固件和 Q35 机器类型,通过 hostpci0 把整张显卡分配给 VM 101。最初的配置是:

hostpci0: 0000:01:00,pcie=1

为了排除显卡 ROM 初始化带来的影响,后面还尝试过关闭 ROM BAR:

hostpci0: 0000:01:00,pcie=1,rombar=0

从宿主机这一侧来看,配置没有明显异常。但把显卡加入虚拟机之后,事情开始变得奇怪。

第一个问题:虚拟机黑屏

最直观的现象是黑屏:

  1. 虚拟机 noVNC 控制台显示黑屏;
  2. 物理显示器仍停留在 PVE 宿主机界面;
  3. 但通过 SSH 进入 Ubuntu 后,系统其实已经正常启动;
  4. Ubuntu 甚至能够识别 RTX 5090D v2。

这里很容易产生一个误区:noVNC 黑屏不等于虚拟机没有启动,也不等于显卡直通失败。

如果关闭了 PVE 提供的虚拟显卡,noVNC 自然就没有可以显示的设备。而物理显示器没有切换到直通显卡的输出,也可能只是显卡 ROM 或启动阶段显示初始化的问题。

因此,在排查期间,我更倾向于先保留一张虚拟显卡:

qm set 101 --vga std

这样至少还能通过 noVNC 观察系统启动过程,不必把“控制台不可见”和“虚拟机启动失败”混在一起判断。

如果问题确实与显卡 ROM 初始化有关,则可以进一步尝试:

qm set 101 --hostpci0 0000:01:00,pcie=1,rombar=0

另外,qemu-guest-agent 如果没有运行,PVE 对虚拟机内部状态的判断也可能不够准确。它未必是黑屏的直接原因,但会增加排查时的干扰。

第二个问题:显卡存在,nvidia-smi 却看不到

比黑屏更关键的问题出现在 Ubuntu 内部。

系统能识别显卡,lspci 也显示 NVIDIA 驱动已经绑定:

设备检查结果如下:

NVIDIA GeForce RTX 5090 D v2 [10de:2b8c]
Kernel driver in use: nvidia

但执行 nvidia-smi 时,返回的却是:

No devices were found

这个组合非常关键:

系统能够枚举设备,驱动也绑定到了设备,但 NVIDIA 用户态工具仍然无法使用 GPU。

这意味着显卡大概率已经成功进入虚拟机,问题不在“有没有直通进来”,而在“驱动能不能完成硬件初始化”。于是,我把排查重点从 PVE 和 VFIO 转向了 Ubuntu 内核日志。

真正有用的线索在内核日志里

检查日志后,首先看到的是这条错误:

RmInitAdapter failed (0x22:0x56:897)

单看 RmInitAdapter failed 很难直接判断原因,不过后面的 NVIDIA 驱动日志给出了更明确的提示:

requires use of the NVIDIA open kernel modules

与此同时,虚拟机里的 NVIDIA 驱动信息目录已经可以识别显卡型号:

/proc/driver/nvidia/gpus/*/information

到这里,排查方向已经比较清晰了:PCIe 直通链路和设备枚举基本正常,真正失败的是 NVIDIA 驱动对 GPU 的初始化。

原因定位:需要 Open Kernel Module

综合以下几个现象:

  • Ubuntu 能通过 PCIe 枚举到 RTX 5090D v2;
  • Kernel driver in use 已经显示为 nvidia
  • nvidia-smi 仍然提示没有设备;
  • 内核出现 RmInitAdapter failed
  • 驱动日志明确提示需要 NVIDIA Open Kernel Module。

我最终把主要原因定位为:当前系统加载的 NVIDIA 内核模块类型与 RTX 5090D v2 不兼容。

换句话说,这不是一次典型的“显卡没有直通成功”,而是显卡已经直通成功,但驱动在真正接管和初始化设备时失败了。

黑屏与 nvidia-smi 无设备也不应该被当成同一个故障:前者更偏向虚拟显示、物理输出或 ROM 初始化,后者则是驱动兼容性问题。

下一步:切换到开放内核模块

根据日志提示,下一步应该优先切换到 NVIDIA Open Kernel Module 版本:

sudo apt update
sudo apt install nvidia-driver-580-open

不过不建议直接覆盖安装。为了避免旧版闭源 DKMS 模块继续被 initramfs 加载,安装前最好先检查当前系统中的 NVIDIA 和 CUDA 软件包:

dpkg -l | grep -E 'nvidia|cuda'
dkms status

确认没有冲突或残留后,再安装开放内核模块。安装完成后,重新生成 initramfs 并重启:

sudo update-initramfs -u
sudo reboot

重启后,我计划使用下面这组命令逐项确认:

lspci -nnk -s 01:00.0
lsmod | grep nvidia
modinfo nvidia
nvidia-smi
dmesg | grep -iE 'nvidia|nvrm|rminitadapter'

同时也需要检查 Secure Boot 状态:

mokutil --sb-state

如果切换到 Open Kernel Module 后仍然无法初始化显卡,接下来还可以继续检查:

  • initramfs 中是否仍包含旧版闭源 NVIDIA 模块;
  • 系统实际加载的是否为 Open Kernel Module;
  • Ubuntu 当前内核版本是否完整支持 RTX 5090D v2;
  • 是否需要升级至更新的 HWE 内核;
  • 显卡是否存在 PCIe Reset 或 ROM BAR 兼容问题;
  • Secure Boot 是否阻止驱动模块正常加载。

验证:Open Kernel Module 切换后 nvidia-smi 恢复正常

切换到 nvidia-driver-580-open 并重新生成 initramfs 后重启,虚拟机内再次检查:

lspci -nnk -s 01:00.0
lsmod | grep nvidia
modinfo nvidia | grep -i license
nvidia-smi

lspci 仍然显示 Kernel driver in use: nvidiamodinfo 确认许可证为 Dual MIT/GPL(Open Kernel Module 特征),nvidia-smi 成功输出设备信息:

+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.159.03             Driver Version: 580.159.03     CUDA Version: 12.8   |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|   0  NVIDIA GeForce RTX 5090 D v2    On | 00000000:01:00.0 Off |                  N/A |
| 30%   34C    P8             15W / 500W |      2MiB /  32760MiB |      0%      Default |
+-----------------------------------------+----------------------+----------------------+

随后跑了一个简单的 CUDA 向量加法测试,结果正确。这说明:

  • 显卡 PCIe 直通链路已经稳定;
  • Open Kernel Module 确实解决了 RTX 5090D v2 在虚拟机中的初始化问题;
  • 黑屏问题在保留虚拟显卡(--vga std)后可忽略,不影响 CUDA 计算任务。

这次排查得到的结论

回过头看,这次最容易误判的地方,是把“黑屏”“驱动已绑定”和“显卡可用”混为一谈。

根据最终验证,可以确认的是:

  1. PVE 宿主机能够正常识别 RTX 5090D v2;
  2. IOMMU 与 vfio-pci 绑定配置基本正常;
  3. 显卡已经成功直通至 Ubuntu 虚拟机;
  4. Ubuntu 能够识别显卡及其 PCIe 设备信息;
  5. 初始闭源 NVIDIA 驱动已经绑定显卡,但未能完成设备初始化;
  6. 驱动日志明确要求使用 NVIDIA Open Kernel Module;
  7. 切换到 nvidia-driver-580-open 后,nvidia-smi 与 CUDA 测试均恢复正常;
  8. 虚拟机黑屏由虚拟显示关闭或显卡 ROM 初始化异常引起,应作为独立显示问题排查,不影响计算任务。

对我来说,这次排查最重要的经验是:

能被 lspci 看到,只能说明设备已经被枚举;显示 Kernel driver in use: nvidia,也不代表 GPU 已经完成初始化。判断 NVIDIA 显卡是否真正可用,仍然要结合 nvidia-smi、CUDA 测试、dmesg 和驱动日志一起分析。

RTX 5090D v2 的 PCIe 直通流程已经跑通,主要问题集中在 NVIDIA 驱动内核模块兼容性。后续只需要保持 Open Kernel Module 状态,并在升级内核或驱动时留意模块类型是否被覆盖。

至于启动黑屏,可以通过保留虚拟显卡和设置 rombar=0 分别验证,不必把它和 CUDA 驱动初始化问题绑在一起处理。