[PATCH v4] vfio/igd: Make MTL/ARL guests fall back to BAR-based framebuffer access

Yuan Wang posted 1 patch 4 days, 13 hours ago
There is a newer version of this series
hw/vfio/igd.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 46 insertions(+), 3 deletions(-)
[PATCH v4] vfio/igd: Make MTL/ARL guests fall back to BAR-based framebuffer access
Posted by Yuan Wang 4 days, 13 hours ago
Meteor Lake and Arrow Lake GOP can read BAR0 MMIO offset 0x138914 to
detect whether direct framebuffer access via DSM is available.

In a VFIO passthrough VM, the guest cannot access the host DSM memory
region via such a pointer. If the guest GOP enables that path, it may
hand off a DSM-based framebuffer address that the guest cannot actually
use.

Intercept reads from the detection register and return 0 so the guest
does not enable the DSM-based path and instead keeps using the standard
BAR-based framebuffer address.

Suggested-by: Tomita Moeko <tomitamoeko@gmail.com>
Reviewed-by: Tomita Moeko <tomitamoeko@gmail.com>
Reviewed-by: Bosheng Xue <bosheng.xue@intel.com>
Reviewed-by: Junjie Cao <junjie.cao@intel.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Yuan Wang <yuan1.wang@intel.com>
---
Changes:
v4:
- Address review comments from Tomita Moeko (update macro/variable
  names and comments).
- Pick up Reviewed-by tags from Tomita Moeko and Cédric Le Goater.

v3:
- Emulated register 0x138914 to return 0x0, which signals the guest
  GOP driver to fall back to BAR-based mapping since DSM is
  unavailable in the VM.

v2:
- Resending because the v1 patch was sent with an incorrect future
  system timestamp due to an unsynchronized local clock. No code
  changes.

Notes:
MTL/ARL device IDs remain in igd_gen().
This is required because vfio_probe_igd_bar0_quirk() checks the
generation before installing BAR0 quirks, and the 0x138914 quirk
is added afterward.
Meanwhile, we also plan to remove the bdsm-size check in the OVMF
offline patches.
---
 hw/vfio/igd.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 3 deletions(-)

diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 413a49aae9..fe9ffc93c8 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -96,6 +96,8 @@ static int igd_gen(VFIOPCIDevice *vdev)
     case 0x4C00:    /* Rocket Lake */
     case 0x4600:    /* Alder Lake */
     case 0xA700:    /* Raptor Lake */
+    case 0x7D00:    /* Meteor Lake / Arrow Lake */
+    case 0xB600:    /* Arrow Lake */
         return 12;
     }
 
@@ -452,12 +454,34 @@ static bool vfio_pci_igd_override_gms(int gen, uint32_t gms, uint32_t *gmch)
     return ret;
 }
 
