Nvidia GPU passthrough失败,代码为43

时间:2016-12-28 13:19:41

标签: gpu nvidia kvm vfio

我正在尝试使用qemu 2.5和libvirt 1.3.5将nvidia GPU传递给Windows 10来宾。

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

我曾尝试通过添加“kvm = off”和“hv_vendor_id = 123456780ab”来隐藏虚拟机管理程序,但它对我不起作用。我在谷歌搜索,人们用这种方式解决了问题。

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

  1. 我用错了吗?我可以将AMD gpu传递给windows guest(AMD不检查kvm虚拟化)。

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

  3. 我的系统信息:

    #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 个答案:

答案 0 :(得分:5)

您需要将未修改的视频卡ROM的副本传递给VM。

  • 您需要一个辅助GPU,您可以将其作为此主要用途 处理。 如果没有,则无法转储BIOS的干净副本 将GPU作为辅助卡
  • 将额外的卡放入主插槽,将预期的直通卡放入另一个pci-e端口并启动。
  • 通过lspci -v再次找到您想要的GPU。就我而言,它的地址大致相同。
  • 现在您可以将ROM转储到文件中:

    # 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
    

    在这种情况下,0000:05:00.0是我的PCI卡地址。你真的不需要底部的绑定步骤,因为你无论如何都要重启。

  • 您可以使用https://github.com/awilliam/rom-parser上的此便捷实用程序检查ROM转储的完整性。我的rom看起来像:

    # ./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
    

    转储中应该同时具有EFI和非EFI x86 ROM(我认为大多数卡都有)

  • 关闭机器并将GTX 1070放回主插槽。
  • 启动后,编辑VM xml,并在GPU的部分中(如果您已将GPU分配给VM),应该有一个部分。向其中添加file ='path / to / dump / here'语句。我的完整部分如下:

    <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>
    

    这将让VM使用该BIOS启动卡,而不是内核提供的卡。

source

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

答案 1 :(得分:1)

如果您使用的是OVMF或其他UEFI,请务必三重检查您的卡是否已准备好UEFI,尤其是对于早于2014年的内容。

我的错误印象是我的(GTX 770),而事实上,它不是(在线查看错误版本的ROM)并且浪费了将近2天的时间。查找UEFI支持like so并查找ROM更新here

我刷了我的卡,但我认为你可以将支持UEFI的ROM设为romfile=。看来other manufacturers' ROMs could work too,如果您没有为您修复UEFI。