在OVMF虚拟机中安装NVIDIA Linux驱动¶
我在完成了 采用OVMF实现passthrough GPU和NVMe存储 配置之后,原本以为在passthough的OVMF虚拟机内部,对NVIDIA GPU的驱动安装会像在物理主机上 安装NVIDIA Linux驱动 一样轻松。毕竟,理论上说,直通进虚拟机的NVIDIA GPU卡不就是虚拟机独占的一块物理GPU卡么。
然而,实践并没有像预想的那么顺利…
备注
由于我之前已经在物理主机安装(演练)过一遍 安装NVIDIA Linux驱动 ,所以采用相同方法在 采用OVMF实现passthrough GPU和NVMe存储 的虚拟机 z-k8s-n-1
安装 NVIDIA CUDA 驱动
安装NVIDIA Linux驱动¶
根据不同发行版在 NVIDIA CUDA Toolkit repo 下载 选择对应的 CUDA软件仓库 ,例如我的 私有云架构 采用了 Ubuntu 22.04 LTS,所以执行如下步骤在系统中添加仓库:
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.0-1_all.deb
sudo dpkg -i cuda-keyring_1.0-1_all.deb
sudo apt-get update
安装 NVIDIA CUDA 驱动:
sudo apt-get -y install cuda-drivers
这里安装过程提示不能支持 Secure Boot:
Building initial module for 5.15.0-57-generic
Can't load /var/lib/shim-signed/mok/.rnd into RNG
40A7F3E73E7F0000:error:12000079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:106:Filename=/var/lib/shim-signed/mok/.rnd
...
Secure Boot not enabled on this system.
Done.
重启操作系统,检查驱动安装:
nvidia-smi
我以为一切顺利结束,然而…
NVIDIA passthrough via ovmf需要Host主机内核参数 pci=realloc
¶
在虚拟机内部 安装NVIDIA Linux驱动 遇到异常,设备没有初始化成功,从 dmesg -T
看到:
[Wed Jan 11 00:56:18 2023] NVRM: The NVIDIA probe routine failed for 1 device(s).
[Wed Jan 11 00:56:18 2023] NVRM: None of the NVIDIA devices were initialized.
[Wed Jan 11 00:56:18 2023] nvidia-nvlink: Unregistered Nvlink Core, major device number 235
[Wed Jan 11 00:56:18 2023] nvidia-nvlink: Nvlink Core is being initialized, major device number 235
[Wed Jan 11 00:56:18 2023] NVRM: This PCI I/O region assigned to your NVIDIA device is invalid:
NVRM: BAR0 is 0M @ 0x0 (PCI:0000:09:00.0)
[Wed Jan 11 00:56:18 2023] nvidia: probe of 0000:09:00.0 failed with error -1
[Wed Jan 11 00:56:18 2023] NVRM: The NVIDIA probe routine failed for 1 device(s).
[Wed Jan 11 00:56:18 2023] NVRM: None of the NVIDIA devices were initialized.
这个问题在 PCI passthrough via OVMF/Examples 找到案例,案例中建议物理主机内核参数需要增加 pci=realloc
,否则就会导致类似错误:
NVRM: This PCI I/O region assigned to your NVIDIA device is invalid: NVRM: BAR1 is 0M @ 0x0 (PCI:0000:0a:00.0)
所以修订 采用OVMF实现passthrough GPU和NVMe存储 物理主机内核参数添加 pci=realloc
并重启物理主机
不过,我在物理主机内核参数配置了 pci=realloc
依然没有解决这个问题,虚拟机内部依然同样错误。
在NVIDIA论坛中 NVRM: This PCI I/O region assigned to your NVIDIA device is invalid #229899 提到如果 pci=realloc
不生效可以尝试 pci=realloc=off
。
正在迷惘的时候,参考 NVRM: This PCI I/O region assigned to your NVIDIA device is invalid #81645 ,原来这个问题就是我在 HP DL360 Gen9 Large Bar Memory(Tesla P10) 曾经解决过的,当时发现BIOS自检报错:
276 Option Card Configuration Error. An option card is requesting more memory
mapped I/O than is available.
Action: Remove the option card to allow the system to boot.
通过 HP DL360 Gen9 BIOS设置 PCI Express 64-Bit BAR Support 解决,所以在物理服务器上 安装NVIDIA Linux驱动 就没有遇到 PCI I/O region assigned to your NVIDIA device is invalid
这样的错误。
这个 PCI I/O region
资源分配问题是常见的,表示pci设备所需的内存窗口大小和区域(BAR)最初是由BIOS分配,但是有时候不正确或不兼容,参数 pci=realloc
使内核能够更改区域。
结合 Nvidia drivers for Tesla V100 PCIe 32Gb failing to load 和上文的几个参考文档,我逐渐想清楚了:
对于NVIDIA GPU,物理主机的BIOS需要激活 HP DL360 Gen9 BIOS设置 PCI Express 64-Bit BAR Support 来支持正确的pci设备所需的内存窗口大小和区域(BAR)
如果BIOS比较古老不支持上述
64-Bit Addressing
或者Large BAR
配置,则可以通过物理服务器的Linux操作系统内核参数pci=realloc
来由内核更改PCI设备内存窗口和区域(BAR)实际上我已经在 HPE ProLiant DL360 Gen9服务器 完成了 HPE DL360 BIOS升级 ,并通过 激活 HP DL360 Gen9 BIOS设置 PCI Express 64-Bit BAR Support 支持,所以没有必要配置物理主机内核参数
pci=realloc
(两者目的是相同的)。这也是为何在物理主机上添加了内核参数pci=realloc
前后效果相同的原因。
需要注意的是,上述配置都是在物理服务器上完成,但是这样依然不能使得虚拟机正确
备注
虚拟机配置 : 反复尝试后我发现 其实需要同时满足2个条件
(见下文)
虚拟机qemu通过传递
-global q35-pcihost.pci-hole64-size=2048G
可以分配更大的PCI内存窗口( HGX A100 VM passthrough issues on Ubuntu 20.04 ),对于libvirt配置方法,我参考 qemuxml2xmlout-pcihole64-gib.xml
执行 virsh edit z-k8s-n-1
找到:
<controller type='pci' index='0' model='pcie-root'/>
修改成:
<controller type='pci' index='0' model='pcie-root'>
<pcihole64 unit='KiB'>2147483648</pcihole64>
</controller>
然后启动虚拟机后检查 qemu
参数就可以看到 -global q35-pcihost.pci-hole64-size=2147483648K
不过,此时虚拟机内部依然报错 (还需要下面一步)
虚拟机内核还是要添加
pci=realloc
才能彻底解决NVIDIA的PCI I/O region
错误问题单纯在虚拟机内核上配置
pci=realloc
是不够的(目前我的物理主机还开启着pci=realloc
,等有时间我关闭物理主机内核pci=realloc
验证一下我的猜想)
在虚拟机内部修改 /etc/default/grub
将:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
修改成:
GRUB_CMDLINE_LINUX_DEFAULT="pci=realloc quiet splash"
然后执行:
update-grub
再重启一次虚拟机
WOW,终于虚拟机内部不再出现NVIDIA相关报错,并且执行 nvidia-smi
可以正确看到
Wed Jan 11 20:27:44 2023
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.60.13 Driver Version: 525.60.13 CUDA Version: 12.0 |
|-------------------------------+----------------------+----------------------+
| 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 Graphics... On | 00000000:09:00.0 Off | 0 |
| N/A 30C P8 9W / 150W | 0MiB / 23040MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+