-#define IGD_GGC_MMIO_OFFSET     0x108040
-#define IGD_BDSM_MMIO_OFFSET    0x1080C0
+#define IGD_GGC_MMIO_OFFSET         0x108040
+#define IGD_BDSM_MMIO_OFFSET        0x1080C0
+#define IGD_MTL_PCODE_STOLEN_ACCESS 0x138914
+
+#define IGD_IS_MTL_OR_ARL(vdev) \
+    ((((vdev)->device_id & 0xff00) == 0x7d00) || \
+     (((vdev)->device_id & 0xff00) == 0xb600))
+
+static uint64_t vfio_igd_pcode_stolen_access_read(void *opaque, hwaddr addr,
+                                                  unsigned size)
+{
+    return 0;
+}
+
+static void vfio_igd_pcode_stolen_access_write(void *opaque, hwaddr addr,
+                                               uint64_t data, unsigned size)
+{
+}
+
+static const MemoryRegionOps vfio_igd_pcode_stolen_access_quirk = {
+    .read = vfio_igd_pcode_stolen_access_read,
+    .write = vfio_igd_pcode_stolen_access_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
 
 void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
 {
-    VFIOQuirk *ggc_quirk, *bdsm_quirk;
+    VFIOQuirk *ggc_quirk, *bdsm_quirk, *pcode_stolen_access_quirk;
     VFIOConfigMirrorQuirk *ggc_mirror, *bdsm_mirror;
     int gen;
 
@@ -472,6 +496,25 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
         return;
     }
 
+    /*
+     * MTL/ARL guests must keep using the BAR-based framebuffer address.
+     * Return 0 for PCODE stolen memory access detection (0x138914) so GOP
+     * stays on the standard access path in the VM.
+     */
+    if (IGD_IS_MTL_OR_ARL(vdev)) {
+        pcode_stolen_access_quirk = vfio_quirk_alloc(1);
+        memory_region_init_io(pcode_stolen_access_quirk->mem, OBJECT(vdev),
+                              &vfio_igd_pcode_stolen_access_quirk, vdev,
+                              "vfio-igd-pcode-stolen-access-quirk", 4);
+        memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
+                                            IGD_MTL_PCODE_STOLEN_ACCESS,
+                                            pcode_stolen_access_quirk->mem,
+                                            1);
+
+        QLIST_INSERT_HEAD(&vdev->bars[nr].quirks,
+                          pcode_stolen_access_quirk, next);
+    }
+
     if (vdev->igd_gms) {
         ggc_quirk = vfio_quirk_alloc(1);
         ggc_mirror = ggc_quirk->data = g_malloc0(sizeof(*ggc_mirror));
-- 
2.34.1


Re: [PATCH v4] vfio/igd: Make MTL/ARL guests fall back to BAR-based framebuffer access
Posted by Cédric Le Goater 4 days, 9 hours ago
Hello Yuan

On 9/22/26 07:36, Yuan Wang wrote:
> Meteor Lake and Arrow Lake GOP can read BAR0 MMIO offset 0x138914 to
> detect whether direct framebuffer access via DSM is available.
> 
> In a VFIO passthrough VM, the guest cannot access the host DSM memory
> region via such a pointer. If the guest GOP enables that path, it may
> hand off a DSM-based framebuffer address that the guest cannot actually
> use.
> 
> Intercept reads from the detection register and return 0 so the guest
> does not enable the DSM-based path and instead keeps using the standard
> BAR-based framebuffer address.
> 
> Suggested-by: Tomita Moeko <tomitamoeko@gmail.com>
> Reviewed-by: Tomita Moeko <tomitamoeko@gmail.com>
> Reviewed-by: Bosheng Xue <bosheng.xue@intel.com>
> Reviewed-by: Junjie Cao <junjie.cao@intel.com>
> Reviewed-by: Cédric Le Goater <clg@redhat.com>
> Signed-off-by: Yuan Wang <yuan1.wang@intel.com>
> ---
> Changes:
> v4:
> - Address review comments from Tomita Moeko (update macro/variable
>    names and comments).
> - Pick up Reviewed-by tags from Tomita Moeko and Cédric Le Goater.
> 
> v3:
> - Emulated register 0x138914 to return 0x0, which signals the guest
>    GOP driver to fall back to BAR-based mapping since DSM is
>    unavailable in the VM.
> 
> v2:
> - Resending because the v1 patch was sent with an incorrect future
>    system timestamp due to an unsynchronized local clock. No code
>    changes.
> 
> Notes:
> MTL/ARL device IDs remain in igd_gen().
> This is required because vfio_probe_igd_bar0_quirk() checks the
> generation before installing BAR0 quirks, and the 0x138914 quirk
> is added afterward.
> Meanwhile, we also plan to remove the bdsm-size check in the OVMF
> offline patches.
> ---
>   hw/vfio/igd.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
>   1 file changed, 46 insertions(+), 3 deletions(-)


This change does not apply cleanly on :

     https://github.com/legoater/qemu vfio-next

because of :

   https://lore.kernel.org/qemu-devel/20260724102959.1043264-1-mike.malyshev@gmail.com/

Could you please resend on top ?

Thanks,

C.


Re: [PATCH v4] vfio/igd: Make MTL/ARL guests fall back to BAR-based framebuffer access
Posted by Wang, Yuan1 3 days, 13 hours ago
On 9/22/2026 5:56 PM, Cédric Le Goater wrote:
> Hello Yuan
>
> On 9/22/26 07:36, Yuan Wang wrote:
>> Meteor Lake and Arrow Lake GOP can read BAR0 MMIO offset 0x138914 to
>> detect whether direct framebuffer access via DSM is available.
>>
>> In a VFIO passthrough VM, the guest cannot access the host DSM memory
>> region via such a pointer. If the guest GOP enables that path, it may
>> hand off a DSM-based framebuffer address that the guest cannot actually
>> use.
>>
>> Intercept reads from the detection register and return 0 so the guest
>> does not enable the DSM-based path and instead keeps using the standard
>> BAR-based framebuffer address.
>>
>> Suggested-by: Tomita Moeko <tomitamoeko@gmail.com>
>> Reviewed-by: Tomita Moeko <tomitamoeko@gmail.com>
>> Reviewed-by: Bosheng Xue <bosheng.xue@intel.com>
>> Reviewed-by: Junjie Cao <junjie.cao@intel.com>
>> Reviewed-by: Cédric Le Goater <clg@redhat.com>
>> Signed-off-by: Yuan Wang <yuan1.wang@intel.com>
>> ---
>> Changes:
>> v4:
>> - Address review comments from Tomita Moeko (update macro/variable
>>    names and comments).
>> - Pick up Reviewed-by tags from Tomita Moeko and Cédric Le Goater.
>>
>> v3:
>> - Emulated register 0x138914 to return 0x0, which signals the guest
>>    GOP driver to fall back to BAR-based mapping since DSM is
>>    unavailable in the VM.
>>
>> v2:
>> - Resending because the v1 patch was sent with an incorrect future
>>    system timestamp due to an unsynchronized local clock. No code
>>    changes.
>>
>> Notes:
>> MTL/ARL device IDs remain in igd_gen().
>> This is required because vfio_probe_igd_bar0_quirk() checks the
>> generation before installing BAR0 quirks, and the 0x138914 quirk
>> is added afterward.
>> Meanwhile, we also plan to remove the bdsm-size check in the OVMF
>> offline patches.
>> ---
>>   hw/vfio/igd.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
>>   1 file changed, 46 insertions(+), 3 deletions(-)
>
>
> This change does not apply cleanly on :
>
>     https://github.com/legoater/qemu vfio-next
>
> because of :
>
> https://lore.kernel.org/qemu-devel/20260724102959.1043264-1-mike.malyshev@gmail.com/
>
> Could you please resend on top ?
>
>
Sure! I have rebased the patch on top of your vfio-next branch and sent out v5.

Please kindly review the v5.

Thanks,
Yuan