Lines Matching +full:gfx +full:- +full:mem

4  * Copyright Red Hat, Inc. 2012-2015
10 * the COPYING file in the top-level directory.
18 #include "qemu/error-report.h"
19 #include "qemu/main-loop.h"
26 #include "hw/qdev-properties.h"
28 #include "pci-quirks.h"
57 trace_vfio_quirk_rom_in_denylist(vdev->vbasedev.name, in vfio_opt_rom_in_denylist()
75 VFIOPCIDevice *vdev = window->vdev; in vfio_generic_window_quirk_address_read()
77 return vfio_region_read(&vdev->bars[window->bar].region, in vfio_generic_window_quirk_address_read()
78 addr + window->address_offset, size); in vfio_generic_window_quirk_address_read()
86 VFIOPCIDevice *vdev = window->vdev; in vfio_generic_window_quirk_address_write()
89 window->window_enabled = false; in vfio_generic_window_quirk_address_write()
91 vfio_region_write(&vdev->bars[window->bar].region, in vfio_generic_window_quirk_address_write()
92 addr + window->address_offset, data, size); in vfio_generic_window_quirk_address_write()
94 for (i = 0; i < window->nr_matches; i++) { in vfio_generic_window_quirk_address_write()
95 if ((data & ~window->matches[i].mask) == window->matches[i].match) { in vfio_generic_window_quirk_address_write()
96 window->window_enabled = true; in vfio_generic_window_quirk_address_write()
97 window->address_val = data & window->matches[i].mask; in vfio_generic_window_quirk_address_write()
98 trace_vfio_quirk_generic_window_address_write(vdev->vbasedev.name, in vfio_generic_window_quirk_address_write()
99 memory_region_name(window->addr_mem), data); in vfio_generic_window_quirk_address_write()
115 VFIOPCIDevice *vdev = window->vdev; in vfio_generic_window_quirk_data_read()
119 data = vfio_region_read(&vdev->bars[window->bar].region, in vfio_generic_window_quirk_data_read()
120 addr + window->data_offset, size); in vfio_generic_window_quirk_data_read()
122 if (window->window_enabled) { in vfio_generic_window_quirk_data_read()
123 data = vfio_pci_read_config(&vdev->pdev, window->address_val, size); in vfio_generic_window_quirk_data_read()
124 trace_vfio_quirk_generic_window_data_read(vdev->vbasedev.name, in vfio_generic_window_quirk_data_read()
125 memory_region_name(window->data_mem), data); in vfio_generic_window_quirk_data_read()
135 VFIOPCIDevice *vdev = window->vdev; in vfio_generic_window_quirk_data_write()
137 if (window->window_enabled) { in vfio_generic_window_quirk_data_write()
138 vfio_pci_write_config(&vdev->pdev, window->address_val, data, size); in vfio_generic_window_quirk_data_write()
139 trace_vfio_quirk_generic_window_data_write(vdev->vbasedev.name, in vfio_generic_window_quirk_data_write()
140 memory_region_name(window->data_mem), data); in vfio_generic_window_quirk_data_write()
144 vfio_region_write(&vdev->bars[window->bar].region, in vfio_generic_window_quirk_data_write()
145 addr + window->data_offset, data, size); in vfio_generic_window_quirk_data_write()
158 VFIOPCIDevice *vdev = mirror->vdev; in vfio_generic_quirk_mirror_read()
162 (void)vfio_region_read(&vdev->bars[mirror->bar].region, in vfio_generic_quirk_mirror_read()
163 addr + mirror->offset, size); in vfio_generic_quirk_mirror_read()
165 addr += mirror->config_offset; in vfio_generic_quirk_mirror_read()
166 data = vfio_pci_read_config(&vdev->pdev, addr, size); in vfio_generic_quirk_mirror_read()
167 trace_vfio_quirk_generic_mirror_read(vdev->vbasedev.name, in vfio_generic_quirk_mirror_read()
168 memory_region_name(mirror->mem), in vfio_generic_quirk_mirror_read()
177 VFIOPCIDevice *vdev = mirror->vdev; in vfio_generic_quirk_mirror_write()
179 addr += mirror->config_offset; in vfio_generic_quirk_mirror_write()
180 vfio_pci_write_config(&vdev->pdev, addr, data, size); in vfio_generic_quirk_mirror_write()
181 trace_vfio_quirk_generic_mirror_write(vdev->vbasedev.name, in vfio_generic_quirk_mirror_write()
182 memory_region_name(mirror->mem), in vfio_generic_quirk_mirror_write()
214 uint64_t data = vfio_pci_read_config(&vdev->pdev, in vfio_ati_3c3_quirk_read()
217 trace_vfio_quirk_ati_3c3_read(vdev->vbasedev.name, data); in vfio_ati_3c3_quirk_read()
237 QLIST_INIT(&quirk->ioeventfds); in vfio_quirk_alloc()
238 quirk->mem = g_new0(MemoryRegion, nr_mem); in vfio_quirk_alloc()
239 quirk->nr_mem = nr_mem; in vfio_quirk_alloc()
247 memory_region_del_eventfd(ioeventfd->mr, ioeventfd->addr, ioeventfd->size, in vfio_ioeventfd_exit()
248 true, ioeventfd->data, &ioeventfd->e); in vfio_ioeventfd_exit()
250 if (ioeventfd->vfio) { in vfio_ioeventfd_exit()
254 vfio_ioeventfd.flags = ioeventfd->size; in vfio_ioeventfd_exit()
255 vfio_ioeventfd.data = ioeventfd->data; in vfio_ioeventfd_exit()
256 vfio_ioeventfd.offset = ioeventfd->region->fd_offset + in vfio_ioeventfd_exit()
257 ioeventfd->region_addr; in vfio_ioeventfd_exit()
258 vfio_ioeventfd.fd = -1; in vfio_ioeventfd_exit()
260 if (ioctl(vdev->vbasedev.fd, VFIO_DEVICE_IOEVENTFD, &vfio_ioeventfd)) { in vfio_ioeventfd_exit()
263 memory_region_name(ioeventfd->mr), ioeventfd->addr, in vfio_ioeventfd_exit()
264 ioeventfd->size, ioeventfd->data); in vfio_ioeventfd_exit()
267 qemu_set_fd_handler(event_notifier_get_fd(&ioeventfd->e), in vfio_ioeventfd_exit()
271 event_notifier_cleanup(&ioeventfd->e); in vfio_ioeventfd_exit()
272 trace_vfio_ioeventfd_exit(memory_region_name(ioeventfd->mr), in vfio_ioeventfd_exit()
273 (uint64_t)ioeventfd->addr, ioeventfd->size, in vfio_ioeventfd_exit()
274 ioeventfd->data); in vfio_ioeventfd_exit()
282 QLIST_FOREACH_SAFE(ioeventfd, &quirk->ioeventfds, next, tmp) { in vfio_drop_dynamic_eventfds()
283 if (ioeventfd->dynamic) { in vfio_drop_dynamic_eventfds()
293 if (event_notifier_test_and_clear(&ioeventfd->e)) { in vfio_ioeventfd_handler()
294 vfio_region_write(ioeventfd->region, ioeventfd->region_addr, in vfio_ioeventfd_handler()
295 ioeventfd->data, ioeventfd->size); in vfio_ioeventfd_handler()
296 trace_vfio_ioeventfd_handler(memory_region_name(ioeventfd->mr), in vfio_ioeventfd_handler()
297 (uint64_t)ioeventfd->addr, ioeventfd->size, in vfio_ioeventfd_handler()
298 ioeventfd->data); in vfio_ioeventfd_handler()
310 if (vdev->no_kvm_ioeventfd) { in vfio_ioeventfd_init()
316 if (event_notifier_init(&ioeventfd->e, 0)) { in vfio_ioeventfd_init()
325 ioeventfd->mr = mr; in vfio_ioeventfd_init()
326 ioeventfd->addr = addr; in vfio_ioeventfd_init()
327 ioeventfd->size = size; in vfio_ioeventfd_init()
328 ioeventfd->data = data; in vfio_ioeventfd_init()
329 ioeventfd->dynamic = dynamic; in vfio_ioeventfd_init()
334 ioeventfd->region = region; in vfio_ioeventfd_init()
335 ioeventfd->region_addr = region_addr; in vfio_ioeventfd_init()
337 if (!vdev->no_vfio_ioeventfd) { in vfio_ioeventfd_init()
341 vfio_ioeventfd.flags = ioeventfd->size; in vfio_ioeventfd_init()
342 vfio_ioeventfd.data = ioeventfd->data; in vfio_ioeventfd_init()
343 vfio_ioeventfd.offset = ioeventfd->region->fd_offset + in vfio_ioeventfd_init()
344 ioeventfd->region_addr; in vfio_ioeventfd_init()
345 vfio_ioeventfd.fd = event_notifier_get_fd(&ioeventfd->e); in vfio_ioeventfd_init()
347 ioeventfd->vfio = !ioctl(vdev->vbasedev.fd, in vfio_ioeventfd_init()
351 if (!ioeventfd->vfio) { in vfio_ioeventfd_init()
352 qemu_set_fd_handler(event_notifier_get_fd(&ioeventfd->e), in vfio_ioeventfd_init()
356 memory_region_add_eventfd(ioeventfd->mr, ioeventfd->addr, ioeventfd->size, in vfio_ioeventfd_init()
357 true, ioeventfd->data, &ioeventfd->e); in vfio_ioeventfd_init()
359 size, data, ioeventfd->vfio); in vfio_ioeventfd_init()
373 !vdev->bars[4].ioport || vdev->bars[4].region.size < 256) { in vfio_vga_probe_ati_3c3_quirk()
379 memory_region_init_io(quirk->mem, OBJECT(vdev), &vfio_ati_3c3_quirk, vdev, in vfio_vga_probe_ati_3c3_quirk()
380 "vfio-ati-3c3-quirk", 1); in vfio_vga_probe_ati_3c3_quirk()
381 memory_region_add_subregion(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem, in vfio_vga_probe_ati_3c3_quirk()
382 3 /* offset 3 bytes from 0x3c0 */, quirk->mem); in vfio_vga_probe_ati_3c3_quirk()
384 QLIST_INSERT_HEAD(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].quirks, in vfio_vga_probe_ati_3c3_quirk()
387 trace_vfio_quirk_ati_3c3_probe(vdev->vbasedev.name); in vfio_vga_probe_ati_3c3_quirk()
395 * data register. When the address is programmed to a range of 0x4000-0x4fff
397 * that read-only may be provided by hardware.
406 !vdev->vga || nr != 4 || !vdev->bars[4].ioport) { in vfio_probe_ati_bar4_quirk()
411 window = quirk->data = g_malloc0(sizeof(*window) + in vfio_probe_ati_bar4_quirk()
413 window->vdev = vdev; in vfio_probe_ati_bar4_quirk()
414 window->address_offset = 0; in vfio_probe_ati_bar4_quirk()
415 window->data_offset = 4; in vfio_probe_ati_bar4_quirk()
416 window->nr_matches = 1; in vfio_probe_ati_bar4_quirk()
417 window->matches[0].match = 0x4000; in vfio_probe_ati_bar4_quirk()
418 window->matches[0].mask = vdev->config_size - 1; in vfio_probe_ati_bar4_quirk()
419 window->bar = nr; in vfio_probe_ati_bar4_quirk()
420 window->addr_mem = &quirk->mem[0]; in vfio_probe_ati_bar4_quirk()
421 window->data_mem = &quirk->mem[1]; in vfio_probe_ati_bar4_quirk()
423 memory_region_init_io(window->addr_mem, OBJECT(vdev), in vfio_probe_ati_bar4_quirk()
425 "vfio-ati-bar4-window-address-quirk", 4); in vfio_probe_ati_bar4_quirk()
426 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_ati_bar4_quirk()
427 window->address_offset, in vfio_probe_ati_bar4_quirk()
428 window->addr_mem, 1); in vfio_probe_ati_bar4_quirk()
430 memory_region_init_io(window->data_mem, OBJECT(vdev), in vfio_probe_ati_bar4_quirk()
432 "vfio-ati-bar4-window-data-quirk", 4); in vfio_probe_ati_bar4_quirk()
433 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_ati_bar4_quirk()
434 window->data_offset, in vfio_probe_ati_bar4_quirk()
435 window->data_mem, 1); in vfio_probe_ati_bar4_quirk()
437 QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); in vfio_probe_ati_bar4_quirk()
439 trace_vfio_quirk_ati_bar4_probe(vdev->vbasedev.name); in vfio_probe_ati_bar4_quirk()
452 !vdev->vga || nr != 2 || !vdev->bars[2].mem64) { in vfio_probe_ati_bar2_quirk()
457 mirror = quirk->data = g_malloc0(sizeof(*mirror)); in vfio_probe_ati_bar2_quirk()
458 mirror->mem = quirk->mem; in vfio_probe_ati_bar2_quirk()
459 mirror->vdev = vdev; in vfio_probe_ati_bar2_quirk()
460 mirror->offset = 0x4000; in vfio_probe_ati_bar2_quirk()
461 mirror->bar = nr; in vfio_probe_ati_bar2_quirk()
463 memory_region_init_io(mirror->mem, OBJECT(vdev), in vfio_probe_ati_bar2_quirk()
465 "vfio-ati-bar2-4000-quirk", PCI_CONFIG_SPACE_SIZE); in vfio_probe_ati_bar2_quirk()
466 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_ati_bar2_quirk()
467 mirror->offset, mirror->mem, 1); in vfio_probe_ati_bar2_quirk()
469 QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); in vfio_probe_ati_bar2_quirk()
471 trace_vfio_quirk_ati_bar2_probe(vdev->vbasedev.name); in vfio_probe_ati_bar2_quirk()
510 VFIOPCIDevice *vdev = quirk->vdev; in vfio_nvidia_3d4_quirk_read()
512 quirk->state = NONE; in vfio_nvidia_3d4_quirk_read()
514 return vfio_vga_read(&vdev->vga->region[QEMU_PCI_VGA_IO_HI], in vfio_nvidia_3d4_quirk_read()
522 VFIOPCIDevice *vdev = quirk->vdev; in vfio_nvidia_3d4_quirk_write()
523 VFIONvidia3d0State old_state = quirk->state; in vfio_nvidia_3d4_quirk_write()
525 quirk->state = NONE; in vfio_nvidia_3d4_quirk_write()
530 quirk->state = SELECT; in vfio_nvidia_3d4_quirk_write()
531 trace_vfio_quirk_nvidia_3d0_state(vdev->vbasedev.name, in vfio_nvidia_3d4_quirk_write()
532 nv3d0_states[quirk->state]); in vfio_nvidia_3d4_quirk_write()
537 quirk->state = READ; in vfio_nvidia_3d4_quirk_write()
538 trace_vfio_quirk_nvidia_3d0_state(vdev->vbasedev.name, in vfio_nvidia_3d4_quirk_write()
539 nv3d0_states[quirk->state]); in vfio_nvidia_3d4_quirk_write()
544 quirk->state = WRITE; in vfio_nvidia_3d4_quirk_write()
545 trace_vfio_quirk_nvidia_3d0_state(vdev->vbasedev.name, in vfio_nvidia_3d4_quirk_write()
546 nv3d0_states[quirk->state]); in vfio_nvidia_3d4_quirk_write()
551 vfio_vga_write(&vdev->vga->region[QEMU_PCI_VGA_IO_HI], in vfio_nvidia_3d4_quirk_write()
565 VFIOPCIDevice *vdev = quirk->vdev; in vfio_nvidia_3d0_quirk_read()
566 VFIONvidia3d0State old_state = quirk->state; in vfio_nvidia_3d0_quirk_read()
567 uint64_t data = vfio_vga_read(&vdev->vga->region[QEMU_PCI_VGA_IO_HI], in vfio_nvidia_3d0_quirk_read()
570 quirk->state = NONE; in vfio_nvidia_3d0_quirk_read()
573 (quirk->offset & ~(PCI_CONFIG_SPACE_SIZE - 1)) == 0x1800) { in vfio_nvidia_3d0_quirk_read()
574 uint8_t offset = quirk->offset & (PCI_CONFIG_SPACE_SIZE - 1); in vfio_nvidia_3d0_quirk_read()
576 data = vfio_pci_read_config(&vdev->pdev, offset, size); in vfio_nvidia_3d0_quirk_read()
577 trace_vfio_quirk_nvidia_3d0_read(vdev->vbasedev.name, in vfio_nvidia_3d0_quirk_read()
588 VFIOPCIDevice *vdev = quirk->vdev; in vfio_nvidia_3d0_quirk_write()
589 VFIONvidia3d0State old_state = quirk->state; in vfio_nvidia_3d0_quirk_write()
591 quirk->state = NONE; in vfio_nvidia_3d0_quirk_write()
594 quirk->offset = (uint32_t)data; in vfio_nvidia_3d0_quirk_write()
595 quirk->state = WINDOW; in vfio_nvidia_3d0_quirk_write()
596 trace_vfio_quirk_nvidia_3d0_state(vdev->vbasedev.name, in vfio_nvidia_3d0_quirk_write()
597 nv3d0_states[quirk->state]); in vfio_nvidia_3d0_quirk_write()
599 if ((quirk->offset & ~(PCI_CONFIG_SPACE_SIZE - 1)) == 0x1800) { in vfio_nvidia_3d0_quirk_write()
600 uint8_t offset = quirk->offset & (PCI_CONFIG_SPACE_SIZE - 1); in vfio_nvidia_3d0_quirk_write()
602 vfio_pci_write_config(&vdev->pdev, offset, data, size); in vfio_nvidia_3d0_quirk_write()
603 trace_vfio_quirk_nvidia_3d0_write(vdev->vbasedev.name, in vfio_nvidia_3d0_quirk_write()
609 vfio_vga_write(&vdev->vga->region[QEMU_PCI_VGA_IO_HI], in vfio_nvidia_3d0_quirk_write()
624 if (vdev->no_geforce_quirks || in vfio_vga_probe_nvidia_3d0_quirk()
626 !vdev->bars[1].region.size) { in vfio_vga_probe_nvidia_3d0_quirk()
631 quirk->data = data = g_malloc0(sizeof(*data)); in vfio_vga_probe_nvidia_3d0_quirk()
632 data->vdev = vdev; in vfio_vga_probe_nvidia_3d0_quirk()
634 memory_region_init_io(&quirk->mem[0], OBJECT(vdev), &vfio_nvidia_3d4_quirk, in vfio_vga_probe_nvidia_3d0_quirk()
635 data, "vfio-nvidia-3d4-quirk", 2); in vfio_vga_probe_nvidia_3d0_quirk()
636 memory_region_add_subregion(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem, in vfio_vga_probe_nvidia_3d0_quirk()
637 0x14 /* 0x3c0 + 0x14 */, &quirk->mem[0]); in vfio_vga_probe_nvidia_3d0_quirk()
639 memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_nvidia_3d0_quirk, in vfio_vga_probe_nvidia_3d0_quirk()
640 data, "vfio-nvidia-3d0-quirk", 2); in vfio_vga_probe_nvidia_3d0_quirk()
641 memory_region_add_subregion(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem, in vfio_vga_probe_nvidia_3d0_quirk()
642 0x10 /* 0x3c0 + 0x10 */, &quirk->mem[1]); in vfio_vga_probe_nvidia_3d0_quirk()
644 QLIST_INSERT_HEAD(&vdev->vga->region[QEMU_PCI_VGA_IO_HI].quirks, in vfio_vga_probe_nvidia_3d0_quirk()
647 trace_vfio_quirk_nvidia_3d0_probe(vdev->vbasedev.name); in vfio_vga_probe_nvidia_3d0_quirk()
668 VFIOPCIDevice *vdev = bar5->window.vdev; in vfio_nvidia_bar5_enable()
670 if (((bar5->master & bar5->enable) & 0x1) == bar5->enabled) { in vfio_nvidia_bar5_enable()
674 bar5->enabled = !bar5->enabled; in vfio_nvidia_bar5_enable()
675 trace_vfio_quirk_nvidia_bar5_state(vdev->vbasedev.name, in vfio_nvidia_bar5_enable()
676 bar5->enabled ? "Enable" : "Disable"); in vfio_nvidia_bar5_enable()
677 memory_region_set_enabled(bar5->addr_mem, bar5->enabled); in vfio_nvidia_bar5_enable()
678 memory_region_set_enabled(bar5->data_mem, bar5->enabled); in vfio_nvidia_bar5_enable()
685 VFIOPCIDevice *vdev = bar5->window.vdev; in vfio_nvidia_bar5_quirk_master_read()
687 return vfio_region_read(&vdev->bars[5].region, addr, size); in vfio_nvidia_bar5_quirk_master_read()
694 VFIOPCIDevice *vdev = bar5->window.vdev; in vfio_nvidia_bar5_quirk_master_write()
696 vfio_region_write(&vdev->bars[5].region, addr, data, size); in vfio_nvidia_bar5_quirk_master_write()
698 bar5->master = data; in vfio_nvidia_bar5_quirk_master_write()
712 VFIOPCIDevice *vdev = bar5->window.vdev; in vfio_nvidia_bar5_quirk_enable_read()
714 return vfio_region_read(&vdev->bars[5].region, addr + 4, size); in vfio_nvidia_bar5_quirk_enable_read()
721 VFIOPCIDevice *vdev = bar5->window.vdev; in vfio_nvidia_bar5_quirk_enable_write()
723 vfio_region_write(&vdev->bars[5].region, addr + 4, data, size); in vfio_nvidia_bar5_quirk_enable_write()
725 bar5->enable = data; in vfio_nvidia_bar5_quirk_enable_write()
741 if (vdev->no_geforce_quirks || in vfio_probe_nvidia_bar5_quirk()
743 !vdev->vga || nr != 5 || !vdev->bars[5].ioport) { in vfio_probe_nvidia_bar5_quirk()
748 bar5 = quirk->data = g_malloc0(sizeof(*bar5) + in vfio_probe_nvidia_bar5_quirk()
750 window = &bar5->window; in vfio_probe_nvidia_bar5_quirk()
752 window->vdev = vdev; in vfio_probe_nvidia_bar5_quirk()
753 window->address_offset = 0x8; in vfio_probe_nvidia_bar5_quirk()
754 window->data_offset = 0xc; in vfio_probe_nvidia_bar5_quirk()
755 window->nr_matches = 2; in vfio_probe_nvidia_bar5_quirk()
756 window->matches[0].match = 0x1800; in vfio_probe_nvidia_bar5_quirk()
757 window->matches[0].mask = PCI_CONFIG_SPACE_SIZE - 1; in vfio_probe_nvidia_bar5_quirk()
758 window->matches[1].match = 0x88000; in vfio_probe_nvidia_bar5_quirk()
759 window->matches[1].mask = vdev->config_size - 1; in vfio_probe_nvidia_bar5_quirk()
760 window->bar = nr; in vfio_probe_nvidia_bar5_quirk()
761 window->addr_mem = bar5->addr_mem = &quirk->mem[0]; in vfio_probe_nvidia_bar5_quirk()
762 window->data_mem = bar5->data_mem = &quirk->mem[1]; in vfio_probe_nvidia_bar5_quirk()
764 memory_region_init_io(window->addr_mem, OBJECT(vdev), in vfio_probe_nvidia_bar5_quirk()
766 "vfio-nvidia-bar5-window-address-quirk", 4); in vfio_probe_nvidia_bar5_quirk()
767 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_nvidia_bar5_quirk()
768 window->address_offset, in vfio_probe_nvidia_bar5_quirk()
769 window->addr_mem, 1); in vfio_probe_nvidia_bar5_quirk()
770 memory_region_set_enabled(window->addr_mem, false); in vfio_probe_nvidia_bar5_quirk()
772 memory_region_init_io(window->data_mem, OBJECT(vdev), in vfio_probe_nvidia_bar5_quirk()
774 "vfio-nvidia-bar5-window-data-quirk", 4); in vfio_probe_nvidia_bar5_quirk()
775 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_nvidia_bar5_quirk()
776 window->data_offset, in vfio_probe_nvidia_bar5_quirk()
777 window->data_mem, 1); in vfio_probe_nvidia_bar5_quirk()
778 memory_region_set_enabled(window->data_mem, false); in vfio_probe_nvidia_bar5_quirk()
780 memory_region_init_io(&quirk->mem[2], OBJECT(vdev), in vfio_probe_nvidia_bar5_quirk()
782 "vfio-nvidia-bar5-master-quirk", 4); in vfio_probe_nvidia_bar5_quirk()
783 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_nvidia_bar5_quirk()
784 0, &quirk->mem[2], 1); in vfio_probe_nvidia_bar5_quirk()
786 memory_region_init_io(&quirk->mem[3], OBJECT(vdev), in vfio_probe_nvidia_bar5_quirk()
788 "vfio-nvidia-bar5-enable-quirk", 4); in vfio_probe_nvidia_bar5_quirk()
789 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_nvidia_bar5_quirk()
790 4, &quirk->mem[3], 1); in vfio_probe_nvidia_bar5_quirk()
792 QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); in vfio_probe_nvidia_bar5_quirk()
794 trace_vfio_quirk_nvidia_bar5_probe(vdev->vbasedev.name); in vfio_probe_nvidia_bar5_quirk()
817 VFIOPCIDevice *vdev = mirror->vdev; in vfio_nvidia_quirk_mirror_write()
818 PCIDevice *pdev = &vdev->pdev; in vfio_nvidia_quirk_mirror_write()
819 LastDataSet *last = (LastDataSet *)&mirror->data; in vfio_nvidia_quirk_mirror_write()
826 * read-only, so we allow writes covering either of those to real hw. in vfio_nvidia_quirk_mirror_write()
828 if ((pdev->cap_present & QEMU_PCI_CAP_MSI) && in vfio_nvidia_quirk_mirror_write()
829 vfio_range_contained(addr, size, pdev->msi_cap, PCI_MSI_FLAGS)) { in vfio_nvidia_quirk_mirror_write()
830 vfio_region_write(&vdev->bars[mirror->bar].region, in vfio_nvidia_quirk_mirror_write()
831 addr + mirror->offset, data, size); in vfio_nvidia_quirk_mirror_write()
832 trace_vfio_quirk_nvidia_bar0_msi_ack(vdev->vbasedev.name); in vfio_nvidia_quirk_mirror_write()
838 * primarily expected to accelerate the MSI-ACK behavior, such as noted in vfio_nvidia_quirk_mirror_write()
843 * MSI-ACK region. Note that as some writes are bypassed via the ioeventfd, in vfio_nvidia_quirk_mirror_write()
850 if (!vdev->no_kvm_ioeventfd && in vfio_nvidia_quirk_mirror_write()
851 addr >= PCI_STD_HEADER_SIZEOF && last->added <= MAX_DYN_IOEVENTFD) { in vfio_nvidia_quirk_mirror_write()
852 if (addr != last->addr || data != last->data || size != last->size) { in vfio_nvidia_quirk_mirror_write()
853 last->addr = addr; in vfio_nvidia_quirk_mirror_write()
854 last->data = data; in vfio_nvidia_quirk_mirror_write()
855 last->size = size; in vfio_nvidia_quirk_mirror_write()
856 last->hits = 1; in vfio_nvidia_quirk_mirror_write()
857 } else if (++last->hits >= HITS_FOR_IOEVENTFD) { in vfio_nvidia_quirk_mirror_write()
858 if (last->added < MAX_DYN_IOEVENTFD) { in vfio_nvidia_quirk_mirror_write()
860 ioeventfd = vfio_ioeventfd_init(vdev, mirror->mem, addr, size, in vfio_nvidia_quirk_mirror_write()
861 data, &vdev->bars[mirror->bar].region, in vfio_nvidia_quirk_mirror_write()
862 mirror->offset + addr, true); in vfio_nvidia_quirk_mirror_write()
864 VFIOQuirk *quirk = last->quirk; in vfio_nvidia_quirk_mirror_write()
866 QLIST_INSERT_HEAD(&quirk->ioeventfds, ioeventfd, next); in vfio_nvidia_quirk_mirror_write()
867 last->added++; in vfio_nvidia_quirk_mirror_write()
870 last->added++; in vfio_nvidia_quirk_mirror_write()
873 "size %u", vdev->vbasedev.name, addr, data, size); in vfio_nvidia_quirk_mirror_write()
887 VFIOConfigMirrorQuirk *mirror = quirk->data; in vfio_nvidia_bar0_quirk_reset()
888 LastDataSet *last = (LastDataSet *)&mirror->data; in vfio_nvidia_bar0_quirk_reset()
890 last->addr = last->data = last->size = last->hits = last->added = 0; in vfio_nvidia_bar0_quirk_reset()
901 if (vdev->no_geforce_quirks || in vfio_probe_nvidia_bar0_quirk()
908 quirk->reset = vfio_nvidia_bar0_quirk_reset; in vfio_probe_nvidia_bar0_quirk()
909 mirror = quirk->data = g_malloc0(sizeof(*mirror) + sizeof(LastDataSet)); in vfio_probe_nvidia_bar0_quirk()
910 mirror->mem = quirk->mem; in vfio_probe_nvidia_bar0_quirk()
911 mirror->vdev = vdev; in vfio_probe_nvidia_bar0_quirk()
912 mirror->offset = 0x88000; in vfio_probe_nvidia_bar0_quirk()
913 mirror->bar = nr; in vfio_probe_nvidia_bar0_quirk()
914 last = (LastDataSet *)&mirror->data; in vfio_probe_nvidia_bar0_quirk()
915 last->quirk = quirk; in vfio_probe_nvidia_bar0_quirk()
917 memory_region_init_io(mirror->mem, OBJECT(vdev), in vfio_probe_nvidia_bar0_quirk()
919 "vfio-nvidia-bar0-88000-mirror-quirk", in vfio_probe_nvidia_bar0_quirk()
920 vdev->config_size); in vfio_probe_nvidia_bar0_quirk()
921 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_nvidia_bar0_quirk()
922 mirror->offset, mirror->mem, 1); in vfio_probe_nvidia_bar0_quirk()
924 QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); in vfio_probe_nvidia_bar0_quirk()
927 if (vdev->vga) { in vfio_probe_nvidia_bar0_quirk()
929 quirk->reset = vfio_nvidia_bar0_quirk_reset; in vfio_probe_nvidia_bar0_quirk()
930 mirror = quirk->data = g_malloc0(sizeof(*mirror) + sizeof(LastDataSet)); in vfio_probe_nvidia_bar0_quirk()
931 mirror->mem = quirk->mem; in vfio_probe_nvidia_bar0_quirk()
932 mirror->vdev = vdev; in vfio_probe_nvidia_bar0_quirk()
933 mirror->offset = 0x1800; in vfio_probe_nvidia_bar0_quirk()
934 mirror->bar = nr; in vfio_probe_nvidia_bar0_quirk()
935 last = (LastDataSet *)&mirror->data; in vfio_probe_nvidia_bar0_quirk()
936 last->quirk = quirk; in vfio_probe_nvidia_bar0_quirk()
938 memory_region_init_io(mirror->mem, OBJECT(vdev), in vfio_probe_nvidia_bar0_quirk()
940 "vfio-nvidia-bar0-1800-mirror-quirk", in vfio_probe_nvidia_bar0_quirk()
942 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_nvidia_bar0_quirk()
943 mirror->offset, mirror->mem, 1); in vfio_probe_nvidia_bar0_quirk()
945 QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); in vfio_probe_nvidia_bar0_quirk()
948 trace_vfio_quirk_nvidia_bar0_probe(vdev->vbasedev.name); in vfio_probe_nvidia_bar0_quirk()
952 * TODO - Some Nvidia devices provide config access to their companion HDA
960 * RTL8168 devices have a backdoor that can access the MSI-X table. At BAR2
962 * register. According to the Linux r8169 driver, the MSI-X table is addressed
966 * ignore because the MSI-X table should always be accessed as a dword (full
971 * Read from MSI-X table offset 0
976 * Write 0xfee00000 to MSI-X table offset 0
992 VFIOPCIDevice *vdev = rtl->vdev; in vfio_rtl8168_quirk_address_read()
993 uint64_t data = vfio_region_read(&vdev->bars[2].region, addr + 0x74, size); in vfio_rtl8168_quirk_address_read()
995 if (rtl->enabled) { in vfio_rtl8168_quirk_address_read()
996 data = rtl->addr ^ 0x80000000U; /* latch/complete */ in vfio_rtl8168_quirk_address_read()
997 trace_vfio_quirk_rtl8168_fake_latch(vdev->vbasedev.name, data); in vfio_rtl8168_quirk_address_read()
1007 VFIOPCIDevice *vdev = rtl->vdev; in vfio_rtl8168_quirk_address_write()
1009 rtl->enabled = false; in vfio_rtl8168_quirk_address_write()
1011 if ((data & 0x7fff0000) == 0x10000) { /* MSI-X table */ in vfio_rtl8168_quirk_address_write()
1012 rtl->enabled = true; in vfio_rtl8168_quirk_address_write()
1013 rtl->addr = (uint32_t)data; in vfio_rtl8168_quirk_address_write()
1016 if (vdev->pdev.cap_present & QEMU_PCI_CAP_MSIX) { in vfio_rtl8168_quirk_address_write()
1018 uint64_t val = rtl->data; in vfio_rtl8168_quirk_address_write()
1020 trace_vfio_quirk_rtl8168_msix_write(vdev->vbasedev.name, in vfio_rtl8168_quirk_address_write()
1023 /* Write to the proper guest MSI-X table instead */ in vfio_rtl8168_quirk_address_write()
1024 memory_region_dispatch_write(&vdev->pdev.msix_table_mmio, in vfio_rtl8168_quirk_address_write()
1029 return; /* Do not write guest MSI-X data to hardware */ in vfio_rtl8168_quirk_address_write()
1033 vfio_region_write(&vdev->bars[2].region, addr + 0x74, data, size); in vfio_rtl8168_quirk_address_write()
1051 VFIOPCIDevice *vdev = rtl->vdev; in vfio_rtl8168_quirk_data_read()
1052 uint64_t data = vfio_region_read(&vdev->bars[2].region, addr + 0x70, size); in vfio_rtl8168_quirk_data_read()
1054 if (rtl->enabled && (vdev->pdev.cap_present & QEMU_PCI_CAP_MSIX)) { in vfio_rtl8168_quirk_data_read()
1055 hwaddr offset = rtl->addr & 0xfff; in vfio_rtl8168_quirk_data_read()
1056 memory_region_dispatch_read(&vdev->pdev.msix_table_mmio, offset, in vfio_rtl8168_quirk_data_read()
1059 trace_vfio_quirk_rtl8168_msix_read(vdev->vbasedev.name, offset, data); in vfio_rtl8168_quirk_data_read()
1069 VFIOPCIDevice *vdev = rtl->vdev; in vfio_rtl8168_quirk_data_write()
1071 rtl->data = (uint32_t)data; in vfio_rtl8168_quirk_data_write()
1073 vfio_region_write(&vdev->bars[2].region, addr + 0x70, data, size); in vfio_rtl8168_quirk_data_write()
1097 quirk->data = rtl = g_malloc0(sizeof(*rtl)); in vfio_probe_rtl8168_bar2_quirk()
1098 rtl->vdev = vdev; in vfio_probe_rtl8168_bar2_quirk()
1100 memory_region_init_io(&quirk->mem[0], OBJECT(vdev), in vfio_probe_rtl8168_bar2_quirk()
1102 "vfio-rtl8168-window-address-quirk", 4); in vfio_probe_rtl8168_bar2_quirk()
1103 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_rtl8168_bar2_quirk()
1104 0x74, &quirk->mem[0], 1); in vfio_probe_rtl8168_bar2_quirk()
1106 memory_region_init_io(&quirk->mem[1], OBJECT(vdev), in vfio_probe_rtl8168_bar2_quirk()
1108 "vfio-rtl8168-window-data-quirk", 4); in vfio_probe_rtl8168_bar2_quirk()
1109 memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, in vfio_probe_rtl8168_bar2_quirk()
1110 0x70, &quirk->mem[1], 1); in vfio_probe_rtl8168_bar2_quirk()
1112 QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); in vfio_probe_rtl8168_bar2_quirk()
1114 trace_vfio_quirk_rtl8168_probe(vdev->vbasedev.name); in vfio_probe_rtl8168_bar2_quirk()
1141 for (i = 0; i < ARRAY_SIZE(vdev->vga->region); i++) { in vfio_vga_quirk_exit()
1142 QLIST_FOREACH(quirk, &vdev->vga->region[i].quirks, next) { in vfio_vga_quirk_exit()
1143 for (j = 0; j < quirk->nr_mem; j++) { in vfio_vga_quirk_exit()
1144 memory_region_del_subregion(&vdev->vga->region[i].mem, in vfio_vga_quirk_exit()
1145 &quirk->mem[j]); in vfio_vga_quirk_exit()
1155 for (i = 0; i < ARRAY_SIZE(vdev->vga->region); i++) { in vfio_vga_quirk_finalize()
1156 while (!QLIST_EMPTY(&vdev->vga->region[i].quirks)) { in vfio_vga_quirk_finalize()
1157 VFIOQuirk *quirk = QLIST_FIRST(&vdev->vga->region[i].quirks); in vfio_vga_quirk_finalize()
1159 for (j = 0; j < quirk->nr_mem; j++) { in vfio_vga_quirk_finalize()
1160 object_unparent(OBJECT(&quirk->mem[j])); in vfio_vga_quirk_finalize()
1162 g_free(quirk->mem); in vfio_vga_quirk_finalize()
1163 g_free(quirk->data); in vfio_vga_quirk_finalize()
1183 VFIOBAR *bar = &vdev->bars[nr]; in vfio_bar_quirk_exit()
1187 QLIST_FOREACH(quirk, &bar->quirks, next) { in vfio_bar_quirk_exit()
1188 while (!QLIST_EMPTY(&quirk->ioeventfds)) { in vfio_bar_quirk_exit()
1189 vfio_ioeventfd_exit(vdev, QLIST_FIRST(&quirk->ioeventfds)); in vfio_bar_quirk_exit()
1192 for (i = 0; i < quirk->nr_mem; i++) { in vfio_bar_quirk_exit()
1193 memory_region_del_subregion(bar->region.mem, &quirk->mem[i]); in vfio_bar_quirk_exit()
1200 VFIOBAR *bar = &vdev->bars[nr]; in vfio_bar_quirk_finalize()
1203 while (!QLIST_EMPTY(&bar->quirks)) { in vfio_bar_quirk_finalize()
1204 VFIOQuirk *quirk = QLIST_FIRST(&bar->quirks); in vfio_bar_quirk_finalize()
1206 for (i = 0; i < quirk->nr_mem; i++) { in vfio_bar_quirk_finalize()
1207 object_unparent(OBJECT(&quirk->mem[i])); in vfio_bar_quirk_finalize()
1209 g_free(quirk->mem); in vfio_bar_quirk_finalize()
1210 g_free(quirk->data); in vfio_bar_quirk_finalize()
1224 VFIOBAR *bar = &vdev->bars[i]; in vfio_quirk_reset()
1226 QLIST_FOREACH(quirk, &bar->quirks, next) { in vfio_quirk_reset()
1227 if (quirk->reset) { in vfio_quirk_reset()
1228 quirk->reset(vdev, quirk); in vfio_quirk_reset()
1263 vfio_region_write(&vdev->bars[5].region, 0x200, 0x80000004, 4); in vfio_radeon_smc_is_running()
1264 clk = vfio_region_read(&vdev->bars[5].region, 0x204, 4); in vfio_radeon_smc_is_running()
1265 vfio_region_write(&vdev->bars[5].region, 0x200, 0x80000370, 4); in vfio_radeon_smc_is_running()
1266 pc_c = vfio_region_read(&vdev->bars[5].region, 0x204, 4); in vfio_radeon_smc_is_running()
1274 * (0 = GFX, 1 = whole GPU), the misc bit is a toggle, with the formula
1284 vfio_region_write(&vdev->bars[5].region, 0x200, 0xc00c0000, 4); in vfio_radeon_set_gfx_only_reset()
1285 fuse = vfio_region_read(&vdev->bars[5].region, 0x204, 4); in vfio_radeon_set_gfx_only_reset()
1288 vfio_region_write(&vdev->bars[5].region, 0x200, 0xc0000010, 4); in vfio_radeon_set_gfx_only_reset()
1289 misc = vfio_region_read(&vdev->bars[5].region, 0x204, 4); in vfio_radeon_set_gfx_only_reset()
1293 vfio_region_write(&vdev->bars[5].region, 0x204, misc ^ 2, 4); in vfio_radeon_set_gfx_only_reset()
1294 vfio_region_read(&vdev->bars[5].region, 0x204, 4); /* flush */ in vfio_radeon_set_gfx_only_reset()
1300 PCIDevice *pdev = &vdev->pdev; in vfio_radeon_reset()
1305 if (vdev->vbasedev.reset_works) { in vfio_radeon_reset()
1306 trace_vfio_quirk_ati_bonaire_reset_skipped(vdev->vbasedev.name); in vfio_radeon_reset()
1307 return -ENODEV; in vfio_radeon_reset()
1315 ret = -EINVAL; in vfio_radeon_reset()
1316 trace_vfio_quirk_ati_bonaire_reset_no_smc(vdev->vbasedev.name); in vfio_radeon_reset()
1320 /* Make sure only the GFX function is reset */ in vfio_radeon_reset()
1329 if (vfio_region_read(&vdev->bars[5].region, 0x5428, 4) != 0xffffffff) { in vfio_radeon_reset()
1335 trace_vfio_quirk_ati_bonaire_reset_timeout(vdev->vbasedev.name); in vfio_radeon_reset()
1339 vfio_region_write(&vdev->bars[5].region, 0x200, 0x80000000, 4); in vfio_radeon_reset()
1340 data = vfio_region_read(&vdev->bars[5].region, 0x204, 4); in vfio_radeon_reset()
1342 vfio_region_write(&vdev->bars[5].region, 0x204, data, 4); in vfio_radeon_reset()
1345 vfio_region_write(&vdev->bars[5].region, 0x200, 0x80000004, 4); in vfio_radeon_reset()
1346 data = vfio_region_read(&vdev->bars[5].region, 0x204, 4); in vfio_radeon_reset()
1348 vfio_region_write(&vdev->bars[5].region, 0x204, data, 4); in vfio_radeon_reset()
1350 trace_vfio_quirk_ati_bonaire_reset_done(vdev->vbasedev.name); in vfio_radeon_reset()
1361 switch (vdev->vendor_id) { in vfio_setup_resetfn_quirk()
1363 switch (vdev->device_id) { in vfio_setup_resetfn_quirk()
1384 vdev->resetfn = vfio_radeon_reset; in vfio_setup_resetfn_quirk()
1385 trace_vfio_quirk_ati_bonaire_reset(vdev->vbasedev.name); in vfio_setup_resetfn_quirk()
1401 * +----------------+----------------+----------------+----------------+
1403 * +----------------+----------------+----------------+----------------+
1405 * +---------------------------------+---------------------------------+
1407 * https://lists.gnu.org/archive/html/qemu-devel/2017-08/pdfUda5iEpgOS.pdf
1410 * https://lists.gnu.org/archive/html/qemu-devel/2023-06/pdf142OR4O4c2.pdf
1434 error_setg(errp, "Property %s: valid range 0-15", name); in set_nv_gpudirect_clique_id()
1443 .description = "NVIDIA GPUDirect Clique ID (0 - 15)",
1451 pos <= (PCI_CFG_SPACE_SIZE - PCI_CAP_SIZEOF)); in is_valid_std_cap_offset()
1457 PCIDevice *pdev = &vdev->pdev; in vfio_add_nv_gpudirect_cap()
1462 if (vdev->nv_gpudirect_clique == 0xFF) { in vfio_add_nv_gpudirect_cap()
1471 if (pci_get_byte(pdev->config + PCI_CLASS_DEVICE + 1) != in vfio_add_nv_gpudirect_cap()
1480 * MSI-X capability at C8h. We don't know how to determine the GPU in vfio_add_nv_gpudirect_cap()
1484 * NB. Cap list head in pdev->config is already cleared, read from device. in vfio_add_nv_gpudirect_cap()
1486 ret = pread(vdev->vbasedev.fd, &tmp, 1, in vfio_add_nv_gpudirect_cap()
1487 vdev->config_offset + PCI_CAPABILITY_LIST); in vfio_add_nv_gpudirect_cap()
1499 tmp = pdev->config[tmp + PCI_CAP_LIST_NEXT]; in vfio_add_nv_gpudirect_cap()
1517 memset(vdev->emulated_config_bits + pos, 0xFF, 8); in vfio_add_nv_gpudirect_cap()
1519 pci_set_byte(pdev->config + pos++, 8); in vfio_add_nv_gpudirect_cap()
1520 pci_set_byte(pdev->config + pos++, 'P'); in vfio_add_nv_gpudirect_cap()
1521 pci_set_byte(pdev->config + pos++, '2'); in vfio_add_nv_gpudirect_cap()
1522 pci_set_byte(pdev->config + pos++, 'P'); in vfio_add_nv_gpudirect_cap()
1523 pci_set_byte(pdev->config + pos++, vdev->nv_gpudirect_clique << 3); in vfio_add_nv_gpudirect_cap()
1524 pci_set_byte(pdev->config + pos, 0); in vfio_add_nv_gpudirect_cap()
1531 * kernel performs enumeration of the VMD sub-device domain. Guest transactions
1532 * to VMD sub-devices go through MMU translation from guest addresses to
1540 * shadow registers in a vendor-specific capability register for devices
1541 * without native support. The position of 0xE8-0xFF is in the reserved range
1560 ret = pread(vdev->vbasedev.fd, membar_phys, 16, in vfio_add_vmd_shadow_cap()
1561 vdev->config_offset + PCI_BASE_ADDRESS_2); in vfio_add_vmd_shadow_cap()
1564 vdev->vbasedev.name, ret); in vfio_add_vmd_shadow_cap()
1568 ret = pci_add_capability(&vdev->pdev, PCI_CAP_ID_VNDR, pos, in vfio_add_vmd_shadow_cap()
1575 memset(vdev->emulated_config_bits + pos, 0xFF, VMD_SHADOW_CAP_LEN); in vfio_add_vmd_shadow_cap()
1577 pci_set_byte(vdev->pdev.config + pos++, VMD_SHADOW_CAP_LEN); in vfio_add_vmd_shadow_cap()
1578 pci_set_byte(vdev->pdev.config + pos++, VMD_SHADOW_CAP_VER); in vfio_add_vmd_shadow_cap()
1579 pci_set_long(vdev->pdev.config + pos, 0x53484457); /* SHDW */ in vfio_add_vmd_shadow_cap()
1580 memcpy(vdev->pdev.config + pos + 4, membar_phys, 16); in vfio_add_vmd_shadow_cap()