本文编写时PVE(Proxmox Virtual Environment)版本为7.3-4,内核版本为5.15.83-1-pve
请注意你使用的PVE版本号!!!

关于PVE

PVE本质上是基于Debian修改的Linux系统,硬件兼容性十分优秀
有两套虚拟化内核,一套为KVM虚拟化,使用qemu作为虚拟化前端配置,另外一套为Linux原生的LXC容器虚拟化,类似于Docker

关于安装

PVE的安装和所有的Linux系统安装基本一致,制作ISO镜像,写入U盘,然后引导安装
这里就详细展开写了,安装并不是很复杂,可以参考其他博客或者官方安装文档

不过有一点需要注意的,如果你准备虚拟化的机器没有核显并且使用的是NVIDIA RTX20系以上的显卡
PVE官方安装引导镜像自带的nouveau驱动无法识别显卡信息,会无法驱动N卡输出画面
表现为PVE引导安装启动后黑屏无输出,切换到tty2后可以看到Xorg输出报错信息

原因是PVE使用的安装镜像自带的nouveau版本比较低,锅是Debian上游的锅
同理Debian安装也无法驱动RTX20系以上显卡(Debian你不修一修吗)

PVE令人无语的一点在于,它不提供CommandLine模式的GUI引导安装,所以Xorg模式下永远也没办法安装成功
Debian至少可以通过Grub参数添加textonly nomodeset引导一个纯文本的Debian安装界面完成安装
这个时候你需要使用Debian原生镜像安装Linux系统,然后通过PVE over Debian的方式安装PVE软件包

开启虚拟化

IOMMU

首先要保证BIOS中开启了VT-d或类似的虚拟化技术,否则是无法直通成功的
然后我们需要在Grub引导中开启iommu

# Intel CPU
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"
# AMD CPU
GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt"

执行更新grub

# PVE over Debian模式安装执行
update-grub2
# PVE引导镜像安装执行
pve-efiboot-tool refresh

加载对应的内核模块

/etc/modules中添加以下模块

vfio
vfio_pci
vfio_virqfd
vfio_iommu_type1

验证是否开启成功

重启之后,在终端输入

dmesg | grep remapping

出现如下例子。则代表成功

DMAR-IR: Enabled IRQ remapping in x2apic mode
#或者
AMD-Vi: Interrupt remapping enabled

到这里已经可以直通PCI-E除显卡外的所有设备了,然而显卡直通还有更多要求和配置

显卡直通

显卡直通需要满足前面所有的配置,同时虚拟机芯片组必须是q35,BIOS最好是UEFI模式

AMD的显卡如果给黑苹果使用,则需要小心重启bug
NVIDIA的显卡如果支持vGPU模式,可以配置虚拟PCI-E设备给虚拟机使用

下面的教程讲述的是全设备直通

屏蔽驱动

编辑/etc/modprobe.d/pve-blacklist.conf添加驱动屏蔽列表

# This file contains a list of modules which are not supported by Proxmox VE                          2
# nidiafb see bugreport https://bugzilla.proxmox.com/show_bug.cgi?id=701

# Nvidia
blacklist nvidiafb
blacklist nouveau
blacklist nvidia

# AMD
blacklist amdgpu
blacklist radeon

# Intel UHD
blacklist snd_hda_codec_hdmi
blacklist snd_hda_intel
blacklist snd_hda_codec
blacklist snd_hda_core

options nouveau modeset=0

根据你的显卡类型来对应添加对应的驱动屏蔽
如果你是NVIDIA的显卡,还需要执行

echo "options kvm ignore_msrs=1 report_ignored_msrs=0" > /etc/modprobe.d/kvm.conf

现在开始查看你需要直通的显卡

lspci -knn | grep -i -A 2 vga

OutPut:
17:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] [1002:67df] (rev e7)
        Subsystem: Advanced Micro Devices, Inc. [AMD/ATI] Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] [1002:0b31]
        Kernel driver in use: vfio-pci
--
65:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU104 [GeForce RTX 2080 Rev. A] [10de:1e87] (rev a1)
        Subsystem: ASUSTeK Computer Inc. TU104 [GeForce RTX 2080 Rev. A] [1043:865f]
        Kernel driver in use: vfio-pci

其中65:00是代表组名。65:00.0是代表65:00组的第一个设备
1043:865f表示厂商ID:设备ID,直接通过lspci看的话可以看到音频设备甚至是USB设备
这里我因为不需要对当前PCI-E设备组再拆分,所以直接略过

