[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 2/8] vfio/igd: canonicalize memory size calculations
From: |
Tomita Moeko |
Subject: |
Re: [PATCH 2/8] vfio/igd: canonicalize memory size calculations |
Date: |
Tue, 3 Dec 2024 00:48:49 +0800 |
User-agent: |
Mozilla Thunderbird |
On 12/2/24 13:28, Alex Williamson wrote:
> On Mon, 2 Dec 2024 00:09:32 +0800
> Tomita Moeko <tomitamoeko@gmail.com> wrote:
>
>> Add helper functions igd_gtt_memory_size() and igd_stolen_size() for
>> calculating GTT stolen memory and Data stolen memory size in bytes,
>> and use macros to replace the hardware-related magic numbers for
>> better readability.
>>
>> Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
>> ---
>> hw/vfio/igd.c | 101 ++++++++++++++++++++++++++++----------------------
>> 1 file changed, 57 insertions(+), 44 deletions(-)
>>
>> diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
>> index e40e601026..b449316ec0 100644
>> --- a/hw/vfio/igd.c
>> +++ b/hw/vfio/igd.c
>> @@ -116,6 +116,54 @@ typedef struct VFIOIGDQuirk {
>> #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_GEN6_GMS_SHIFT 3
>> +#define IGD_GMCH_GEN6_GMS_MASK 0x1f
>> +#define IGD_GMCH_GEN6_GGMS_SHIFT 8
>> +#define IGD_GMCH_GEN6_GGMS_MASK 0x3
>> +#define IGD_GMCH_GEN8_GMS_SHIFT 8
>> +#define IGD_GMCH_GEN8_GMS_MASK 0xff
>> +#define IGD_GMCH_GEN8_GGMS_SHIFT 6
>> +#define IGD_GMCH_GEN8_GGMS_MASK 0x3
>> +
>> +static uint64_t igd_gtt_memory_size(int gen, uint16_t gmch)
>> +{
>> + uint64_t ggms;
>> +
>> + if (gen < 8) {
>> + ggms = (gmch >> IGD_GMCH_GEN6_GGMS_SHIFT) & IGD_GMCH_GEN6_GGMS_MASK;
>> + } else {
>> + ggms = (gmch >> IGD_GMCH_GEN8_GGMS_SHIFT) & IGD_GMCH_GEN8_GGMS_MASK;
>> + ggms *= 2;
>> + }
>> +
>> + return ggms * MiB;
>> +}
>> +
>> +static uint64_t igd_stolen_memory_size(int gen, uint32_t gmch)
>> +{
>> + uint64_t gms;
>> +
>> + if (gen < 8) {
>> + gms = (gmch >> IGD_GMCH_GEN6_GMS_SHIFT) & IGD_GMCH_GEN6_GMS_MASK;
>> + } else {
>> + gms = (gmch >> IGD_GMCH_GEN8_GMS_SHIFT) & IGD_GMCH_GEN8_GMS_MASK;
>> + }
>> +
>> + if (gen < 9) {
>> + if (gms < 0x10) {
>> + return gms * 32 * MiB;
>> + }
>
> igd_get_stolen_mb() used:
>
> if (gms > 0x10) {
> error_report("Unsupported IGD GMS value 0x%x", gms);
> return 0;
> }
> return gms * 32;
>
> Therefore this should use <= to be equivalent.
Got it, will fix in v2
>> + } else {
>> + if (gms < 0xf0) {
>> + return gms * 32 * MiB;
>> + } else {
>> + return (gms - 0xf0 + 1) * 4 * MiB;
>
> This does not match the line from igd_get_stolen_mb():
>
> return (gms - 0xf0) * 4 + 4;
>
> Explain.
It was changed to return size in bytes, instead of size in MB, to make
the behavior of 2 size calculation functions consistent. Original one
should be changed to.
return ((gms - 0xf0) * 4 + 4) * MiB;
Then I changed it to
return (gms - 0xf0 + 1) * 4 * MiB;
to make it easier to read. gms is uint64, the masked value is 0xff at
most, +1 won't cause overflow here.
>> + }
>> + }
>> +
>> + error_report("Unsupported IGD GMS value 0x%lx", gms);
>> + return 0;
>> +}
>>
>> /*
>> * The rather short list of registers that we copy from the host devices.
>> @@ -264,17 +312,10 @@ static int vfio_pci_igd_lpc_init(VFIOPCIDevice *vdev,
>> static int vfio_igd_gtt_max(VFIOPCIDevice *vdev)
>> {
>> uint32_t gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH,
>> sizeof(gmch));
>> - int ggms, gen = igd_gen(vdev);
>> -
>> - gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, sizeof(gmch));
>> - ggms = (gmch >> (gen < 8 ? 8 : 6)) & 0x3;
>> - if (gen > 7) {
>> - ggms = 1 << ggms;
>> - }
>> -
>> - ggms *= MiB;
>> + int gen = igd_gen(vdev);
>> + uint64_t ggms_size = igd_gtt_memory_size(gen, gmch);
>>
>> - return (ggms / (4 * KiB)) * (gen < 8 ? 4 : 8);
>> + return (ggms_size / (4 * KiB)) * (gen < 8 ? 4 : 8);
>> }
>>
>> /*
>> @@ -481,30 +522,6 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int
>> nr)
>> QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
>> }
>>
>> -static int igd_get_stolen_mb(int gen, uint32_t gmch)
>> -{
>> - int gms;
>> -
>> - if (gen < 8) {
>> - gms = (gmch >> 3) & 0x1f;
>> - } else {
>> - gms = (gmch >> 8) & 0xff;
>> - }
>> -
>> - if (gen < 9) {
>> - if (gms > 0x10) {
>> - error_report("Unsupported IGD GMS value 0x%x", gms);
>> - return 0;
>> - }
>> - return gms * 32;
>> - } else {
>> - if (gms < 0xf0)
>> - return gms * 32;
>> - else
>> - return (gms - 0xf0) * 4 + 4;
>> - }
>> -}
>> -
>> void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
>> {
>> g_autofree struct vfio_region_info *rom = NULL;
>> @@ -514,7 +531,8 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int
>> nr)
>> VFIOQuirk *quirk;
>> VFIOIGDQuirk *igd;
>> PCIDevice *lpc_bridge;
>> - int i, ret, ggms_mb, gms_mb = 0, gen;
>> + int i, ret, gen;
>> + uint64_t ggms_size, gms_size;
>> uint64_t *bdsm_size;
>> uint32_t gmch;
>> uint16_t cmd_orig, cmd;
>> @@ -676,13 +694,8 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int
>> nr)
>>
>> QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
>>
>> - /* Determine the size of stolen memory needed for GTT */
>> - ggms_mb = (gmch >> (gen < 8 ? 8 : 6)) & 0x3;
>> - if (gen > 7) {
>> - ggms_mb = 1 << ggms_mb;
>> - }
>> -
>> - gms_mb = igd_get_stolen_mb(gen, gmch);
>> + ggms_size = igd_gtt_memory_size(gen, gmch);
>> + gms_size = igd_stolen_memory_size(gen, gmch);
>>
>> /*
>> * Request reserved memory for stolen memory via fw_cfg. VM firmware
>> @@ -693,7 +706,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int
>> nr)
>> * config offset 0x5C.
>> */
>> bdsm_size = g_malloc(sizeof(*bdsm_size));
>> - *bdsm_size = cpu_to_le64((ggms_mb + gms_mb) * MiB);
>> + *bdsm_size = cpu_to_le64(ggms_size + gms_size);
>> fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size",
>> bdsm_size, sizeof(*bdsm_size));
>>
>> @@ -744,5 +757,5 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int
>> nr)
>> vdev->vbasedev.name);
>> }
>>
>> - trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb);
>> + trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, *bdsm_size / MiB);
>
> Technically this should use le64_to_cpu(*bdsm_size), or retain the
> addition logic. Thanks,
Got it.
> Alex
>
[PATCH 5/8] vfio/igd: add Alder/Raptor/Rocket/Ice/Jasper Lake device ids, Tomita Moeko, 2024/12/01