Advertisement
Guest User

vfio notes

a guest
Jul 16th, 2016
413
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.84 KB | None | 0 0
  1. ## VFIO from scratch
  2.  
  3. by https://www.reddit.com/user/Chapo_Rouge
  4.  
  5. *The goal of this document is to provide an up-to-date (July 2016) way to setup a VGA
  6. passthrough on QEMU/KVM with the help of VFIO on any Linux host.*
  7.  
  8. *This guide focus on Intel CPU and Nvidia GPU as I don't own another type of hardware, nevertheless, a good part of it is hardware agnostic.*
  9.  
  10. *This guide use the most recent KVM VGA passthrough method which is OVMF + vfio-pci (compared to Seabios + pci-stub) and requires a GPU with EFI ROM*
  11.  
  12. #### Hardware prerequisites :
  13.  
  14. + VT-x & VT-d enabled hardware (CPU + motherboard)
  15. + 2 GPU
  16. + (optional) coffee or cold beers
  17.  
  18. #### Software used :
  19.  
  20. Gentoo amd64, Linux kernel 4.6.x
  21. QEMU 2.5.1 + KVM
  22. virt-manager & libvirt
  23. OVMF (if using Windows >= 8.0)
  24.  
  25. ### Part 1 : Host system setup
  26.  
  27. #### Kernel configuration
  28. todo
  29.  
  30. CONFIG_VFIO_IOMMU_TYPE1=m
  31. CONFIG_VFIO=m
  32. CONFIG_VFIO_PCI=m
  33. CONFIG_INTEL_IOMMU=y
  34. CONFIG_IOMMU_HELPER=y
  35. CONFIG_VFIO=m
  36. CONFIG_IOMMU_API=y
  37. CONFIG_IOMMU_SUPPORT=y
  38. CONFIG_KVM_VFIO=y
  39.  
  40. #### Kernel boot options
  41.  
  42. edit `/etc/default/grub` and add to GRUB_CMDLINE_LINUX
  43.  
  44. intel_iommu=on
  45.  
  46. > not always needed ?
  47.  
  48. Then regenerate grub2 menu with
  49.  
  50. grub2-mkconfig -o /boot/grub/grub.cfg
  51.  
  52. or add the kernel option at boot time.
  53.  
  54. #### Check IOMMU groups
  55.  
  56. > This command should report the various IOMMU groups from your machine (An IOMMU group is the smallest set of physical devices that can be passed to a virtual machine.)
  57.  
  58. > if there's nothing it means IOMMU is not properly enabled.
  59.  
  60. #!/bin/bash
  61.  
  62. for iommu_group in $(find /sys/kernel/iommu_groups/ -maxdepth 1 -mindepth 1 -type d);
  63. do echo "IOMMU group $(basename "$iommu_group")";
  64. for device in $(ls -1 "$iommu_group"/devices/);
  65. do echo -n $'\t'; lspci -nns "$device";
  66. done;
  67. done
  68.  
  69. #### Isolating the GPU with vfio-pci
  70.  
  71. Get your vendor-id :
  72.  
  73. lspci | grep -i vga
  74.  
  75. > note down the first number, it is the slot number i.e 01:00.0
  76.  
  77. lspci -nns 01:00.0
  78.  
  79. > Note down the last number between "[]", this is the vendor-id, i.e 10de:1380
  80.  
  81. lspci -nnk -d vendor-id
  82.  
  83. Edit `/etc/modprobe.d/vfio.conf` with the vendor-id from your GPU you want to isolate gathered from the previous command, in this __example__, the vendor-id is __10de:13c2__ for the GPU and __10de:0fbb__ for the audio
  84.  
  85. options vfio-pci ids=10de:13c2,10de:0fbb
  86.  
  87. Add these modules to `/etc/conf.d/modules` (Gentoo/OpenRC specific)
  88.  
  89. modules="vfio vfio-pci vfio_iommu_type1 vfio_virqfd"
  90.  
  91. module loading at boot is enabled by
  92.  
  93. rc-update add modules boot
  94.  
  95. Reboot
  96.  
  97. #### Check that your GPU is correctly isolated :
  98.  
  99. $ dmesg | grep -i vfio
  100. [ 0.329224] VFIO - User Level meta-driver version: 0.3
  101. [ 0.341372] vfio_pci: add [10de:13c2[ffff:ffff]] class 0x000000/00000000 <-- Good
  102.  
  103. $ lspci -nnk -d <VENDOR_ID>
  104. Kernel driver in use: vfio-pci <-- Good
  105.  
  106. Same check for your sound card
  107.  
  108. If lspci -nnk -d reports a "Kernel driver in use" which is not vfio-pci, there's something wrong.
  109.  
  110. You can blacklist module loading by settings up the blacklist in /etc/modprobe.d/blacklist.conf
  111.  
  112. blacklist snd_hda_intel
  113.  
  114. Also check IOMMU & DMAR, output should contains :
  115.  
  116. dmesg | grep "IOMMU\|DMAR"
  117. [ 0.000000] ACPI: DMAR 0x00000000BD9373C0 000080 (v01 INTEL HSW 00000001 INTL 00000001)
  118. [ 0.019360] dmar: IOMMU 0: reg_base_addr fed90000 ver 1:0 cap d2008c20660462 ecap f010da
  119. [ 0.019362] IOAPIC id 8 under DRHD base 0xfed90000 IOMMU 0
  120. [ 0.292166] DMAR: No ATSR found
  121. [ 0.292235] IOMMU: dmar0 using Queued invalidation
  122. [ 0.292237] IOMMU: Setting RMRR:
  123. [ 0.292246] IOMMU: Setting identity map for device 0000:00:14.0 [0xbd8a6000 - 0xbd8b2fff]
  124. [ 0.292301] IOMMU: Prepare 0-16MiB unity mapping for LPC
  125. [ 0.292307] IOMMU: Setting identity map for device 0000:00:1f.0 [0x0 - 0xffffff]
  126.  
  127. #### Kernel modules (.ko)
  128.  
  129. Make sure these modules are present when you run lsmod
  130.  
  131. $ lsmod
  132. [...]
  133. vfio (?)
  134. vfio_iommu_type1 (?)
  135. kvm
  136. kvm_intel
  137. vfio-pci
  138. intel_iommu (?)
  139. [...]
  140.  
  141. #### QEMU / KVM / libvirt
  142.  
  143. Below example is for Gentoo & OpenRC, adjust for your distro.
  144.  
  145. # emerge --ask qemu virt-manager libvirt git
  146. # rc-update add libvirt-guests
  147. # service libvirt-guests start
  148. # service libvirtd start
  149.  
  150. #### OVMF setup
  151.  
  152. Get OVMF via https://www.kraxel.org/repos/jenkins/edk2/ and choose the
  153.  
  154. `edk2.git-ovmf-x64-[...] RPM.`
  155.  
  156. Unpack it and copy `OVMF-pure-efi.fd` and `OVMF_VARS-pure-efi.fd` to /usr/share/ovmf/x64/, creating the directory if needed.
  157.  
  158. Add this line to /etc/libvirt/qemu.conf :
  159.  
  160. nvram = [
  161. "/usr/share/ovmf/x64/ovmf_x64.bin:/usr/share/ovmf/x64/ovmf_vars_x64.bin"
  162. ]
  163.  
  164. Create a new machine with virt-manager and check "edit settings" before finishing the setup, change firmware from BIOS to UEFI (or to "Custom: /usr/share/ovmf/x64/ovmf_x64.bin") then boot the VM.
  165.  
  166. > If you're dropped to an EFI shell, make sure the ISO you wish to boot is correct, try with a recent Ubuntu release for instance.
  167.  
  168. #### Networking (Poor man's)
  169.  
  170. emerge bridge-utils
  171.  
  172. Create bridge :
  173.  
  174. brctl addbr br0
  175. brctl addif br0 eth0
  176. dhcpcd br0
  177.  
  178. Delete bridge :
  179.  
  180. ifconfig br0 down
  181. brctl delif br0 eth0
  182. brctl delbr br0
  183.  
  184. Add a network card on guest, attached to br0
  185.  
  186. #### Unhinge QEMU (needed ?) :
  187.  
  188. Ref : http://www.firewing1.com/howtos/fedora-20/create-gaming-virtual-machine-using-vfio-pci-passthrough-kvm
  189.  
  190. Because QEMU normally runs sandboxed, we need to 'unhinge' it and give it root privileges so it can control hardware.
  191.  
  192. In /etc/libvirt/qemu.conf, add:
  193.  
  194. user = "root"
  195. group = "root"
  196. clear_emulator_capabilities = 0
  197.  
  198. #### Common patches explained
  199.  
  200. __vgaarb__ aka __i915__ :
  201.  
  202. `x-vga=on`
  203. If OVMF : vgaarb is not needed
  204. If SeaBIOS : Requires vgaarb
  205.  
  206. __ACS Override__
  207.  
  208. If you find your PCI devices grouped among others that you do not wish to pass through, you may be able to seperate them using Alex Williamson ACS override patch.
  209.  
  210. ### Part 2 : Guest VM setup
  211.  
  212. The XML configuration of the VM is located at `/etc/libvirt/qemu`
  213.  
  214. #### Possible bugs :
  215.  
  216. + Nvidia Code 43 :
  217.  
  218. Recent nvidia drivers block the driver if it runs on top of an hypervisor, the workaround is to hide KVM :
  219.  
  220. via cli :
  221.  
  222. -cpu [type],kvm=off
  223.  
  224. via libvirt :
  225.  
  226. > edit your VM XML definition with virsh edit <VM_NAME>
  227.  
  228. <domain type='kvm'>
  229. ...
  230. <features>
  231. <kvm>
  232. <hidden state='on'/>
  233. </kvm>
  234. ...
  235. </features>
  236. </domain>
  237.  
  238.  
  239. ### Part 3 : Optimizations
  240.  
  241. Chipset : 440FX is ok
  242.  
  243. ### Appendices : Biblography
  244.  
  245. #### Online resources :
  246.  
  247. + https://www.reddit.com/r/VFIO
  248. + https://www.redhat.com/archives/vfio-users/
  249. + https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement