diff mbox series

[8/8] vfio/igd: add x-igd-gms option back to set DSM region size for guest

Message ID 20241201160938.44355-9-tomitamoeko@gmail.com (mailing list archive)
State New
Headers show
Series vfio/igd: Enable legacy mode on more devices | expand

Commit Message

Tomita Moeko Dec. 1, 2024, 4:09 p.m. UTC
DSM region is likely to store framebuffer in Windows, a small DSM
region may cause display issues (e.g. half of the screen is black).
By default, QEMU uses host's original value, which is determined by
DVMT Pre-Allocated option in Intel FSP of host bios. Some vendors
do not expose this config item to users. In such cases, x-igd-gms
option can be used to manually set the data stolen memory size for
guest.

When DVMT Pre-Allocated option is available in host BIOS, user should
set DSM region size there instead of using x-igd-gms option.

Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
---
 hw/vfio/igd.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

Comments

Corvin Köhne Dec. 2, 2024, 9:48 a.m. UTC | #1
On Mon, 2024-12-02 at 00:09 +0800, Tomita Moeko wrote:
> CAUTION: External Email!!
> DSM region is likely to store framebuffer in Windows, a small DSM
> region may cause display issues (e.g. half of the screen is black).
> By default, QEMU uses host's original value, which is determined by
> DVMT Pre-Allocated option in Intel FSP of host bios. Some vendors
> do not expose this config item to users. In such cases, x-igd-gms
> option can be used to manually set the data stolen memory size for
> guest.
> 
> When DVMT Pre-Allocated option is available in host BIOS, user should
> set DSM region size there instead of using x-igd-gms option.
> 
> Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
> ---
>  hw/vfio/igd.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
> index 3fd822241d..614223123b 100644
> --- a/hw/vfio/igd.c
> +++ b/hw/vfio/igd.c
> @@ -712,6 +712,23 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
>  
>      QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
>  
> +    /*
> +     * Allow user to override dsm size using x-igd-gms option, in multiples of
> +     * 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) {
> +        if (gen < 8 && vdev->igd_gms <= 0x10) {
> +            gmch &= ~(IGD_GMCH_GEN6_GMS_MASK << IGD_GMCH_GEN6_GMS_SHIFT);
> +            gmch |= vdev->igd_gms << IGD_GMCH_GEN6_GMS_SHIFT;
> +        } else if (vdev->igd_gms <= 0x40) {
> +            gmch &= ~(IGD_GMCH_GEN8_GMS_MASK << IGD_GMCH_GEN8_GMS_SHIFT);
> +            gmch |= vdev->igd_gms << IGD_GMCH_GEN8_GMS_SHIFT;
> +        } else {
> +            error_report("Unsupported IGD GMS value 0x%x", vdev->igd_gms);
> +        }
> +    }
> +
>      ggms_size = igd_gtt_memory_size(gen, gmch);
>      gms_size = igd_stolen_memory_size(gen, gmch);
>  

As mentioned in my commit removing the x-igd-gms option, I've seen issues on Windows guest when
setting a wrong gms value. I can try to recheck this.
Tomita Moeko Dec. 2, 2024, 6:11 p.m. UTC | #2
On 12/2/24 17:48, Corvin Köhne wrote:
> On Mon, 2024-12-02 at 00:09 +0800, Tomita Moeko wrote:
>> CAUTION: External Email!!
>> DSM region is likely to store framebuffer in Windows, a small DSM
>> region may cause display issues (e.g. half of the screen is black).
>> By default, QEMU uses host's original value, which is determined by
>> DVMT Pre-Allocated option in Intel FSP of host bios. Some vendors
>> do not expose this config item to users. In such cases, x-igd-gms
>> option can be used to manually set the data stolen memory size for
>> guest.
>>
>> When DVMT Pre-Allocated option is available in host BIOS, user should
>> set DSM region size there instead of using x-igd-gms option.
>>
>> Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
>> ---
>>  hw/vfio/igd.c | 17 +++++++++++++++++
>>  1 file changed, 17 insertions(+)
>>
>> diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
>> index 3fd822241d..614223123b 100644
>> --- a/hw/vfio/igd.c
>> +++ b/hw/vfio/igd.c
>> @@ -712,6 +712,23 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
>>  
>>      QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
>>  
>> +    /*
>> +     * Allow user to override dsm size using x-igd-gms option, in multiples of
>> +     * 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) {
>> +        if (gen < 8 && vdev->igd_gms <= 0x10) {
>> +            gmch &= ~(IGD_GMCH_GEN6_GMS_MASK << IGD_GMCH_GEN6_GMS_SHIFT);
>> +            gmch |= vdev->igd_gms << IGD_GMCH_GEN6_GMS_SHIFT;
>> +        } else if (vdev->igd_gms <= 0x40) {
>> +            gmch &= ~(IGD_GMCH_GEN8_GMS_MASK << IGD_GMCH_GEN8_GMS_SHIFT);
>> +            gmch |= vdev->igd_gms << IGD_GMCH_GEN8_GMS_SHIFT;
>> +        } else {
>> +            error_report("Unsupported IGD GMS value 0x%x", vdev->igd_gms);
>> +        }
>> +    }
>> +
>>      ggms_size = igd_gtt_memory_size(gen, gmch);
>>      gms_size = igd_stolen_memory_size(gen, gmch);
>>  
> 
> As mentioned in my commit removing the x-igd-gms option, I've seen issues on Windows guest when
> setting a wrong gms value. I can try to recheck this.
> 

What's the windows GPU driver version you're using? I am using latest
32.0.101.6299. My DVMT Pre-allocated is 64M in BIOS. When using
default value, with a 4K display, strange behaviors were discovered
during my tests, like the lower half (actuall about 1/3) of the
screen is black, 3D mark only runs at 2560*1440 and the refresh rate
was limited to 30Hz.  Restarting guest won't fix this, but when I
forcefully set the GMS size in emulated GGC to 128M, these issue
disappears. That's why I suspect DSM may contain framebuffer.

Per my result, it seems windows guest is using the DSM as something
like dedicated VRAM, and GPU itself can handle guest physical address
internally.

The OVMF firmware I use is
https://github.com/tomitamoeko/edk2/commits/igd-pt-adl/
with GOP driver extracted from bios image from motherboard vendor.

I'm also wondering why the BAR4 quirks were implemented before, GTT
are not located in DSM, but in GGMS size below BDSM. This region is
inaccessible directly, reading it via /dev/mem immediately hangs the
system. The only way to access GTT is via MMIO BAR0.
diff mbox series

Patch

diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
index 3fd822241d..614223123b 100644
--- a/hw/vfio/igd.c
+++ b/hw/vfio/igd.c
@@ -712,6 +712,23 @@  void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
 
     QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
 
+    /*
+     * Allow user to override dsm size using x-igd-gms option, in multiples of
+     * 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) {
+        if (gen < 8 && vdev->igd_gms <= 0x10) {
+            gmch &= ~(IGD_GMCH_GEN6_GMS_MASK << IGD_GMCH_GEN6_GMS_SHIFT);
+            gmch |= vdev->igd_gms << IGD_GMCH_GEN6_GMS_SHIFT;
+        } else if (vdev->igd_gms <= 0x40) {
+            gmch &= ~(IGD_GMCH_GEN8_GMS_MASK << IGD_GMCH_GEN8_GMS_SHIFT);
+            gmch |= vdev->igd_gms << IGD_GMCH_GEN8_GMS_SHIFT;
+        } else {
+            error_report("Unsupported IGD GMS value 0x%x", vdev->igd_gms);
+        }
+    }
+
     ggms_size = igd_gtt_memory_size(gen, gmch);
     gms_size = igd_stolen_memory_size(gen, gmch);