diff options
Diffstat (limited to 'hw/vfio')
-rw-r--r-- | hw/vfio/cpr.c | 2 | ||||
-rw-r--r-- | hw/vfio/display.c | 4 | ||||
-rw-r--r-- | hw/vfio/igd.c | 19 | ||||
-rw-r--r-- | hw/vfio/pci.c | 31 | ||||
-rw-r--r-- | hw/vfio/pci.h | 13 | ||||
-rw-r--r-- | hw/vfio/types.h | 23 | ||||
-rw-r--r-- | hw/vfio/vfio-migration-internal.h | 1 |
7 files changed, 69 insertions, 24 deletions
diff --git a/hw/vfio/cpr.c b/hw/vfio/cpr.c index af0f12a..384b56c 100644 --- a/hw/vfio/cpr.c +++ b/hw/vfio/cpr.c @@ -116,6 +116,8 @@ static int vfio_cpr_pci_post_load(void *opaque, int version_id) PCIDevice *pdev = &vdev->pdev; int nr_vectors; + vfio_sub_page_bar_update_mappings(vdev); + if (msix_enabled(pdev)) { vfio_pci_msix_set_notifiers(vdev); nr_vectors = vdev->msix->entries; diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 9c6f5aa..faacd90 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -365,7 +365,7 @@ static bool vfio_display_dmabuf_init(VFIOPCIDevice *vdev, Error **errp) &vfio_display_dmabuf_ops, vdev); if (vdev->enable_ramfb) { - vdev->dpy->ramfb = ramfb_setup(errp); + vdev->dpy->ramfb = ramfb_setup(vdev->use_legacy_x86_rom, errp); if (!vdev->dpy->ramfb) { return false; } @@ -494,7 +494,7 @@ static bool vfio_display_region_init(VFIOPCIDevice *vdev, Error **errp) &vfio_display_region_ops, vdev); if (vdev->enable_ramfb) { - vdev->dpy->ramfb = ramfb_setup(errp); + vdev->dpy->ramfb = ramfb_setup(vdev->use_legacy_x86_rom, errp); if (!vdev->dpy->ramfb) { return false; } diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c index e7a9d1f..ee0767b 100644 --- a/hw/vfio/igd.c +++ b/hw/vfio/igd.c @@ -113,6 +113,7 @@ static int igd_gen(VFIOPCIDevice *vdev) #define IGD_BDSM 0x5c /* Base Data of Stolen Memory */ #define IGD_BDSM_GEN11 0xc0 /* Base Data of Stolen Memory of gen 11 and later */ +#define IGD_GMCH_VGA_DISABLE BIT(1) #define IGD_GMCH_GEN6_GMS_SHIFT 3 /* SNB_GMCH in i915 */ #define IGD_GMCH_GEN6_GMS_MASK 0x1f #define IGD_GMCH_GEN8_GMS_SHIFT 8 /* BDW_GMCH in i915 */ @@ -533,12 +534,14 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp) /* * For backward compatibility, enable legacy mode when * - Device geneation is 6 to 9 (including both) + * - IGD claims VGA cycles on host * - Machine type is i440fx (pc_piix) * - IGD device is at guest BDF 00:02.0 * - Not manually disabled by x-igd-legacy-mode=off */ if ((vdev->igd_legacy_mode != ON_OFF_AUTO_OFF) && (gen >= 6 && gen <= 9) && + !(gmch & IGD_GMCH_VGA_DISABLE) && !strcmp(MACHINE_GET_CLASS(qdev_get_machine())->family, "pc_piix") && (&vdev->pdev == pci_find_device(pci_device_root_bus(&vdev->pdev), 0, PCI_DEVFN(0x2, 0)))) { @@ -568,14 +571,16 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp) } /* - * If IGD VGA Disable is clear (expected) and VGA is not already - * enabled, try to enable it. Probably shouldn't be using legacy mode - * without VGA, but also no point in us enabling VGA if disabled in - * hardware. + * If VGA is not already enabled, try to enable it. We shouldn't be + * using legacy mode without VGA. */ - if (!(gmch & 0x2) && !vdev->vga && !vfio_populate_vga(vdev, &err)) { - error_setg(&err, "Unable to enable VGA access"); - goto error; + if (!vdev->vga) { + if (vfio_populate_vga(vdev, &err)) { + vfio_pci_config_register_vga(vdev); + } else { + error_setg(&err, "Unable to enable VGA access"); + goto error; + } } /* Enable OpRegion and LPC bridge quirk */ diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index be05002..4fa692c 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -49,8 +49,6 @@ #include "vfio-migration-internal.h" #include "vfio-helpers.h" -#define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug" - /* Protected by BQL */ static KVMRouteChange vfio_route_change; @@ -2826,6 +2824,20 @@ static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f) return ret; } +void vfio_sub_page_bar_update_mappings(VFIOPCIDevice *vdev) +{ + PCIDevice *pdev = &vdev->pdev; + int page_size = qemu_real_host_page_size(); + int bar; + + for (bar = 0; bar < PCI_ROM_SLOT; bar++) { + PCIIORegion *r = &pdev->io_regions[bar]; + if (r->addr != PCI_BAR_UNMAPPED && r->size > 0 && r->size < page_size) { + vfio_sub_page_bar_update_mapping(pdev, bar); + } + } +} + static VFIODeviceOps vfio_pci_ops = { .vfio_compute_needs_reset = vfio_pci_compute_needs_reset, .vfio_hot_reset_multi = vfio_pci_hot_reset_multi, @@ -3150,6 +3162,15 @@ static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev) vdev->req_enabled = false; } +void vfio_pci_config_register_vga(VFIOPCIDevice *vdev) +{ + assert(vdev->vga != NULL); + + pci_register_vga(&vdev->pdev, &vdev->vga->region[QEMU_PCI_VGA_MEM].mem, + &vdev->vga->region[QEMU_PCI_VGA_IO_LO].mem, + &vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem); +} + bool vfio_pci_config_setup(VFIOPCIDevice *vdev, Error **errp) { PCIDevice *pdev = &vdev->pdev; @@ -3271,9 +3292,7 @@ bool vfio_pci_config_setup(VFIOPCIDevice *vdev, Error **errp) vfio_bars_register(vdev); if (vdev->vga && vfio_is_vga(vdev)) { - pci_register_vga(&vdev->pdev, &vdev->vga->region[QEMU_PCI_VGA_MEM].mem, - &vdev->vga->region[QEMU_PCI_VGA_IO_LO].mem, - &vdev->vga->region[QEMU_PCI_VGA_IO_HI].mem); + vfio_pci_config_register_vga(vdev); } return true; @@ -3849,6 +3868,8 @@ static const TypeInfo vfio_pci_dev_info = { static const Property vfio_pci_dev_nohotplug_properties[] = { DEFINE_PROP_BOOL("ramfb", VFIOPCIDevice, enable_ramfb, false), + DEFINE_PROP_BOOL("use-legacy-x86-rom", VFIOPCIDevice, + use_legacy_x86_rom, false), DEFINE_PROP_ON_OFF_AUTO("x-ramfb-migrate", VFIOPCIDevice, ramfb_migrate, ON_OFF_AUTO_AUTO), }; diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index 4aa6461..81465a8 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -14,6 +14,7 @@ #include "system/memory.h" #include "hw/pci/pci_device.h" +#include "hw/vfio/types.h" #include "hw/vfio/vfio-device.h" #include "hw/vfio/vfio-region.h" #include "qemu/event_notifier.h" @@ -119,17 +120,8 @@ typedef struct VFIOMSIXInfo { MemoryRegion *pba_region; } VFIOMSIXInfo; -/* - * TYPE_VFIO_PCI_BASE is an abstract type used to share code - * between VFIO implementations that use a kernel driver - * with those that use user sockets. - */ -#define TYPE_VFIO_PCI_BASE "vfio-pci-base" OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI_BASE) -#define TYPE_VFIO_PCI "vfio-pci" -/* TYPE_VFIO_PCI shares struct VFIOPCIDevice. */ - struct VFIOPCIDevice { PCIDevice pdev; VFIODevice vbasedev; @@ -189,6 +181,7 @@ struct VFIOPCIDevice { bool no_kvm_ioeventfd; bool no_vfio_ioeventfd; bool enable_ramfb; + bool use_legacy_x86_rom; OnOffAuto ramfb_migrate; bool defer_kvm_irq_routing; bool clear_parent_atomics_on_exit; @@ -226,6 +219,7 @@ void vfio_pci_write_config(PCIDevice *pdev, uint64_t vfio_vga_read(void *opaque, hwaddr addr, unsigned size); void vfio_vga_write(void *opaque, hwaddr addr, uint64_t data, unsigned size); +void vfio_sub_page_bar_update_mappings(VFIOPCIDevice *vdev); bool vfio_opt_rom_in_denylist(VFIOPCIDevice *vdev); bool vfio_config_quirk_setup(VFIOPCIDevice *vdev, Error **errp); void vfio_vga_quirk_setup(VFIOPCIDevice *vdev); @@ -259,6 +253,7 @@ extern const VMStateDescription vfio_display_vmstate; void vfio_pci_bars_exit(VFIOPCIDevice *vdev); bool vfio_pci_add_capabilities(VFIOPCIDevice *vdev, Error **errp); +void vfio_pci_config_register_vga(VFIOPCIDevice *vdev); bool vfio_pci_config_setup(VFIOPCIDevice *vdev, Error **errp); bool vfio_pci_interrupt_setup(VFIOPCIDevice *vdev, Error **errp); void vfio_pci_intx_eoi(VFIODevice *vbasedev); diff --git a/hw/vfio/types.h b/hw/vfio/types.h new file mode 100644 index 0000000..c19334f --- /dev/null +++ b/hw/vfio/types.h @@ -0,0 +1,23 @@ +/* + * VFIO types definition + * + * Copyright Red Hat, Inc. 2025 + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef HW_VFIO_VFIO_TYPES_H +#define HW_VFIO_VFIO_TYPES_H + +/* + * TYPE_VFIO_PCI_BASE is an abstract type used to share code + * between VFIO implementations that use a kernel driver + * with those that use user sockets. + */ +#define TYPE_VFIO_PCI_BASE "vfio-pci-base" + +#define TYPE_VFIO_PCI "vfio-pci" +/* TYPE_VFIO_PCI shares struct VFIOPCIDevice. */ + +#define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug" + +#endif /* HW_VFIO_VFIO_TYPES_H */ diff --git a/hw/vfio/vfio-migration-internal.h b/hw/vfio/vfio-migration-internal.h index 54141e2..814fbd9 100644 --- a/hw/vfio/vfio-migration-internal.h +++ b/hw/vfio/vfio-migration-internal.h @@ -13,7 +13,6 @@ #include <linux/vfio.h> #endif -#include "qemu/typedefs.h" #include "qemu/notify.h" /* |