Nvidia GPU 直通失败,代码为 43
Nvidia GPU passthrough fail with code 43
我目前正在尝试使用 qemu 2.5 和 libvirt 1.3.5 将 nvidia GPU 传递给 Windows 10 个来宾。
我在设备管理器的 Nvidia GPU 上看到 "Error 43"。
我曾尝试通过添加 "kvm=off" 和 "hv_vendor_id=123456780ab" 来隐藏管理程序,但它对我不起作用。我在 google 中搜索,人们用这种方式解决了问题。
而且我还在任务管理器中看到虚拟机:是。
我是不是用错了?我可以将 AMD gpu 传递给 windows guest(AMD 不检查 kvm 虚拟化)。
我可以用其他方式欺骗 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
显卡:
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
期待您的帮助!
您需要将未修改的显卡 ROM 副本传递给 VM。
- 您需要一个可以用作主 GPU 的辅助 GPU
过程。 如果没有
直通 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 启动卡,而不是内核提供的任何内容。
请注意,您必须使用 OVMF (EFI),因为 SeaBIOS 无法正确使用卡 ROM。
如果您使用的是 OVMF 或其他一些 UEFI,请务必三重检查您的卡是否支持 UEFI,尤其是在 ~2014 之前的东西上。
我误以为我的是(GTX 770),而实际上它不是(在线查看了错误版本的ROM)并且浪费了将近2天的时间来扯掉我的头发。查找 UEFI 支持 like so and look for ROM updates here。
我刷了我的卡,但我认为你可以把一个支持 UEFI 的 ROM 作为 romfile=
。似乎 other manufacturers' ROMs could work too,如果您的系统没有适合您的 UEFI 修复程序。
我目前正在尝试使用 qemu 2.5 和 libvirt 1.3.5 将 nvidia GPU 传递给 Windows 10 个来宾。
我在设备管理器的 Nvidia GPU 上看到 "Error 43"。
我曾尝试通过添加 "kvm=off" 和 "hv_vendor_id=123456780ab" 来隐藏管理程序,但它对我不起作用。我在 google 中搜索,人们用这种方式解决了问题。
而且我还在任务管理器中看到虚拟机:是。
我是不是用错了?我可以将 AMD gpu 传递给 windows guest(AMD 不检查 kvm 虚拟化)。
我可以用其他方式欺骗 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
显卡:
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
期待您的帮助!
您需要将未修改的显卡 ROM 副本传递给 VM。
- 您需要一个可以用作主 GPU 的辅助 GPU
过程。 如果没有 直通 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 启动卡,而不是内核提供的任何内容。
请注意,您必须使用 OVMF (EFI),因为 SeaBIOS 无法正确使用卡 ROM。
如果您使用的是 OVMF 或其他一些 UEFI,请务必三重检查您的卡是否支持 UEFI,尤其是在 ~2014 之前的东西上。
我误以为我的是(GTX 770),而实际上它不是(在线查看了错误版本的ROM)并且浪费了将近2天的时间来扯掉我的头发。查找 UEFI 支持 like so and look for ROM updates here。
我刷了我的卡,但我认为你可以把一个支持 UEFI 的 ROM 作为 romfile=
。似乎 other manufacturers' ROMs could work too,如果您的系统没有适合您的 UEFI 修复程序。