]>
Commit | Line | Data |
---|---|---|
29d62771 TH |
1 | /* |
2 | * IGD device quirks | |
3 | * | |
4 | * Copyright Red Hat, Inc. 2016 | |
5 | * | |
6 | * Authors: | |
7 | * Alex Williamson <[email protected]> | |
8 | * | |
9 | * This work is licensed under the terms of the GNU GPL, version 2. See | |
10 | * the COPYING file in the top-level directory. | |
11 | */ | |
12 | ||
13 | #include "qemu/osdep.h" | |
14 | #include "qemu/units.h" | |
15 | #include "qapi/error.h" | |
16 | #include "hw/hw.h" | |
17 | #include "hw/nvram/fw_cfg.h" | |
18 | #include "pci.h" | |
19 | #include "trace.h" | |
20 | ||
21 | /* | |
22 | * Intel IGD support | |
23 | * | |
24 | * Obviously IGD is not a discrete device, this is evidenced not only by it | |
25 | * being integrated into the CPU, but by the various chipset and BIOS | |
26 | * dependencies that it brings along with it. Intel is trying to move away | |
27 | * from this and Broadwell and newer devices can run in what Intel calls | |
28 | * "Universal Pass-Through" mode, or UPT. Theoretically in UPT mode, nothing | |
29 | * more is required beyond assigning the IGD device to a VM. There are | |
30 | * however support limitations to this mode. It only supports IGD as a | |
31 | * secondary graphics device in the VM and it doesn't officially support any | |
32 | * physical outputs. | |
33 | * | |
34 | * The code here attempts to enable what we'll call legacy mode assignment, | |
35 | * IGD retains most of the capabilities we expect for it to have on bare | |
36 | * metal. To enable this mode, the IGD device must be assigned to the VM | |
37 | * at PCI address 00:02.0, it must have a ROM, it very likely needs VGA | |
38 | * support, we must have VM BIOS support for reserving and populating some | |
39 | * of the required tables, and we need to tweak the chipset with revisions | |
40 | * and IDs and an LPC/ISA bridge device. The intention is to make all of | |
41 | * this happen automatically by installing the device at the correct VM PCI | |
42 | * bus address. If any of the conditions are not met, we cross our fingers | |
43 | * and hope the user knows better. | |
44 | * | |
45 | * NB - It is possible to enable physical outputs in UPT mode by supplying | |
46 | * an OpRegion table. We don't do this by default because the guest driver | |
47 | * behaves differently if an OpRegion is provided and no monitor is attached | |
48 | * vs no OpRegion and a monitor being attached or not. Effectively, if a | |
49 | * headless setup is desired, the OpRegion gets in the way of that. | |
50 | */ | |
51 | ||
52 | /* | |
53 | * This presumes the device is already known to be an Intel VGA device, so we | |
54 | * take liberties in which device ID bits match which generation. This should | |
55 | * not be taken as an indication that all the devices are supported, or even | |
56 | * supportable, some of them don't even support VT-d. | |
57 | * See linux:include/drm/i915_pciids.h for IDs. | |
58 | */ | |
59 | static int igd_gen(VFIOPCIDevice *vdev) | |
60 | { | |
61 | if ((vdev->device_id & 0xfff) == 0xa84) { | |
62 | return 8; /* Broxton */ | |
63 | } | |
64 | ||
65 | switch (vdev->device_id & 0xff00) { | |
66 | /* Old, untested, unavailable, unknown */ | |
67 | case 0x0000: | |
68 | case 0x2500: | |
69 | case 0x2700: | |
70 | case 0x2900: | |
71 | case 0x2a00: | |
72 | case 0x2e00: | |
73 | case 0x3500: | |
74 | case 0xa000: | |
75 | return -1; | |
76 | /* SandyBridge, IvyBridge, ValleyView, Haswell */ | |
77 | case 0x0100: | |
78 | case 0x0400: | |
79 | case 0x0a00: | |
80 | case 0x0c00: | |
81 | case 0x0d00: | |
82 | case 0x0f00: | |
83 | return 6; | |
84 | /* BroadWell, CherryView, SkyLake, KabyLake */ | |
85 | case 0x1600: | |
86 | case 0x1900: | |
87 | case 0x2200: | |
88 | case 0x5900: | |
89 | return 8; | |
90 | } | |
91 | ||
92 | return 8; /* Assume newer is compatible */ | |
93 | } | |
94 | ||
95 | typedef struct VFIOIGDQuirk { | |
96 | struct VFIOPCIDevice *vdev; | |
97 | uint32_t index; | |
98 | uint32_t bdsm; | |
99 | } VFIOIGDQuirk; | |
100 | ||
101 | #define IGD_GMCH 0x50 /* Graphics Control Register */ | |
102 | #define IGD_BDSM 0x5c /* Base Data of Stolen Memory */ | |
103 | ||
104 | ||
105 | /* | |
106 | * The rather short list of registers that we copy from the host devices. | |
107 | * The LPC/ISA bridge values are definitely needed to support the vBIOS, the | |
108 | * host bridge values may or may not be needed depending on the guest OS. | |
109 | * Since we're only munging revision and subsystem values on the host bridge, | |
110 | * we don't require our own device. The LPC/ISA bridge needs to be our very | |
111 | * own though. | |
112 | */ | |
113 | typedef struct { | |
114 | uint8_t offset; | |
115 | uint8_t len; | |
116 | } IGDHostInfo; | |
117 | ||
118 | static const IGDHostInfo igd_host_bridge_infos[] = { | |
119 | {PCI_REVISION_ID, 2}, | |
120 | {PCI_SUBSYSTEM_VENDOR_ID, 2}, | |
121 | {PCI_SUBSYSTEM_ID, 2}, | |
122 | }; | |
123 | ||
124 | static const IGDHostInfo igd_lpc_bridge_infos[] = { | |
125 | {PCI_VENDOR_ID, 2}, | |
126 | {PCI_DEVICE_ID, 2}, | |
127 | {PCI_REVISION_ID, 2}, | |
128 | {PCI_SUBSYSTEM_VENDOR_ID, 2}, | |
129 | {PCI_SUBSYSTEM_ID, 2}, | |
130 | }; | |
131 | ||
132 | static int vfio_pci_igd_copy(VFIOPCIDevice *vdev, PCIDevice *pdev, | |
133 | struct vfio_region_info *info, | |
134 | const IGDHostInfo *list, int len) | |
135 | { | |
136 | int i, ret; | |
137 | ||
138 | for (i = 0; i < len; i++) { | |
139 | ret = pread(vdev->vbasedev.fd, pdev->config + list[i].offset, | |
140 | list[i].len, info->offset + list[i].offset); | |
141 | if (ret != list[i].len) { | |
142 | error_report("IGD copy failed: %m"); | |
143 | return -errno; | |
144 | } | |
145 | } | |
146 | ||
147 | return 0; | |
148 | } | |
149 | ||
150 | /* | |
151 | * Stuff a few values into the host bridge. | |
152 | */ | |
153 | static int vfio_pci_igd_host_init(VFIOPCIDevice *vdev, | |
154 | struct vfio_region_info *info) | |
155 | { | |
156 | PCIBus *bus; | |
157 | PCIDevice *host_bridge; | |
158 | int ret; | |
159 | ||
160 | bus = pci_device_root_bus(&vdev->pdev); | |
161 | host_bridge = pci_find_device(bus, 0, PCI_DEVFN(0, 0)); | |
162 | ||
163 | if (!host_bridge) { | |
164 | error_report("Can't find host bridge"); | |
165 | return -ENODEV; | |
166 | } | |
167 | ||
168 | ret = vfio_pci_igd_copy(vdev, host_bridge, info, igd_host_bridge_infos, | |
169 | ARRAY_SIZE(igd_host_bridge_infos)); | |
170 | if (!ret) { | |
171 | trace_vfio_pci_igd_host_bridge_enabled(vdev->vbasedev.name); | |
172 | } | |
173 | ||
174 | return ret; | |
175 | } | |
176 | ||
177 | /* | |
178 | * IGD LPC/ISA bridge support code. The vBIOS needs this, but we can't write | |
179 | * arbitrary values into just any bridge, so we must create our own. We try | |
180 | * to handle if the user has created it for us, which they might want to do | |
181 | * to enable multifunction so we don't occupy the whole PCI slot. | |
182 | */ | |
183 | static void vfio_pci_igd_lpc_bridge_realize(PCIDevice *pdev, Error **errp) | |
184 | { | |
185 | if (pdev->devfn != PCI_DEVFN(0x1f, 0)) { | |
186 | error_setg(errp, "VFIO dummy ISA/LPC bridge must have address 1f.0"); | |
187 | } | |
188 | } | |
189 | ||
190 | static void vfio_pci_igd_lpc_bridge_class_init(ObjectClass *klass, void *data) | |
191 | { | |
192 | DeviceClass *dc = DEVICE_CLASS(klass); | |
193 | PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); | |
194 | ||
195 | set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); | |
196 | dc->desc = "VFIO dummy ISA/LPC bridge for IGD assignment"; | |
197 | dc->hotpluggable = false; | |
198 | k->realize = vfio_pci_igd_lpc_bridge_realize; | |
199 | k->class_id = PCI_CLASS_BRIDGE_ISA; | |
200 | } | |
201 | ||
202 | static TypeInfo vfio_pci_igd_lpc_bridge_info = { | |
203 | .name = "vfio-pci-igd-lpc-bridge", | |
204 | .parent = TYPE_PCI_DEVICE, | |
205 | .class_init = vfio_pci_igd_lpc_bridge_class_init, | |
206 | .interfaces = (InterfaceInfo[]) { | |
207 | { INTERFACE_CONVENTIONAL_PCI_DEVICE }, | |
208 | { }, | |
209 | }, | |
210 | }; | |
211 | ||
212 | static void vfio_pci_igd_register_types(void) | |
213 | { | |
214 | type_register_static(&vfio_pci_igd_lpc_bridge_info); | |
215 | } | |
216 | ||
217 | type_init(vfio_pci_igd_register_types) | |
218 | ||
219 | static int vfio_pci_igd_lpc_init(VFIOPCIDevice *vdev, | |
220 | struct vfio_region_info *info) | |
221 | { | |
222 | PCIDevice *lpc_bridge; | |
223 | int ret; | |
224 | ||
225 | lpc_bridge = pci_find_device(pci_device_root_bus(&vdev->pdev), | |
226 | 0, PCI_DEVFN(0x1f, 0)); | |
227 | if (!lpc_bridge) { | |
228 | lpc_bridge = pci_create_simple(pci_device_root_bus(&vdev->pdev), | |
229 | PCI_DEVFN(0x1f, 0), "vfio-pci-igd-lpc-bridge"); | |
230 | } | |
231 | ||
232 | ret = vfio_pci_igd_copy(vdev, lpc_bridge, info, igd_lpc_bridge_infos, | |
233 | ARRAY_SIZE(igd_lpc_bridge_infos)); | |
234 | if (!ret) { | |
235 | trace_vfio_pci_igd_lpc_bridge_enabled(vdev->vbasedev.name); | |
236 | } | |
237 | ||
238 | return ret; | |
239 | } | |
240 | ||
241 | /* | |
242 | * IGD Gen8 and newer support up to 8MB for the GTT and use a 64bit PTE | |
243 | * entry, older IGDs use 2MB and 32bit. Each PTE maps a 4k page. Therefore | |
244 | * we either have 2M/4k * 4 = 2k or 8M/4k * 8 = 16k as the maximum iobar index | |
245 | * for programming the GTT. | |
246 | * | |
247 | * See linux:include/drm/i915_drm.h for shift and mask values. | |
248 | */ | |
249 | static int vfio_igd_gtt_max(VFIOPCIDevice *vdev) | |
250 | { | |
251 | uint32_t gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, sizeof(gmch)); | |
252 | int ggms, gen = igd_gen(vdev); | |
253 | ||
254 | gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, sizeof(gmch)); | |
255 | ggms = (gmch >> (gen < 8 ? 8 : 6)) & 0x3; | |
256 | if (gen > 6) { | |
257 | ggms = 1 << ggms; | |
258 | } | |
259 | ||
260 | ggms *= MiB; | |
261 | ||
262 | return (ggms / (4 * KiB)) * (gen < 8 ? 4 : 8); | |
263 | } | |
264 | ||
265 | /* | |
266 | * The IGD ROM will make use of stolen memory (GGMS) for support of VESA modes. | |
267 | * Somehow the host stolen memory range is used for this, but how the ROM gets | |
268 | * it is a mystery, perhaps it's hardcoded into the ROM. Thankfully though, it | |
269 | * reprograms the GTT through the IOBAR where we can trap it and transpose the | |
270 | * programming to the VM allocated buffer. That buffer gets reserved by the VM | |
271 | * firmware via the fw_cfg entry added below. Here we're just monitoring the | |
272 | * IOBAR address and data registers to detect a write sequence targeting the | |
273 | * GTTADR. This code is developed by observed behavior and doesn't have a | |
274 | * direct spec reference, unfortunately. | |
275 | */ | |
276 | static uint64_t vfio_igd_quirk_data_read(void *opaque, | |
277 | hwaddr addr, unsigned size) | |
278 | { | |
279 | VFIOIGDQuirk *igd = opaque; | |
280 | VFIOPCIDevice *vdev = igd->vdev; | |
281 | ||
282 | igd->index = ~0; | |
283 | ||
284 | return vfio_region_read(&vdev->bars[4].region, addr + 4, size); | |
285 | } | |
286 | ||
287 | static void vfio_igd_quirk_data_write(void *opaque, hwaddr addr, | |
288 | uint64_t data, unsigned size) | |
289 | { | |
290 | VFIOIGDQuirk *igd = opaque; | |
291 | VFIOPCIDevice *vdev = igd->vdev; | |
292 | uint64_t val = data; | |
293 | int gen = igd_gen(vdev); | |
294 | ||
295 | /* | |
296 | * Programming the GGMS starts at index 0x1 and uses every 4th index (ie. | |
297 | * 0x1, 0x5, 0x9, 0xd,...). For pre-Gen8 each 4-byte write is a whole PTE | |
298 | * entry, with 0th bit enable set. For Gen8 and up, PTEs are 64bit, so | |
299 | * entries 0x5 & 0xd are the high dword, in our case zero. Each PTE points | |
300 | * to a 4k page, which we translate to a page from the VM allocated region, | |
301 | * pointed to by the BDSM register. If this is not set, we fail. | |
302 | * | |
303 | * We trap writes to the full configured GTT size, but we typically only | |
304 | * see the vBIOS writing up to (nearly) the 1MB barrier. In fact it often | |
305 | * seems to miss the last entry for an even 1MB GTT. Doing a gratuitous | |
306 | * write of that last entry does work, but is hopefully unnecessary since | |
307 | * we clear the previous GTT on initialization. | |
308 | */ | |
309 | if ((igd->index % 4 == 1) && igd->index < vfio_igd_gtt_max(vdev)) { | |
310 | if (gen < 8 || (igd->index % 8 == 1)) { | |
311 | uint32_t base; | |
312 | ||
313 | base = pci_get_long(vdev->pdev.config + IGD_BDSM); | |
314 | if (!base) { | |
315 | hw_error("vfio-igd: Guest attempted to program IGD GTT before " | |
316 | "BIOS reserved stolen memory. Unsupported BIOS?"); | |
317 | } | |
318 | ||
319 | val = data - igd->bdsm + base; | |
320 | } else { | |
321 | val = 0; /* upper 32bits of pte, we only enable below 4G PTEs */ | |
322 | } | |
323 | ||
324 | trace_vfio_pci_igd_bar4_write(vdev->vbasedev.name, | |
325 | igd->index, data, val); | |
326 | } | |
327 | ||
328 | vfio_region_write(&vdev->bars[4].region, addr + 4, val, size); | |
329 | ||
330 | igd->index = ~0; | |
331 | } | |
332 | ||
333 | static const MemoryRegionOps vfio_igd_data_quirk = { | |
334 | .read = vfio_igd_quirk_data_read, | |
335 | .write = vfio_igd_quirk_data_write, | |
336 | .endianness = DEVICE_LITTLE_ENDIAN, | |
337 | }; | |
338 | ||
339 | static uint64_t vfio_igd_quirk_index_read(void *opaque, | |
340 | hwaddr addr, unsigned size) | |
341 | { | |
342 | VFIOIGDQuirk *igd = opaque; | |
343 | VFIOPCIDevice *vdev = igd->vdev; | |
344 | ||
345 | igd->index = ~0; | |
346 | ||
347 | return vfio_region_read(&vdev->bars[4].region, addr, size); | |
348 | } | |
349 | ||
350 | static void vfio_igd_quirk_index_write(void *opaque, hwaddr addr, | |
351 | uint64_t data, unsigned size) | |
352 | { | |
353 | VFIOIGDQuirk *igd = opaque; | |
354 | VFIOPCIDevice *vdev = igd->vdev; | |
355 | ||
356 | igd->index = data; | |
357 | ||
358 | vfio_region_write(&vdev->bars[4].region, addr, data, size); | |
359 | } | |
360 | ||
361 | static const MemoryRegionOps vfio_igd_index_quirk = { | |
362 | .read = vfio_igd_quirk_index_read, | |
363 | .write = vfio_igd_quirk_index_write, | |
364 | .endianness = DEVICE_LITTLE_ENDIAN, | |
365 | }; | |
366 | ||
367 | void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr) | |
368 | { | |
369 | struct vfio_region_info *rom = NULL, *opregion = NULL, | |
370 | *host = NULL, *lpc = NULL; | |
371 | VFIOQuirk *quirk; | |
372 | VFIOIGDQuirk *igd; | |
373 | PCIDevice *lpc_bridge; | |
374 | int i, ret, ggms_mb, gms_mb = 0, gen; | |
375 | uint64_t *bdsm_size; | |
376 | uint32_t gmch; | |
377 | uint16_t cmd_orig, cmd; | |
378 | Error *err = NULL; | |
379 | ||
380 | /* | |
381 | * This must be an Intel VGA device at address 00:02.0 for us to even | |
382 | * consider enabling legacy mode. The vBIOS has dependencies on the | |
383 | * PCI bus address. | |
384 | */ | |
385 | if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) || | |
386 | !vfio_is_vga(vdev) || nr != 4 || | |
387 | &vdev->pdev != pci_find_device(pci_device_root_bus(&vdev->pdev), | |
388 | 0, PCI_DEVFN(0x2, 0))) { | |
389 | return; | |
390 | } | |
391 | ||
392 | /* | |
393 | * We need to create an LPC/ISA bridge at PCI bus address 00:1f.0 that we | |
394 | * can stuff host values into, so if there's already one there and it's not | |
395 | * one we can hack on, legacy mode is no-go. Sorry Q35. | |
396 | */ | |
397 | lpc_bridge = pci_find_device(pci_device_root_bus(&vdev->pdev), | |
398 | 0, PCI_DEVFN(0x1f, 0)); | |
399 | if (lpc_bridge && !object_dynamic_cast(OBJECT(lpc_bridge), | |
400 | "vfio-pci-igd-lpc-bridge")) { | |
401 | error_report("IGD device %s cannot support legacy mode due to existing " | |
402 | "devices at address 1f.0", vdev->vbasedev.name); | |
403 | return; | |
404 | } | |
405 | ||
406 | /* | |
407 | * IGD is not a standard, they like to change their specs often. We | |
408 | * only attempt to support back to SandBridge and we hope that newer | |
409 | * devices maintain compatibility with generation 8. | |
410 | */ | |
411 | gen = igd_gen(vdev); | |
412 | if (gen != 6 && gen != 8) { | |
413 | error_report("IGD device %s is unsupported in legacy mode, " | |
414 | "try SandyBridge or newer", vdev->vbasedev.name); | |
415 | return; | |
416 | } | |
417 | ||
418 | /* | |
419 | * Most of what we're doing here is to enable the ROM to run, so if | |
420 | * there's no ROM, there's no point in setting up this quirk. | |
421 | * NB. We only seem to get BIOS ROMs, so a UEFI VM would need CSM support. | |
422 | */ | |
423 | ret = vfio_get_region_info(&vdev->vbasedev, | |
424 | VFIO_PCI_ROM_REGION_INDEX, &rom); | |
425 | if ((ret || !rom->size) && !vdev->pdev.romfile) { | |
426 | error_report("IGD device %s has no ROM, legacy mode disabled", | |
427 | vdev->vbasedev.name); | |
428 | goto out; | |
429 | } | |
430 | ||
431 | /* | |
432 | * Ignore the hotplug corner case, mark the ROM failed, we can't | |
433 | * create the devices we need for legacy mode in the hotplug scenario. | |
434 | */ | |
435 | if (vdev->pdev.qdev.hotplugged) { | |
436 | error_report("IGD device %s hotplugged, ROM disabled, " | |
437 | "legacy mode disabled", vdev->vbasedev.name); | |
438 | vdev->rom_read_failed = true; | |
439 | goto out; | |
440 | } | |
441 | ||
442 | /* | |
443 | * Check whether we have all the vfio device specific regions to | |
444 | * support legacy mode (added in Linux v4.6). If not, bail. | |
445 | */ | |
446 | ret = vfio_get_dev_region_info(&vdev->vbasedev, | |
447 | VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL, | |
448 | VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, &opregion); | |
449 | if (ret) { | |
450 | error_report("IGD device %s does not support OpRegion access," | |
451 | "legacy mode disabled", vdev->vbasedev.name); | |
452 | goto out; | |
453 | } | |
454 | ||
455 | ret = vfio_get_dev_region_info(&vdev->vbasedev, | |
456 | VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL, | |
457 | VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG, &host); | |
458 | if (ret) { | |
459 | error_report("IGD device %s does not support host bridge access," | |
460 | "legacy mode disabled", vdev->vbasedev.name); | |
461 | goto out; | |
462 | } | |
463 | ||
464 | ret = vfio_get_dev_region_info(&vdev->vbasedev, | |
465 | VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL, | |
466 | VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG, &lpc); | |
467 | if (ret) { | |
468 | error_report("IGD device %s does not support LPC bridge access," | |
469 | "legacy mode disabled", vdev->vbasedev.name); | |
470 | goto out; | |
471 | } | |
472 | ||
473 | gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4); | |
474 | ||
475 | /* | |
476 | * If IGD VGA Disable is clear (expected) and VGA is not already enabled, | |
477 | * try to enable it. Probably shouldn't be using legacy mode without VGA, | |
478 | * but also no point in us enabling VGA if disabled in hardware. | |
479 | */ | |
480 | if (!(gmch & 0x2) && !vdev->vga && vfio_populate_vga(vdev, &err)) { | |
481 | error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); | |
482 | error_report("IGD device %s failed to enable VGA access, " | |
483 | "legacy mode disabled", vdev->vbasedev.name); | |
484 | goto out; | |
485 | } | |
486 | ||
487 | /* Create our LPC/ISA bridge */ | |
488 | ret = vfio_pci_igd_lpc_init(vdev, lpc); | |
489 | if (ret) { | |
490 | error_report("IGD device %s failed to create LPC bridge, " | |
491 | "legacy mode disabled", vdev->vbasedev.name); | |
492 | goto out; | |
493 | } | |
494 | ||
495 | /* Stuff some host values into the VM PCI host bridge */ | |
496 | ret = vfio_pci_igd_host_init(vdev, host); | |
497 | if (ret) { | |
498 | error_report("IGD device %s failed to modify host bridge, " | |
499 | "legacy mode disabled", vdev->vbasedev.name); | |
500 | goto out; | |
501 | } | |
502 | ||
503 | /* Setup OpRegion access */ | |
504 | ret = vfio_pci_igd_opregion_init(vdev, opregion, &err); | |
505 | if (ret) { | |
506 | error_append_hint(&err, "IGD legacy mode disabled\n"); | |
507 | error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); | |
508 | goto out; | |
509 | } | |
510 | ||
511 | /* Setup our quirk to munge GTT addresses to the VM allocated buffer */ | |
512 | quirk = vfio_quirk_alloc(2); | |
513 | igd = quirk->data = g_malloc0(sizeof(*igd)); | |
514 | igd->vdev = vdev; | |
515 | igd->index = ~0; | |
516 | igd->bdsm = vfio_pci_read_config(&vdev->pdev, IGD_BDSM, 4); | |
517 | igd->bdsm &= ~((1 * MiB) - 1); /* 1MB aligned */ | |
518 | ||
519 | memory_region_init_io(&quirk->mem[0], OBJECT(vdev), &vfio_igd_index_quirk, | |
520 | igd, "vfio-igd-index-quirk", 4); | |
521 | memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, | |
522 | 0, &quirk->mem[0], 1); | |
523 | ||
524 | memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_igd_data_quirk, | |
525 | igd, "vfio-igd-data-quirk", 4); | |
526 | memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, | |
527 | 4, &quirk->mem[1], 1); | |
528 | ||
529 | QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); | |
530 | ||
531 | /* Determine the size of stolen memory needed for GTT */ | |
532 | ggms_mb = (gmch >> (gen < 8 ? 8 : 6)) & 0x3; | |
533 | if (gen > 6) { | |
534 | ggms_mb = 1 << ggms_mb; | |
535 | } | |
536 | ||
537 | /* | |
538 | * Assume we have no GMS memory, but allow it to be overrided by device | |
539 | * option (experimental). The spec doesn't actually allow zero GMS when | |
540 | * when IVD (IGD VGA Disable) is clear, but the claim is that it's unused, | |
541 | * so let's not waste VM memory for it. | |
542 | */ | |
543 | gmch &= ~((gen < 8 ? 0x1f : 0xff) << (gen < 8 ? 3 : 8)); | |
544 | ||
545 | if (vdev->igd_gms) { | |
546 | if (vdev->igd_gms <= 0x10) { | |
547 | gms_mb = vdev->igd_gms * 32; | |
548 | gmch |= vdev->igd_gms << (gen < 8 ? 3 : 8); | |
549 | } else { | |
550 | error_report("Unsupported IGD GMS value 0x%x", vdev->igd_gms); | |
551 | vdev->igd_gms = 0; | |
552 | } | |
553 | } | |
554 | ||
555 | /* | |
556 | * Request reserved memory for stolen memory via fw_cfg. VM firmware | |
557 | * must allocate a 1MB aligned reserved memory region below 4GB with | |
558 | * the requested size (in bytes) for use by the Intel PCI class VGA | |
559 | * device at VM address 00:02.0. The base address of this reserved | |
560 | * memory region must be written to the device BDSM regsiter at PCI | |
561 | * config offset 0x5C. | |
562 | */ | |
563 | bdsm_size = g_malloc(sizeof(*bdsm_size)); | |
564 | *bdsm_size = cpu_to_le64((ggms_mb + gms_mb) * MiB); | |
565 | fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size", | |
566 | bdsm_size, sizeof(*bdsm_size)); | |
567 | ||
568 | /* GMCH is read-only, emulated */ | |
569 | pci_set_long(vdev->pdev.config + IGD_GMCH, gmch); | |
570 | pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0); | |
571 | pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0); | |
572 | ||
573 | /* BDSM is read-write, emulated. The BIOS needs to be able to write it */ | |
574 | pci_set_long(vdev->pdev.config + IGD_BDSM, 0); | |
575 | pci_set_long(vdev->pdev.wmask + IGD_BDSM, ~0); | |
576 | pci_set_long(vdev->emulated_config_bits + IGD_BDSM, ~0); | |
577 | ||
578 | /* | |
579 | * This IOBAR gives us access to GTTADR, which allows us to write to | |
580 | * the GTT itself. So let's go ahead and write zero to all the GTT | |
581 | * entries to avoid spurious DMA faults. Be sure I/O access is enabled | |
582 | * before talking to the device. | |
583 | */ | |
584 | if (pread(vdev->vbasedev.fd, &cmd_orig, sizeof(cmd_orig), | |
585 | vdev->config_offset + PCI_COMMAND) != sizeof(cmd_orig)) { | |
586 | error_report("IGD device %s - failed to read PCI command register", | |
587 | vdev->vbasedev.name); | |
588 | } | |
589 | ||
590 | cmd = cmd_orig | PCI_COMMAND_IO; | |
591 | ||
592 | if (pwrite(vdev->vbasedev.fd, &cmd, sizeof(cmd), | |
593 | vdev->config_offset + PCI_COMMAND) != sizeof(cmd)) { | |
594 | error_report("IGD device %s - failed to write PCI command register", | |
595 | vdev->vbasedev.name); | |
596 | } | |
597 | ||
598 | for (i = 1; i < vfio_igd_gtt_max(vdev); i += 4) { | |
599 | vfio_region_write(&vdev->bars[4].region, 0, i, 4); | |
600 | vfio_region_write(&vdev->bars[4].region, 4, 0, 4); | |
601 | } | |
602 | ||
603 | if (pwrite(vdev->vbasedev.fd, &cmd_orig, sizeof(cmd_orig), | |
604 | vdev->config_offset + PCI_COMMAND) != sizeof(cmd_orig)) { | |
605 | error_report("IGD device %s - failed to restore PCI command register", | |
606 | vdev->vbasedev.name); | |
607 | } | |
608 | ||
609 | trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb); | |
610 | ||
611 | out: | |
612 | g_free(rom); | |
613 | g_free(opregion); | |
614 | g_free(host); | |
615 | g_free(lpc); | |
616 | } |