QEMU passthrough - GPU showing error 43 in guest

Update ii 04.08. : After updating kernel(so effing easy today … click… :exploding_head:) it took me about 30 minutes to get it running with the instructions in the arch wiki :partying_face:

Update 04.08.2025 : Just came across this (no point trying until kernel is update):
https://www.reddit.com/r/VFIO/comments/1ma1gk1/error_43_after_libvirtqemu_update_nvidia/

Some notes:

Placing the VM file on an NTFS partition because that’s where space is available should be avoided. At some point funky permission problems arise.

Using HDMI or Display Port can make a difference. For some only one works. For some it only works if a monitor is connected for the guest after guest has booted.

There is a HUGE difference in performance between qcow2 and RAW on HDDs

Hello

Summary:

  • Host uses iGPU from an i7-9700k
  • An RTX 3070 on the system is using vfio-pci and not in use by the host.
  • The RTX 3070 has been made available to a Windows 11 guest as a PCI device in QEMU.
  • NVIDIA driver installation under Windows guest successful.
  • However the GPU shows correctly named with error 43 in the guest’s device manager.
Long version

I felt tremendous success when finally I saw this under the GPU:

“Kernel driver in use: vfio-pci”.

But that was killed a few minutes later by error 43 in the guest.

From what I read, the error used to be caused by a missing function in the nvidia drivers which has since become available.

For the GPU isolation I looked at various tutorials and what some scripts did.(One killed my installation)

My last attempt was first going through the Virt-manager steps in the Wiki on a freshly installed system. Then ‘upgrading’ that with everything from SysGuides (How Do I Properly Install KVM on Linux (2024)) except for bridged networking.

A fresh install of a Windows guest (again following tips from SysGuides) then resulted in a more responsive VM, but the error with GPU passthrough remains.

I’ve also dumped the ROM and added that to the corresponding XML configuration in QEMU. Just like adding the now obsolete lines for vendor ID and hiding in the main config XML… no luck.

Host is using the IGPU of an i7-9700k and for the guest I want to make an RTX 3070 available.

I’m using GRUB (most systems in tutorials and instructions appear to be).

Both outputs go to the same monitor and for now I’ll be happy to switch inputs as needed. I’ll look at the other things allowing for a more seamless integration, including proper passthrough of USB after the GPU is working. Main thing is having the processing power available.

Many thanks in advance.

Every step along the way,
starting with the first,
has been verified?

https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF

https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF/Examples

I would like to do it - but my laptop, my hardware, just can’t do it. :man_shrugging:

Thank you. Yes, I visited this page many times during recent days. Without what is described there the RTX wouldn’t be using the vfio-pci driver and likely not show correctly named in the guest.

I’ve seen the page with the examples too, but did not gain any useful information from there. One user has the same GPU but nothing related to what I encounter.

I got excited with some progress last night but started using nano to edit files I’m not really familiar with yet… restored a backup of a fresh installation.

Why I got excited(late night reading so I can’t find all of the sources):

Apparently some people become cable plugging ninjas to make it work. I can’t recall which combination triggered it, however:

at some point the GPU output the first screen and froze that, whilst the VM booted and was working in a window via the iGPU output the host is using.

I had been using Display Port from the GPU, and HDMI from the iGPU. The other way around gave me the above (I miss days when ports just output their thing and you could fry a printer by plugging it in to the scanner interface. :grin:)

So obviously it briefly works then stops. Searched for scripts for binding and releasing for single GPU pass-through and used from here:

https://github.com/martinopiaggi/Single-GPU-Passthrough-for-Dummies

… and I got the Windows 11 login screen via the RTX. However, I still needed to pass-through input devices.

This looked like what I needed to do:

https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Passing_keyboard/mouse_via_Evdev

But I ran into permission errors.*

At some point I messed something up when editing with nano whilst going through permission troubleshooting as described here:

https://passthroughpo.st/using-evdev-passthrough-seamless-vm-input/

So today I’ll start again and stick a note on my screen “Tired eyes? nano, no no!!!”

*Permission errors related to VM being on an ntfs disk

All of my data disks are still ntfs… so I expected problems and figured deal with them as they arise until I can get storage to do the transfers.

I have been warned for decades to avoid ntfs when running Linux. However … and if it’s just single user accessing simple files it works well. But:

before I create a new VM, I’ll partition one of the drives to create one in ext4 to avoid running into those issues. I’m aware that there are solutions to manage the permissions for ntfs under Linux like under Windows, but no long term interest in that. It would feel like asking for more pain.

Right now it’s about having Windows with processing power of the GPU for photography tools available when I need it. I have two commercial (non-subscription) tools for which there are simply no alternatives. The companies are too small for a Linux port.

