From: Tomita Moeko <tomitamo...@gmail.com> x-igd-gms is used for overriding DSM region size in GGC register in both config space and MMIO BAR0, by default host value is used. There is no need to emulate it in default case.
Signed-off-by: Tomita Moeko <tomitamo...@gmail.com> Reviewed-by: Corvin Köhne <c.koe...@beckhoff.com> Reviewed-by: Alex Williamson <alex.william...@redhat.com> Tested-by: Alex Williamson <alex.william...@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250505170305.23622-9-tomitamo...@gmail.com Signed-off-by: Cédric Le Goater <c...@redhat.com> --- hw/vfio/igd.c | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c index 8ad9d723e29cd4d63e12346b6e40604ac020e747..886d44f017f415d5f82c892e630ae2de1637677c 100644 --- a/hw/vfio/igd.c +++ b/hw/vfio/igd.c @@ -478,22 +478,24 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr) return; } - ggc_quirk = vfio_quirk_alloc(1); - ggc_mirror = ggc_quirk->data = g_malloc0(sizeof(*ggc_mirror)); - ggc_mirror->mem = ggc_quirk->mem; - ggc_mirror->vdev = vdev; - ggc_mirror->bar = nr; - ggc_mirror->offset = IGD_GGC_MMIO_OFFSET; - ggc_mirror->config_offset = IGD_GMCH; - - memory_region_init_io(ggc_mirror->mem, OBJECT(vdev), - &vfio_generic_mirror_quirk, ggc_mirror, - "vfio-igd-ggc-quirk", 2); - memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, - ggc_mirror->offset, ggc_mirror->mem, - 1); + if (vdev->igd_gms) { + ggc_quirk = vfio_quirk_alloc(1); + ggc_mirror = ggc_quirk->data = g_malloc0(sizeof(*ggc_mirror)); + ggc_mirror->mem = ggc_quirk->mem; + ggc_mirror->vdev = vdev; + ggc_mirror->bar = nr; + ggc_mirror->offset = IGD_GGC_MMIO_OFFSET; + ggc_mirror->config_offset = IGD_GMCH; - QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, ggc_quirk, next); + memory_region_init_io(ggc_mirror->mem, OBJECT(vdev), + &vfio_generic_mirror_quirk, ggc_mirror, + "vfio-igd-ggc-quirk", 2); + memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, + ggc_mirror->offset, ggc_mirror->mem, + 1); + + QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, ggc_quirk, next); + } bdsm_quirk = vfio_quirk_alloc(1); bdsm_mirror = bdsm_quirk->data = g_malloc0(sizeof(*bdsm_mirror)); @@ -632,9 +634,15 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp) * 32MiB. This option should only be used when the desired size cannot be * set from DVMT Pre-Allocated option in host BIOS. */ - if (vdev->igd_gms && - !vfio_pci_igd_override_gms(gen, vdev->igd_gms, &gmch)) { - return false; + if (vdev->igd_gms) { + if (!vfio_pci_igd_override_gms(gen, vdev->igd_gms, &gmch)) { + return false; + } + + /* GMCH is read-only, emulated */ + pci_set_long(vdev->pdev.config + IGD_GMCH, gmch); + pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0); + pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0); } gms_size = igd_stolen_memory_size(gen, gmch); @@ -652,11 +660,6 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp) fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size", bdsm_size, sizeof(*bdsm_size)); - /* GMCH is read-only, emulated */ - pci_set_long(vdev->pdev.config + IGD_GMCH, gmch); - pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0); - pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0); - /* BDSM is read-write, emulated. The BIOS needs to be able to write it */ if (gen < 11) { pci_set_long(vdev->pdev.config + IGD_BDSM, 0); -- 2.49.0