Nvidia GPU虚拟化转发失败,错误代码为43。

7

我目前正在尝试使用qemu 2.5和libvirt 1.3.5将nvidia GPU传递给Windows 10客户机。

在设备管理器中,我看到Nvidia GPU上显示“错误43”。

我尝试通过添加“kvm=off”和“hv_vendor_id=123456780ab”来隐藏虚拟化监控程序,但对我无效。我在谷歌上搜索,人们是这样解决问题的。

我还在任务管理器中看到虚拟机:是。

  1. 我用错了吗?我可以将AMD GPU传递给Windows客户机(AMD不检查kvm虚拟化)。

  2. 我能以其他方式欺骗nvidia吗?

我的系统信息:

#uname -a
Linux ns.mqcache.net 4.2.0-1.el7.elrepo.x86_64 #1 SMP Sun Aug 30 21:25:29 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux

#/root/qemu25/qemu/x86_64-softmmu/qemu-system-x86_64 --version
QEMU emulator version 2.5.1.1, Copyright (c) 2003-2008 Fabrice Bellard

GPU:

02:00.0 VGA compatible controller: NVIDIA Corporation GF119 [GeForce GT 620 OEM] (rev a1)
02:00.1 Audio device: NVIDIA Corporation GF119 HDMI Audio Controller (rev a1)

libvirt.xml

<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">  
  <name>win10</name>  
  <os> 
    <type machine="q35">hvm</type>  
    <boot dev="hd"/>  
    <boot dev="cdrom"/> 
  </os>  
  <features> 
    <acpi/>  
    <apic/>  
    <hyperv>
      <vendor_id state='on' value='1234567890ab'/>
    </hyperv>
    <kvm>
      <hidden state='on'/>
    </kvm>
  </features>   
  <clock offset="localtime"> 
    <timer name="rtc" tickpolicy="catchup"/>  
    <timer name="pit" tickpolicy="delay"/>  
    <timer name="hpet" present="no"/> 
    <timer name='hypervclock' present='yes'/>
  </clock>  
  <on_poweroff>destroy</on_poweroff>  
  <on_reboot>restart</on_reboot>  
  <on_crash>destroy</on_crash>  
  <vcpu current="4">4</vcpu>  
  <cpu mode="host-passthrough"> 
    <topology sockets="1" cores="4" threads="1"/> 
  </cpu>  
  <memory>8388608</memory>  
  <currentMemory>8388608</currentMemory>  
  <devices> 
    <emulator>/root/qemu25/qemu/x86_64-softmmu/qemu-system-x86_64</emulator>  
    <disk device="disk" type="file"> 
      <driver name="qemu" type="qcow2"/>  
      <source file="/root/vm/win10/image.qcow2"/>  
      <target bus="virtio" dev="vda"/> 
    </disk>  
    <sound model="ac97"/>  
    <interface type="bridge"> 
      <mac address="fa:16:3e:81:00:03"/>  
      <source bridge="eucabr"/>  
      <model type="virtio"/>  
      <driver name="qemu"/>  
      <alias name="net0"/> 
    </interface>  
    <hostdev mode="subsystem" type="pci" managed="yes"> 
      <source> 
        <address domain="0x0000" bus="0x02" slot="0x00" function="0x1"/>
      </source> 
    </hostdev> 
  </devices>  
  <qemu:commandline> 
    <qemu:arg value="-machine"/>  
    <qemu:arg value="smm=off"/>  
    <qemu:arg value="-device"/>  
    <qemu:arg value="ioh3420,bus=pcie.0,addr=1c.0,multifunction=on,port=1,chassis=1,id=root.1"/>  
    <qemu:arg value="-device"/>  
    <qemu:arg value="vfio-pci,host=02:00.0,bus=root.1,addr=00.0,multifunction=on,x-vga=on"/>  
    <qemu:arg value="-vga"/>  
    <qemu:arg value="none"/>  
  </qemu:commandline> 
</domain>

QEMU命令

