修改 PVE 使 VNC 显示显卡画面!

背景

如果我们给虚拟机安装了显卡

  • 如果我们将显示改为 "无 none"

VNC 就无法使用

  • 不修改, 双显示

部分应用无法调用 GPU


佛西 pxvirt 制作了补丁, 但是这个补丁有一些问题, 会将参数设置到非显卡设备上 (例如 SR-IOV 显卡)

修改

以下内容需要在 PVE 更新后重新修改!

修改 /usr/share/perl5/PVE/QemuServer.qm

原代码

    push @$devices, '-device', print_vga_device(
        $conf, $vga, $arch, $machine_version, $machine_type, undef, $qxlnum, $bridges);

添加判断到 ;

if $vga->{type} ne 'gpu'

修改后的代码

    push @$devices, '-device', print_vga_device(
        $conf, $vga, $arch, $machine_version, $machine_type, undef, $qxlnum, $bridges) if $vga->{type} ne 'gpu';

修改 /usr/share/perl5/PVE/QemuServer/PCI.qm

添加以下代码

        # If GPU is installed, read the frame from GPU
        if ($d->{'x-vga'}) {
            my $mdevtype = $d->{mdev} // "";
            $mdevtype =~ s/^(.*?)-.*$/$1/;

            $devicestr .= ",x-igd-opregion=on" if $mdevtype eq "i915";
            $devicestr .= ",display=on,ramfb=on,driver=vfio-pci-nohotplug";
            $vga->{type} = 'gpu';
        }

完整内容

        if ($j == 0) {
        $devicestr .= ',rombar=0' if defined($d->{rombar}) && !$d->{rombar};
        $devicestr .= "$xvga";
        $devicestr .= ",multifunction=on" if $multifunction;
        $devicestr .= ",romfile=/usr/share/kvm/$d->{romfile}" if $d->{romfile};
        $devicestr .= ",bootindex=$bootorder->{$id}" if $bootorder->{$id};
        for my $option (qw(vendor-id device-id sub-vendor-id sub-device-id)) {
            $devicestr .= ",x-pci-$option=$d->{$option}" if $d->{$option};
        }

        # If GPU is installed, read the frame from GPU
        if ($d->{'x-vga'}) {
            my $mdevtype = $d->{mdev} // "";
            $mdevtype =~ s/^(.*?)-.*$/$1/;

            $devicestr .= ",x-igd-opregion=on" if $mdevtype eq "i915";
            $devicestr .= ",display=on,ramfb=on,driver=vfio-pci-nohotplug";
            $vga->{type} = 'gpu';
        }
        }

建议顺便将上方的 x-vga 代码一起修改

    my $xvga = '';
    if ($d->{'x-vga'}) {
        $xvga = ',x-vga=on' if !($conf->{bios} && $conf->{bios} eq 'ovmf');
        $kvm_off = 1;
        $vga->{type} = 'none' if !defined($conf->{vga});
        $gpu_passthrough = 1;
    }

$kvm_off = 1 改为 将 $kvm_off = 0

原始代码会关闭 KVM 特征, 可能会影响虚拟机性能 (解决 NVIDIA 检测虚拟机导致 43 的问题, 新版 PVE 还会帮你自动设置 hv_vendor_idproxmox 绕过检测)

据说新版 NVIDIA 驱动已经不检测虚拟机了

光有 kvm=off 无法完全去除虚拟机特征, 新系统还需要在 CPU 中 -hypervisor

要去虚拟机特征还是老实写虚拟机配置文件

PVE 这个全局设置会影响 Intel 和 AMD 以及 vGPU, 挺傻逼的

重启 PVE

systemctl restart {pvedaemon,pveproxy}

当然你想直接 reboot 也行

设置虚拟机

将虚拟机的显卡 PCI 设备的 "主 GPU Primary GPU (x-vga)" 勾选, 重启虚拟机即可

如果虚拟机安装了显卡, 默认显示设备会被禁用, VNC 将从显卡读取画面

参考 / 致谢

最后修改:2025 年 05 月 31 日
如果觉得我的文章对你有用,请随意赞赏