Laptop VFIO - "NVIDIA driver not compatiable with this version of Windows"

Hi!
I’ve been trying to passthrough my dGPU on my Optimus laptop, mostly following the Arch wiki on PCI passthrough. I’ve successfully followed the steps up until attaching PCI as a device in Virtual Machine Manager.

My hardware is:

  • Lenovo Legion Y520 Laptop
  • dGPU: GTX 1060M 3GB
  • iGPU: Intel HD 630
  • CPU: i5-7300HQ

lspci output shows:

00:02.0 VGA compatible controller [0300]: Intel Corporation HD Graphics 630 [8086:591b] (rev 04) (prog-if 00 [VGA controller])
        Subsystem: Lenovo Device [17aa:39b9]
        Flags: bus master, fast devsel, latency 0, IRQ 135, IOMMU group 2
        Memory at a2000000 (64-bit, non-prefetchable) [size=16M]
        Memory at b0000000 (64-bit, prefetchable) [size=256M]
        I/O ports at 6000 [size=64]
        Expansion ROM at 000c0000 [virtual] [disabled] [size=128K]
        Capabilities: <access denied>
        Kernel driver in use: i915
        Kernel modules: i915

01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP106M [GeForce GTX 1060 Mobile] [10de:1c20] (rev a1) (prog-if 00 [VGA controller])
        Flags: bus master, fast devsel, latency 0, IRQ 16, IOMMU group 1
        Memory at a3000000 (32-bit, non-prefetchable) [size=16M]
        Memory at 90000000 (64-bit, prefetchable) [size=256M]
        Memory at a0000000 (64-bit, prefetchable) [size=32M]
        I/O ports at 5000 [size=128]
        Expansion ROM at a4080000 [disabled] [size=512K]
        Capabilities: <access denied>
        Kernel driver in use: vfio-pci
        Kernel modules: nouveau, nvidia_drm, nvidia

I pass through 01:00.0 which shows up in the Windows VM as a VGA controller. However when trying to install the NVIDIA drivers, I get the error message “NVIDIA drriver not compatiable with this version of Windows”. I’ve double checked that I’m running 64-bit os, and installing 64-bit driver. I’ve also installed the virtio win drivers.

Not sure if this has anything to do with my graphics driver problem, but one thing I’ve noticed is that I don’t see the audio device 01:00.01 from lspci. I can see in dmesg that the Audio device is being added to group 1, but then removed again:

$ sudo dmesg | grep iommu
[    0.036552] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-5.9-x86_64 root=UUID=b64353b7-ff47-4ac3-b772-3ae66b683103 rw quiet apparmor=1 security=apparmor resume=UUID=dfcda415-768c-4208-b7c0-4cd0a2a2364a udev.log_priority=3 intel_iommu=on iommu=pt vfio-pci.ids=10de:1c20,8086:1901
[    0.231187] iommu: Default domain type: Passthrough (set via kernel command line)
[    0.432813] pci 0000:00:00.0: Adding to iommu group 0
[    0.432827] pci 0000:00:01.0: Adding to iommu group 1
[    0.432836] pci 0000:00:02.0: Adding to iommu group 2
[    0.432851] pci 0000:00:14.0: Adding to iommu group 3
[    0.432859] pci 0000:00:14.2: Adding to iommu group 3
[    0.432870] pci 0000:00:16.0: Adding to iommu group 4
[    0.432879] pci 0000:00:17.0: Adding to iommu group 5
[    0.432890] pci 0000:00:1c.0: Adding to iommu group 6
[    0.432901] pci 0000:00:1c.3: Adding to iommu group 7
[    0.432911] pci 0000:00:1d.0: Adding to iommu group 8
[    0.432934] pci 0000:00:1f.0: Adding to iommu group 9
[    0.432943] pci 0000:00:1f.2: Adding to iommu group 9
[    0.432952] pci 0000:00:1f.3: Adding to iommu group 9
[    0.432961] pci 0000:00:1f.4: Adding to iommu group 9
[    0.432965] pci 0000:01:00.0: Adding to iommu group 1
[    0.432968] pci 0000:01:00.1: Adding to iommu group 1
[    0.433021] pci 0000:02:00.0: Adding to iommu group 10
[    0.433031] pci 0000:03:00.0: Adding to iommu group 11
[    0.433041] pci 0000:04:00.0: Adding to iommu group 12
[    0.918329]     intel_iommu=on
[    2.089138] pci 0000:01:00.1: Removing from iommu group 1

Not sure if the audio device has anything to do with my graphics driver problems though…

This is my current libvirt config. My plan was to get the GPU working, and then moving on to optimizing the settings, removing anything unnecessary devices and pinning CPUs etc:

<domain type="kvm">
  <name>win10</name>
  <uuid>aa940b56-87b9-44ba-8c6f-1ab268f23d58</uuid>
  <metadata>
    <libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
      <libosinfo:os id="http://microsoft.com/win/10"/>
    </libosinfo:libosinfo>
  </metadata>
  <memory unit="KiB">4194304</memory>
  <currentMemory unit="KiB">4194304</currentMemory>
  <vcpu placement="static">2</vcpu>
  <os>
    <type arch="x86_64" machine="pc-q35-5.1">hvm</type>
    <loader readonly="yes" type="pflash">/usr/share/edk2-ovmf/x64/OVMF_CODE.fd</loader>
    <nvram>/var/lib/libvirt/qemu/nvram/win10_VARS.fd</nvram>
    <boot dev="hd"/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
      <vendor_id state="on" value="randomid"/>
    </hyperv>
    <kvm>
      <hidden state="on"/>
    </kvm>
    <vmport state="off"/>
  </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/win10.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="/home/d/Downloads/Win10_20H2_v2_English_x64.iso"/>
      <target dev="sdb" bus="sata"/>
      <readonly/>
      <address type="drive" controller="0" bus="0" target="0" unit="1"/>
    </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="sata" index="0">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x1f" function="0x2"/>
    </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-to-pci-bridge">
      <model name="pcie-pci-bridge"/>
      <address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
    </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:6c:09:ac"/>
      <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" autoport="yes" listen="127.0.0.1">
      <listen type="address" address="127.0.0.1"/>
      <image compression="off"/>
    </graphics>
    <sound model="ich9">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x1b" function="0x0"/>
    </sound>
    <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="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
    </hostdev>
    <redirdev bus="usb" type="spicevmc">
      <address type="usb" bus="0" port="2"/>
    </redirdev>
    <redirdev bus="usb" type="spicevmc">
      <address type="usb" bus="0" port="3"/>
    </redirdev>
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
    </memballoon>
    <shmem name="looking-glass">
      <model type="ivshmem-plain"/>
      <size unit="M">32</size>
      <address type="pci" domain="0x0000" bus="0x07" slot="0x01" function="0x0"/>
    </shmem>
  </devices>
</domain>

I’ve understood that laptops are a bit trickier than desktops, but I haven’t completely understood why. So it may very well be that I’m getting my driver install failures because I’ve miss understood something basic… I just thought I’d get my hands dirty and learn as I go (with a bit of help from knowledgeable people).

Thanks in advance!