/root/qemu25/qemu/x86_64-softmmu/qemu-system-x86_64 \
-name win10 \
-machine q35,accel=kvm,usb=off \
-cpu host,kvm=off,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time,hv_vendor_id=blah \
-m 2048 \
-realtime mlock=off \
-smp 2,sockets=1,cores=2,threads=1 \
-no-user-config \
-nodefaults  \
-rtc base=localtime \
-no-shutdown \
-boot strict=on \
-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \
-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x1 \
-drive file=/root/vm/win10/snap.qcow2,if=none,id=drive-virtio-disk0,format=qcow2 \
-device virtio-blk-pci,scsi=off,bus=pci.2,addr=0x2,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 \
-k en-us \
-device virtio-balloon-pci,id=balloon0,bus=pci.2,addr=0x4 \
-machine smm=off \
-device ioh3420,bus=pcie.0,addr=1c.0,multifunction=on,port=1,chassis=1,id=root.1 \
-device vfio-pci,host=02:00.0,bus=root.1,addr=00.0,multifunction=on,x-vga=on \
-device vfio-pci,host=02:00.1,bus=root.1,addr=00.1 \
-msg timestamp=on \
-vga none

期待您的帮助!

2个回答

8

您需要将未修改的显卡ROM副本传递给虚拟机。

  • You need a secondary GPU that you can use as the primary for this
    process. You cannot dump a clean copy of the BIOS without having the passthrough GPU as a secondary card
  • Put the extra card in the primary slot and the intended passthrough card in another pci-e port and bootup.
  • Find your intended GPU again via lspci -v. In my case it had about the same address.
  • Now you can dump the ROM to a file:

    # echo "0000:05:00.0" > /sys/bus/pci/drivers/vfio-pci/unbind
    # cd /sys/bus/pci/devices/0000\:05\:00.0
    # echo 1 > rom 
    # cat rom > /home/username/KVM/evga_gtx970.dump
    # echo 0 > rom
    # echo "0000:05:00.0" > /sys/bus/pci/drivers/vfio-pci/bind
    

    In this case, 0000:05:00.0 is my PCI card address. You don't really need the bind step at the bottom since you'll be rebooting anyways.

  • You can check the integrity of the ROM dump with this handy utility at https://github.com/awilliam/rom-parser. My rom looks like:

    # ./rom-parser evga_gtx970.dump
    Valid ROM signature found @0h, PCIR offset 1a0h
            PCIR: type 0 (x86 PC-AT), vendor: 10de, device: 13c2, class: 030000
            PCIR: revision 0, vendor revision: 1
    Valid ROM signature found @f400h, PCIR offset 1ch
            PCIR: type 3 (EFI), vendor: 10de, device: 13c2, class: 030000
            PCIR: revision 3, vendor revision: 0
                    EFI: Signature Valid, Subsystem: Boot, Machine: X64
    Last image
    

    You should have both an EFI and a non-EFI x86 ROM in the dump ( I think most cards have both)

  • Turn off the machine and put your GTX 1070 back in the primary slot.
  • After booting, edit your VM xml and in the section for your GPU (if you have already assigned the GPU to the VM) there should be a section. Add a file='path/to/dump/here' statement to it. My full section looks like:

    <hostdev mode='subsystem' type='pci' managed='yes'>
      <source>
        <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
      </source>
      <rom bar='on' file='/home/username/KVM/evga_gtx970.dump'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </hostdev>
    

    This will have the VM start the card with that BIOS instead of whatever the kernel gives it.

来源

请注意,您必须使用OVMF(EFI),因为SeaBIOS无法正确使用卡ROM。


对我来说,以这种方式转储BIOS是有效的,但通过GPU-Z转储的BIOS无法使用。然而,rom-parser表示两者都是有效的。有效的BIOS为126K,无效的BIOS为253K。 - Joey Adams
我正在使用的卡是我的次要卡。我已经通过vfio让我的主机忽略它了。除非我已经启动了主机计算机,否则在启动主机计算机时没有什么可以转储的,然后我可以从该GPU转储rom。这与您描述的是否不同? - Ant
不确定我理解你的情况。你能详细解释一下吗? - Andrey

1
如果您使用OVMF或其他UEFI,请确保三次检查您的显卡是否支持UEFI,特别是在早于2014年的设备上。
我错误地认为我的显卡(GTX 770)支持UEFI,但实际上并不支持(在线查看了错误版本的ROM),浪费了将近两天的时间。请查找UEFI支持(例如),并在此处查找ROM更新。
我刷过我的显卡,但我认为您也可以将启用UEFI的ROM作为romfile=。如果您的显卡没有UEFI修复程序,则其他制造商的ROM也可能适用于您的设备

事实上,这个“假象”正是我的问题所在。我去了那个网站,下载了最新的适合于我的卡型号的固件,然后,嘣!它就可以用了。 - Panayotis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接