i can help you with the passthrough of usb mouse and keyboard to a win11 guest.
I’m using it because there is no other way to fully configure my razer mouse and steelseries keyboard.

The downside of it is, that you need a second pair of mouse and keyboard.

i will try to find the source of it again, but here’s the code:
you will need a script to attach and another to detach
and an .xml for each device with vendor and product id.
I not sure about the changes to the VM config, but i think i added an usb device.

file input_attach.sh

#!/bin/sh

virsh attach-device win11 /home/xxx/.VFIOinput/razer_1.xml
virsh attach-device win11 /home/xxx/.VFIOinput/steelseries_1.xml 

file input_detach.sh

#!/bin/sh

virsh detach-device win11 /home/xxx/.VFIOinput/razer_1.xml
virsh detach-device win11 /home/xxx/.VFIOinput/steelseries_1.xml

razer_1.xml

<hostdev mode='subsystem' type='usb'>
<source>
<vendor id='0x1532'/>
<product id='0x0099'/>
</source>
</hostdev>

steelseries_1.xml

<hostdev mode='subsystem' type='usb'>
<source>
<vendor id='0x1038'/>
<product id='0x1640'/>
</source>
</hostdev>

here’s my config of the VM:

<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
  virsh edit win11
or other application using the libvirt API.
-->

<domain type='kvm'>
  <name>win11</name>
  <uuid>ea017815-d7ff-4ca8-a689-2b79c4756304</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://microsoft.com/win/11"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory unit='KiB'>8388608</memory>
  <currentMemory unit='KiB'>8388608</currentMemory>
  <vcpu placement='static'>4</vcpu>
  <os firmware='efi'>
    <type arch='x86_64' machine='pc-q35-9.2'>hvm</type>
    <firmware>
      <feature enabled='no' name='enrolled-keys'/>
      <feature enabled='yes' name='secure-boot'/>
    </firmware>
    <loader readonly='yes' secure='yes' type='pflash' format='raw'>/usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd</loader>
    <nvram template='/usr/share/edk2/x64/OVMF_VARS.4m.fd' templateFormat='raw' format='raw'>/var/lib/libvirt/qemu/nvram/win11_VARS.fd</nvram>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv mode='custom'>
      <relaxed state='on'/>
      <vapic state='on'/>
      <spinlocks state='on' retries='8191'/>
      <vpindex state='on'/>
      <runtime state='on'/>
      <synic state='on'/>
      <stimer state='on'/>
      <frequencies state='on'/>
      <tlbflush state='on'/>
      <ipi state='on'/>
      <avic state='on'/>
    </hyperv>
    <vmport state='off'/>
    <smm state='on'/>
  </features>
  <cpu mode='host-passthrough' check='none' migratable='on'/>
  <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>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/WinDev2407Eval-disk001.qcow2'/>
      <target dev='sda' bus='sata'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/virtio-win-0.1.271.iso'/>
      <target dev='sdc' bus='sata'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='2'/>
    </disk>
    <controller type='usb' index='0' model='qemu-xhci' ports='15'>
      <address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
    </controller>
    <controller type='pci' index='0' model='pcie-root'/>
    <controller type='pci' index='1' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='1' port='0x10'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
    </controller>
    <controller type='pci' index='2' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='2' port='0x11'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
    </controller>
    <controller type='pci' index='3' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='3' port='0x12'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
    </controller>
    <controller type='pci' index='4' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='4' port='0x13'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
    </controller>
    <controller type='pci' index='5' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='5' port='0x14'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
    </controller>
    <controller type='pci' index='6' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='6' port='0x15'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
    </controller>
    <controller type='pci' index='7' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='7' port='0x16'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
    </controller>
    <controller type='pci' index='8' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='8' port='0x17'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
    </controller>
    <controller type='pci' index='9' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='9' port='0x18'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='on'/>
    </controller>
    <controller type='pci' index='10' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='10' port='0x19'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
    </controller>
    <controller type='pci' index='11' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='11' port='0x1a'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/>
    </controller>
    <controller type='pci' index='12' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='12' port='0x1b'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/>
    </controller>
    <controller type='pci' index='13' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='13' port='0x1c'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/>
    </controller>
    <controller type='pci' index='14' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='14' port='0x1d'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/>
    </controller>
    <controller type='sata' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
    </controller>
    <controller type='virtio-serial' index='0'>
      <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
    </controller>
    <interface type='network'>
      <mac address='52:54:00:2f:38:c1'/>
      <source network='default'/>
      <model type='e1000e'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='spice'>
      <listen type='none'/>
      <image compression='off'/>
    </graphics>
    <sound model='ich9'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1b' function='0x0'/>
    </sound>
    <audio id='1' type='spice'/>
    <video>
      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
    </video>
    <hostdev mode='subsystem' type='usb' managed='yes'>
      <source>
        <vendor id='0x1532'/>
        <product id='0x0099'/>
      </source>
      <address type='usb' bus='0' port='4'/>
    </hostdev>
    <hostdev mode='subsystem' type='usb' managed='yes'>
      <source>
        <vendor id='0x1038'/>
        <product id='0x1640'/>
      </source>
      <address type='usb' bus='0' port='5'/>
    </hostdev>
    <watchdog model='itco' action='reset'/>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
    </memballoon>
  </devices>
