]>
Commit | Line | Data |
---|---|---|
0eb73424 AW |
1 | Intel Graphics Device (IGD) assignment with vfio-pci |
2 | ==================================================== | |
3 | ||
4 | IGD has two different modes for assignment using vfio-pci: | |
5 | ||
6 | 1) Universal Pass-Through (UPT) mode: | |
7 | ||
8 | In this mode the IGD device is added as a *secondary* (ie. non-primary) | |
9 | graphics device in combination with an emulated primary graphics device. | |
10 | This mode *requires* guest driver support to remove the external | |
11 | dependencies generally associated with IGD (see below). Those guest | |
12 | drivers only support this mode for Broadwell and newer IGD, according to | |
13 | Intel. Additionally, this mode by default, and as officially supported | |
14 | by Intel, does not support direct video output. The intention is to use | |
15 | this mode either to provide hardware acceleration to the emulated graphics | |
16 | or to use this mode in combination with guest-based remote access software, | |
17 | for example VNC (see below for optional output support). This mode | |
18 | theoretically has no device specific handling dependencies on vfio-pci or | |
19 | the VM firmware. | |
20 | ||
21 | 2) "Legacy" mode: | |
22 | ||
23 | In this mode the IGD device is intended to be the primary and exclusive | |
24 | graphics device in the VM[1], as such QEMU does not facilitate any sort | |
25 | of remote graphics to the VM in this mode. A connected physical monitor | |
26 | is the intended output device for IGD. This mode includes several | |
27 | requirements and restrictions: | |
28 | ||
29 | * IGD must be given address 02.0 on the PCI root bus in the VM | |
30 | * The host kernel must support vfio extensions for IGD (v4.6) | |
31 | * vfio VGA support very likely needs to be enabled in the host kernel | |
32 | * The VM firmware must support specific fw_cfg enablers for IGD | |
33 | * The VM machine type must support a PCI host bridge at 00.0 (standard) | |
34 | * The VM machine type must provide or allow to be created a special | |
35 | ISA/LPC bridge device (vfio-pci-igd-lpc-bridge) on the root bus at | |
36 | PCI address 1f.0. | |
37 | * The IGD device must have a VGA ROM, either provided via the romfile | |
38 | option or loaded automatically through vfio (standard). rombar=0 | |
39 | will disable legacy mode support. | |
40 | * Hotplug of the IGD device is not supported. | |
41 | * The IGD device must be a SandyBridge or newer model device. | |
42 | ||
43 | For either mode, depending on the host kernel, the i915 driver in the host | |
44 | may generate faults and errors upon re-binding to an IGD device after it | |
45 | has been assigned to a VM. It's therefore generally recommended to prevent | |
46 | such driver binding unless the host driver is known to work well for this. | |
47 | There are numerous ways to do this, i915 can be blacklisted on the host, | |
48 | the driver_override option can be used to ensure that only vfio-pci can bind | |
49 | to the device on the host[2], virsh nodedev-detach can be used to bind the | |
50 | device to vfio drivers and then managed='no' set in the VM xml to prevent | |
51 | re-binding to i915, etc. Also note that IGD is also typically the primary | |
52 | graphics in the host and special options may be required beyond simply | |
53 | blacklisting i915 or using pci-stub/vfio-pci to take ownership of IGD as a | |
54 | PCI class device. Lower level drivers exist that may still claim the device. | |
55 | It may therefore be necessary to use kernel boot options video=vesafb:off or | |
56 | video=efifb:off (depending on host BIOS/UEFI) or these can be combined to | |
57 | a catch-all, video=vesafb:off,efifb:off. Error messages such as: | |
58 | ||
59 | Failed to mmap 0000:00:02.0 BAR <>. Performance may be slow | |
60 | ||
61 | are a good indicator that such a problem exists. The host files /proc/iomem | |
62 | and /proc/ioports are often useful for identifying drivers consuming ranges | |
63 | of the device to cause such conflicts. | |
64 | ||
65 | Additionally, IGD device are known to generate small numbers of DMAR faults | |
66 | when initially assigned. It is believed that this is simply the IGD attempting | |
67 | to access the reserved GTT space after reset, which it no longer has access to | |
68 | when accessed from userspace. So long as the DMAR faults are small in number | |
69 | and most importantly, not ongoing, these are not an indication of an error. | |
70 | ||
71 | Additionally++, analog VGA output (as opposed to digital outputs like HDMI, | |
72 | DVI, or DisplayPort) may be unsupported in some use cases. In the author's | |
73 | experience, even DP to VGA adapters can be troublesome while adapters between | |
74 | digital formats work well. | |
75 | ||
76 | Usage | |
77 | ===== | |
78 | The intention is for IGD assignment to be transparent for users and thus for | |
79 | management tools like libvirt. To make use of legacy mode, simply remove all | |
80 | other graphics options and use "-nographic" and either "-vga none" or | |
81 | "-nodefaults", along with adding the device using vfio-pci: | |
82 | ||
83 | -device vfio-pci,host=00:02.0,id=hostdev0,bus=pci.0,addr=0x2 | |
84 | ||
85 | For UPT mode, retain the default emulated graphics and simply add the vfio-pci | |
86 | device making use of any other bus address other than 02.0. libvirt will | |
87 | default to assigning the device a UPT compatible address while legacy mode | |
88 | users will need to manually edit the XML if using a tool like virt-manager | |
89 | where the VM device address is not expressly specified. | |
90 | ||
91 | An experimental vfio-pci option also exists to enable OpRegion, and thus | |
92 | external monitor support, for UPT mode. This can be enabled by adding | |
93 | "x-igd-opregion=on" to the vfio-pci device options for the IGD device. As | |
94 | with legacy mode, this requires the host to support features introduced in | |
95 | the v4.6 kernel. If Intel chooses to embrace this support, the option may | |
96 | be made non-experimental in the future, opening it to libvirt support. | |
97 | ||
98 | Developer ABI | |
99 | ============= | |
100 | Legacy mode IGD support imposes two fw_cfg requirements on the VM firmware: | |
101 | ||
102 | 1) "etc/igd-opregion" | |
103 | ||
104 | This fw_cfg file exposes the OpRegion for the IGD device. A reserved | |
105 | region should be created below 4GB (recommended 4KB alignment), sized | |
106 | sufficient for the fw_cfg file size, and the content of this file copied | |
107 | to it. The dword based address of this reserved memory region must also | |
108 | be written to the ASLS register at offset 0xFC on the IGD device. It is | |
109 | recommended that firmware should make use of this fw_cfg entry for any | |
110 | PCI class VGA device with Intel vendor ID. Multiple of such devices | |
111 | within a VM is undefined. | |
112 | ||
113 | 2) "etc/igd-bdsm-size" | |
114 | ||
115 | This fw_cfg file contains an 8-byte, little endian integer indicating | |
116 | the size of the reserved memory region required for IGD stolen memory. | |
117 | Firmware must allocate a reserved memory below 4GB with required 1MB | |
118 | alignment equal to this size. Additionally the base address of this | |
119 | reserved region must be written to the dword BDSM register in PCI config | |
120 | space of the IGD device at offset 0x5C. As this support is related to | |
121 | running the IGD ROM, which has other dependencies on the device appearing | |
122 | at guest address 00:02.0, it's expected that this fw_cfg file is only | |
123 | relevant to a single PCI class VGA device with Intel vendor ID, appearing | |
124 | at PCI bus address 00:02.0. | |
125 | ||
126 | Footnotes | |
127 | ========= | |
128 | [1] Nothing precludes adding additional emulated or assigned graphics devices | |
129 | as non-primary, other than the combination typically not working. I only | |
130 | intend to set user expectations, others are welcome to find working | |
131 | combinations or fix whatever issues prevent this from working in the common | |
132 | case. | |
133 | [2] # echo "vfio-pci" > /sys/bus/pci/devices/0000:00:02.0/driver_override |