一次失败的 KVM 虚拟化 GPU 穿透案例

    科技2022-07-10  138

    了解到 KVM 虚拟化技术,可以直接将宿主机的物理硬件穿透到客户机,让客户机独占硬件,所以我尝试在自己的笔记本上做实验。

    场景说明:

    笔记本:拯救者 Y7000P 2018版 GTX 1060(这个版本的电脑一言难尽,首先它是双显卡,电脑显示器与 Intel 核显直连,而电脑的 HDMI 接口和独显直连。这个奇怪的结构让我没办法完美安装 nvidia 驱动,我尝试了交火驱动和单独nvidia驱动都有各种毛病。后来放弃折腾了,就只装了一个 nouveau 驱动勉强凑活着。操作系统:Manjaro Linux 5.8

    因为笔记本上的 linux 本身就没办法使用 NIVIDA 的独显,所以安装一个虚拟机,把 NVIDIA 独显穿透过去,岂不美哉?

    不过,经过了一整天的折腾,我都没有成功。

    KVM 硬件穿透的思路

    经过资料搜集,我理解的 kvm 硬件穿透的流程如下:

    首先硬件上要支持,主要是 cpu 和主板都支持硬件穿透才可以;配置好 kvm 相关的软件包,可以基于 kvm 安装虚拟机,大约需要先安装 kvm 和 kvm_intel 内核模块,再安装 qemu libvirt virt-manager 等相关软件包;在宿主机上屏蔽掉想要穿透的硬件,为他强行绑定一个do nonthing 的驱动 vfio,避免宿主机和客户机同时对硬件访问造成冲突;安装 OVMF ,其作用是提供 UEFI 的虚拟机引导方式;在 virt-manager 中设置客户机的配置时,将 PCI 设备分配给客户机;在客户机上为对应的设备安装驱动,完成使用。

    Manjaro 的 KVM 硬件传统教程在PCI passthrough via OVMF (简体中文)一文中讲的非常详细,我是参照这篇文章进行解决的。

    碰到问题的地方

    NVIDIA 驱动的反虚拟机问题

    首先我没想到的是,NVIDIA 的显卡驱动居然会检查是否在虚拟机环境,如果它认为自己在虚拟机环境,就不会工作。。其他人表现为:

    Windows 下安装驱动报 43 错误Linux 安装驱动后,运行 nvidia-smi 无法找到显卡

    实验中实际表现为:

    ~ >>> nvidia-smi Unable to determine the device handle for GPU 0000:07:00.0: Unknown Error

    需要编辑 libvirt 虚拟机的 xml 文件,添加下面参数 到 <features></features>位置,value 为任意12位即可。

    <hyperv> <relaxed state="on"/> <vapic state="on"/> <spinlocks state="on" retries="8191"/> <vendor_id state="on" value="123456789123"/> </hyperv> <kvm> <hidden state="on"/> </kvm>

    解决了这个问题后,报错内容发生了变化,但主要意思依旧是找不到显卡:

    ~ >>> nvidia-smi No devices were found

    这里,我尝试了多种 NVIDIA 驱动,都没能解决:

    从官方源下载的最新驱动 linux58-nvidia-450xx从官方源下载的稍久一些的驱动 linux58-nvidia-430xx从 NVIDIA 网站下载的驱动 xx450xx.run 手动安装

    VBIOS 与 UEFI 兼容问题

    后来经过一番搜索,可以认为在穿透的过程中发生了 VBIOS 的兼容问题(大概)

    客户机启动后,通过排查 log 可以看到类似的错误信息:

    sudo dmesg | grep NVRM [ 5.043645] NVRM: loading NVIDIA UNIX x86_64 Kernel Module 450.66 Wed Aug 12 19:42:48 UTC 2020 [ 5.401373] NVRM: GPU 0000:07:00.0: Failed to enable MSI; falling back to PCIe virtual-wire interrupts. [ 5.433614] NVRM: GPU 0000:07:00.0: Failed to copy vbios to system memory. [ 5.433825] NVRM: GPU 0000:07:00.0: RmInitAdapter failed! (0x30:0xffff:794) [ 5.439493] NVRM: GPU 0000:07:00.0: rm_init_adapter failed, device minor number 0 [ 24.653394] NVRM: GPU 0000:07:00.0: Failed to enable MSI; falling back to PCIe virtual-wire interrupts. [ 24.657640] NVRM: GPU 0000:07:00.0: Failed to copy vbios to system memory. [ 24.657827] NVRM: GPU 0000:07:00.0: RmInitAdapter failed! (0x30:0xffff:794) [ 24.658861] NVRM: GPU 0000:07:00.0: rm_init_adapter failed, device minor number 0 [ 26.235602] NVRM: GPU 0000:07:00.0: Failed to enable MSI; falling back to PCIe virtual-wire interrupts. [ 26.241812] NVRM: GPU 0000:07:00.0: Failed to copy vbios to system memory. [ 26.241941] NVRM: GPU 0000:07:00.0: RmInitAdapter failed! (0x30:0xffff:794) [ 26.242174] NVRM: GPU 0000:07:00.0: rm_init_adapter failed, device minor number 0 [ 27.023331] NVRM: GPU 0000:07:00.0: Failed to enable MSI; falling back to PCIe virtual-wire interrupts. [ 27.034210] NVRM: GPU 0000:07:00.0: Failed to copy vbios to system memory. [ 27.034393] NVRM: GPU 0000:07:00.0: RmInitAdapter failed! (0x30:0xffff:794) ......

    其中关键的报错为 GPU 0000:07:00.0: Failed to copy vbios to system memory.

    sudo cat /var/log/Xorg.0.log [ 5.394] (II) NVIDIA GLX Module 450.66 Wed Aug 12 19:41:37 UTC 2020 [ 5.398] (II) NVIDIA: The X server supports PRIME Render Offload. [ 5.542] (EE) NVIDIA(GPU-0): Failed to initialize the NVIDIA GPU at PCI:7:0:0. Please [ 5.542] (EE) NVIDIA(GPU-0): check your system's kernel log for additional error [ 5.542] (EE) NVIDIA(GPU-0): messages and refer to Chapter 8: Common Problems in the [ 5.542] (EE) NVIDIA(GPU-0): README for additional information. [ 5.542] (EE) NVIDIA(GPU-0): Failed to initialize the NVIDIA graphics device! [ 5.542] (EE) NVIDIA(0): Failing initialization of X screen [ 5.542] (II) UnloadModule: "nvidia" [ 5.542] (II) UnloadSubModule: "glxserver_nvidia" [ 5.542] (II) Unloading glxserver_nvidia [ 5.542] (II) UnloadSubModule: "wfb" [ 5.542] (II) UnloadSubModule: "fb" [ 5.542] (EE) Screen(s) found, but none have a usable configuration. [ 5.542] (EE) Fatal server error: [ 5.542] (EE) no screens found(EE) [ 5.542] (EE) Please consult the The X.Org Foundation support at http://wiki.x.org for help. [ 5.542] (EE) Please also check the log file at "/var/log/Xorg.0.log" for additional information. [ 5.542] (EE) [ 5.543] (EE) Server terminated with error (1). Closing log file.

    着相关的报错,让我们知道可能在 VBIOS 的地方出了问题。但什么是 VBIOS 呢?大概相当于显卡的 BIOS。

    PCI passthrough via OVMF (简体中文)中建议首先通过对比 VBIOS 的内容或版本来判断是否支持 EFI。

    该文中建议使用如下方法提取 rom,但实际操作时提取不出来,会提示输入输出错误。

    sudo su root echo 1 > /sys/bus/pci/devices/0000:01:00.0/rom cat /sys/bus/pci/devices/0000:01:00.0/rom > /tmp/image.rom echo 0 > /sys/bus/pci/devices/0000:01:00.0/rom [manjaro 0000:01:00.0]# echo 1 > rom [manjaro 0000:01:00.0]# cat rom cat: rom: 输入/输出错误 [manjaro 0000:01:00.0]#

    此外,还有一种可以读取、刷些 VBIOS 的程序 nvflash,可以从外网搜索下载。

    [manjaro tmp]# ./nvflash_linux --version NVIDIA Firmware Update Utility (Version 5.414.0) Simplified Version For OEM Only mmap(): /dev/mem[0xa3000000:0x1000000]: Operation not permitted Device:01:00:00=10DE:1C20:0000:0000 GPU ERROR: attempt to map physical memory failed

    该软件却无法解读我的电脑的 VBIOS 的内容信息。所以一时半会不知道如何解决这个问题,只能大概认为是笔记本设计的问题了,等后面有机会用台式试一下。(因为稍微麻烦下,要多准备一张显卡)

    所以一次失败而又愉快的 KVM 显卡穿透实验就此结束,稍晚点儿试试其他硬件穿透(移动硬盘、USB 分线器之类的),到时如果成功了会重新写一篇文章。

    Reference

    PCI passthrough via OVMF (简体中文)Ubuntu+KVM显卡穿透VBIOS
    Processed: 0.019, SQL: 8