</domain>

PS: i found the source
6.4 Swap peripherals to and from the Host

Hey thanks for all that @AlexBoldt. And at this opportunity also thanks again @Nachlese.

Thank you for sharing the config XML. I noticed two differences to mine (aside from folder names). One are some settings under hypery and the other is your USB passthrough.

For hyperv I have this enabled:
https://www.qemu.org/docs/master/system/i386/hyperv.html

Some maybe useless info re the USB passthrough, I had read that you can also use bus and device ID instead of vendor and product ID. So instead of:

<source>
        <vendor id='0x1038'/>
        <product id='0x1640'/>
</source>

you could use something like (if two devices happen to share vendor and product ID)

<source>
        <address bus='8' device='1'/>
</source>

My hardware should really not be the issue. It is more a matter of my (lack of) understanding things. As I mentioned my last attempt failed due to being sloppy whilst I should be in learning mode.

I do have enough mice and keyboards, but I also have an input switch somewhere.

What I’ll do in the long run is passthrough a usb hub and use the switch to toggle between inputs on the PC. But I need to learn how to do that too (plenty of information available).

But all that only matters if I get the GPU passed through. I don’t mind input lag. I just want things to be fast when I finished editing and hit export.

Yesterday a trip to the attic yielded one old HDMI cable and a 150GB SATA HDD. It still had my first install of Windows 10 (it was first in an XP system).

I think it is advisable to do everything with HDMI as opposed to Display Port. Display Port makes devices talk more.

More talk...

…introduces more vectors for misunderstanding. Which is not so bad if you understand the language and have a good vocabulary. But when you’re like tourist who’s just able to order food and drinks, it’s entertaining but often not productive.

Right now I’m like a tourist at his regular place where he never bothered to really learn the language apart from what was needed and decided to start living there.

I am for the first time seeing the downside of using a older HDMI cable version that is also very long. Currently the RTX 3070 is the second GPU of the host.

Both iGPU and and RTX are connected to the same monitor. The RTX shows some pixel flickering. This does not happen when Manjaro is output through the RTX via display port or a newer HDMI cable.

One thing I hadn’t done was this (not a mobile GPU):
https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#%22Error_43:_Driver_failed_to_load%22_with_mobile_(Optimus/max-q)_nvidia_GPUs

However I get this in the QEMU log:
qemu-system-x86_64: -acpitable file=/usr/.../SSDT1.dat: warning: ACPI table has wrong length, header says 827664160, actual size 250 bytes

The things is it refers to a 6 year old reddit thread as the source that has not been updated in 5. All comments were basically just “cool thanks”… not one with the same problem so I’m thinking I should be doing something different in 2025 and the kernel in use.

ARCH wiki is considered to be the best. I’ve used it for reference when using other distros. But I’m taking it with a pinch of salt from now on. Manjaro Wiki also really needs some updating.

I’m going through my notes again (essentially like one of the github tutorials) and starting to add comments in the files I create. In the past I would have abndoned again at this stage, especially as the last 30 years it was always something related to GPU output. But my deadline to have everything working with Linux as a base is Windows 10 EOL. I should be able to get this working in 3 months.

@AlexBoldt I setup my mouse kbd passthough so that I can use CTRL+CTRL to switch (it actually works and I can do things in the windows VM - albeit without seeing anything). I found the base for the instructions here: https://passthroughpo.st/using-evdev-passthrough-seamless-vm-input/ (current instruction are in the arch wiki https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Passing_keyboard/mouse_via_Evdev)

1 Like

According to a thread that was started on r/vfio 3 days before I started trying to setup, some have had issue with kernel 6.12.39-1 (current for Manjaro). Error 43 appeared on previously working setups.

Update to kernel 6.15.7-1 for example fixed it.

At least one Debian and one other Manjaro user with the problem.

So basically I picked a bad week to start :smiley:

Or a good one actually… lot’s of learning.

So I’ll just wait until Manjaro kernel is updated before trying again. (or go look how to update kernel now)

(I did have it working once… downloaded driver under windows… thought better backup before installing… shutdown… same error).

Added solved to subject. Issue was resolved with kernel update.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.