PCI passthrough via OVMF

From ArchWiki
Revision as of 07:54, 21 February 2015 by Naruni (talk | contribs) (Created page with "THANKS to everyone who has contributed to this field. It's taken me 5 months to get it working, nothing compared to the hard work of many others. Those seriously dedicated to...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

THANKS to everyone who has contributed to this field. It's taken me 5 months to get it working, nothing compared to the hard work of many others. Those seriously dedicated to the cause will drink for free when I'm around. They have earned my gratitude.

How I got vfio working with gpu via ovmf:

Hardware: ASRock z97e-itx/ac, Intel 4790S, Gigabyte GeForce GTX 750

1. Ovmf binary from Gerd Hoffman's repo page: [1] I grabbed edk2.git-ovmf-x64-0-20150219.b876.g818bc86.noarch.rpm

Extract that file and throw into /usr, end up with /usr/share/edk2.git/ovmf-x64 containing a bunch of files.

2. QEMU & Libvirt:

pacman -S qemu libvirt ebtables dnsmasq bridge-utils virt-manager dmidecode

3. Libvirt bypass password: [2]

4. Start virtmanager & configure hypervisor: if virtmanager connects to the qemu session, all is good.

5. PCI-STUB & IOMMU: edit mkinitcpio.conf and include pci-stub in modules section. edit bootloader and add intel_iommu=on to kernel options. Check dmesg to confirm:

[********@orange_arch_kvm ~]$ dmesg|grep -e DMAR -e IOMMU
[    0.000000] ACPI: DMAR 0x00000000BDCB1CB0 0000B8 (v01 INTEL  BDW      00000001 INTL 00000001)
[    0.000000] Intel-IOMMU: enabled
[    0.028879] dmar: IOMMU 0: reg_base_addr fed90000 ver 1:0 cap c0000020660462 ecap f0101a
[    0.028883] dmar: IOMMU 1: reg_base_addr fed91000 ver 1:0 cap d2008c20660462 ecap f010da
[    0.028950] IOAPIC id 8 under DRHD base  0xfed91000 IOMMU 1
[    0.536212] DMAR: No ATSR found
[    0.536229] IOMMU 0 0xfed90000: using Queued invalidation
[    0.536230] IOMMU 1 0xfed91000: using Queued invalidation
[    0.536231] IOMMU: Setting RMRR:
[    0.536241] IOMMU: Setting identity map for device 0000:00:02.0 [0xbf000000 - 0xcf1fffff]
[    0.537490] IOMMU: Setting identity map for device 0000:00:14.0 [0xbdea8000 - 0xbdeb6fff]
[    0.537512] IOMMU: Setting identity map for device 0000:00:1a.0 [0xbdea8000 - 0xbdeb6fff]
[    0.537530] IOMMU: Setting identity map for device 0000:00:1d.0 [0xbdea8000 - 0xbdeb6fff]
[    0.537543] IOMMU: Prepare 0-16MiB unity mapping for LPC
[    0.537549] IOMMU: Setting identity map for device 0000:00:1f.0 [0x0 - 0xffffff]
[    2.182790] [drm] DMAR active, disabling use of stolen memory

6. vfio-bind the gpu: firewing1 webpage [3] Check the part just after grub2-mkconfig.

7. blacklist nouveau: or whatever else is getting in the way

[********@orange_arch_kvm ~]$ cat /etc/modprobe.d/modprobe.conf 
blacklist nouveau

8. ACL list & user config: [4] I only had to add /dev/vfio/1

9. Create/config VM for OVMF: Alex Williamson's blog: [5]

   <os>
   <loader readonly='yes' type='pflash'>/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd</loader>
   <nvram template='/usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd'>/var/lib/libvirt/qemu/nvram/win8.1_VARS.fd</nvram>

And

   <hyperv>
     <relaxed state='off'/>
     <vapic state='off'/>
     <spinlocks state='off'/>
   </hyperv>
   <kvm>
     <hidden state='on'/>
   </kvm>

And

   <clock>
   <timer name='hypervclock' present='no'/>

Towards the end (before </domain>

 <qemu:commandline>
   <qemu:arg value='-drive'/>
   <qemu:arg value='if=pflash,format=raw,readonly,file=/usr/share/edk2.git/ovmf-x64/OVMF-pure-efi.fd'/>
   <qemu:arg value='-cpu'/>                                                                            
   <qemu:arg value='host,kvm=off'/>                                                                    
 </qemu:commandline

10. boot/install win8.1, check device manager and see if graphics card (generic microsoft or something similar) has pci device id equal to your actual GPU (NVIDIA is 10de). Install nvidia drivers.