如果你需要设置显卡显示设备和音频设备单独直通,需要执行下面语句
让PCI-E设备(显卡)由vfio驱动程序接管便于直通
如果不需要单独直通,vfio驱动会在设置直通的时候自动接管PCI-E设备,可以不用配置vfio-pci

echo "options vfio-pci ids=10de:1381,10de:0fbc" > /etc/modprobe.d/vfio.conf
#注意,上面这条命令,ids=后面跟直通组的所有设备。中间以英文逗号隔开。自己的设备自己替换。

然后执行下面命令更新引导配置

update-initramfs -u -k all

重启验证PCI-E显卡是否被vfio-pci驱动,Kernel driver in use: vfio-pci表示直通驱动成功

lspci -knn | grep -i -A 2 vga

......
Kernel driver in use: vfio-pci

添加设备

虚拟机设置

在对应需要直通的虚拟机中添加PCI设备,使用如上图所示设置
勾选所有功能后同一IOMMU分组下所有PCIE设备都会进入直通

至此显卡直通已经完成,如果在虚拟机中安装完成以后出现驱动错误请继续往下看

Window错误代码43

网上有人说是CPU需要伪装,有的人说grub不需要那么多参数
但是都不适用我的情况

如果你和我情况一样可以继续看下去
注意PVE版本!!!
注意PVE版本!!!
注意PVE版本!!!

博主这边的CPU没有核显,独显作为输出设备的同时需要直通给虚拟机使用
此时显卡直通是成功的,进入Windows虚拟机后也能正常安装驱动,但是,一旦重启以后就显示错误代码43,显卡无法被正常驱动

同时会在dmesg中输出如下提示

vfio-pci 0000:65:00.0: BAR 3: can't reserve [mem 0xca000000-0xcbffffff 64bit]

这是因为在PVE 7.3中,5.15的内核会启动一个simplefb作为默认的显示输出设备
我们可以通过命令来确定是否有simplefb被加载了
上面的mem后面的地址就是要查询的内存地址
下面示例为修正以后的结果

cat /proc/iomem

......
93000000-b5ffffff : PCI Bus 0000:16
  a0000000-b01fffff : PCI Bus 0000:17
    a0000000-afffffff : 0000:17:00.0
      a0000000-afffffff : vfio-pci
    b0000000-b01fffff : 0000:17:00.0
      b0000000-b01fffff : vfio-pci
  b5e00000-b5efffff : PCI Bus 0000:17
    b5e00000-b5e3ffff : 0000:17:00.0
      b5e00000-b5e3ffff : vfio-pci
    b5e40000-b5e5ffff : 0000:17:00.0
    b5e60000-b5e63fff : 0000:17:00.1
      b5e60000-b5e63fff : vfio-pci
  b5f00000-b5f00fff : 0000:16:05.4
  b5ffc000-b5ffcfff : dmar0
b6000000-d8ffffff : PCI Bus 0000:64
  c0000000-d20fffff : PCI Bus 0000:65
    c0000000-cfffffff : 0000:65:00.0
      c0000000-cfffffff : vfio-pci
    d0000000-d1ffffff : 0000:65:00.0
      d0000000-d1ffffff : vfio-pci
    d2000000-d203ffff : 0000:65:00.2
      d2000000-d203ffff : vfio-pci
    d2040000-d204ffff : 0000:65:00.2
      d2040000-d204ffff : vfio-pci
  d7000000-d80fffff : PCI Bus 0000:65
    d7000000-d7ffffff : 0000:65:00.0
      d7000000-d7ffffff : vfio-pci
    d8080000-d8083fff : 0000:65:00.1
      d8080000-d8083fff : vfio-pci
    d8084000-d8084fff : 0000:65:00.3
      d8084000-d8084fff : vfio-pci
  d8100000-d8100fff : 0000:64:05.4
  d8ffc000-d8ffcfff : dmar1


如果你的输出里面出现了simplefb的字样,说明显卡被simplefb驱动了,这就是导致错误的原因。
我们可以修改grub引导菜单,添加一条指令就可以屏蔽simplefb的加载

# Intel CPU
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt initcall_blacklist=sysfb_init"
# AMD CPU
GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt initcall_blacklist=sysfb_init"

别的教程会让你在grub中添加video=vesafb:off video=efifb:off来保证直通,不过在PVE 7.3版本中这两条指令就没有必要加了,因为都被simplefb取代了,需要用initcall_blacklist=sysfb_init让simplefb不加载
vesafb是veas设备的fb,efifb是指uefi设备的fb

附录

参考链接:

说点什么
支持Markdown语法
在"PVE 7.3 优化和显卡直通"已有12条评论
Loading...