On 1/31/25 17:14, Cédric Le Goater wrote:
> Hello Tomita,
> 
> On 1/24/25 20:12, Tomita Moeko wrote:
>> The actual IO BAR4 write quirk in vfio_probe_igd_bar4_quirk() was
>> removed in previous change, leaving the function not matching its name,
>> so move it into the newly introduced vfio_config_quirk_setup(). There
>> is no functional change in this commit. If any failure occurs, the
>> function simply returns and proceeds.
>>
>> Signed-off-by: Tomita Moeko <tomitamo...@gmail.com>
>> ---
>>   hw/vfio/igd.c        | 31 +++++++++++++++++--------------
>>   hw/vfio/pci-quirks.c |  6 +++++-
>>   hw/vfio/pci.h        |  2 +-
>>   3 files changed, 23 insertions(+), 16 deletions(-)
>>
>> diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
>> index ca3a32f4f2..376a26fbae 100644
>> --- a/hw/vfio/igd.c
>> +++ b/hw/vfio/igd.c
>> @@ -359,7 +359,8 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>       QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, bdsm_quirk, next);
>>   }
>>   -void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
>> +bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
>> +                                 Error **errp G_GNUC_UNUSED)
> 
> Adding an 'Error **' parameter is in improvement indeed. All the error_report
> of this routine need to be converted too.

Sorry I missed this mail previously.

Originally this function simply return and continue on error, I prefer
keeping current behavior until legacy mode was finally removed, as I
described in my reply to Alex. At that point, this function will
terminate and report on error.
 
>>   {
>>       g_autofree struct vfio_region_info *rom = NULL;
>>       g_autofree struct vfio_region_info *opregion = NULL;
>> @@ -378,10 +379,10 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, 
>> int nr)
>>        * PCI bus address.
>>        */
>>       if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
>> -        !vfio_is_vga(vdev) || nr != 4 ||
>> +        !vfio_is_vga(vdev) ||
>>           &vdev->pdev != pci_find_device(pci_device_root_bus(&vdev->pdev),
>>                                          0, PCI_DEVFN(0x2, 0))) {
>> -        return;
>> +        return true;
>>       }
>>         /*
>> @@ -395,7 +396,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>                                              "vfio-pci-igd-lpc-bridge")) {
>>           error_report("IGD device %s cannot support legacy mode due to 
>> existing "
>>                        "devices at address 1f.0", vdev->vbasedev.name);
>> -        return;
>> +        return true;
> 
> if there is an error_report, why is this returning true ? It should be false.

Please see my comment above
  
>>       }
>>         /*
>> @@ -407,7 +408,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>       if (gen == -1) {
>>           error_report("IGD device %s is unsupported in legacy mode, "
>>                        "try SandyBridge or newer", vdev->vbasedev.name);
>> -        return;
>> +        return true;
> 
> same here and else where.
> 
>>       }
>>         /*
>> @@ -420,7 +421,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>       if ((ret || !rom->size) && !vdev->pdev.romfile) {
>>           error_report("IGD device %s has no ROM, legacy mode disabled",
>>                        vdev->vbasedev.name);
>> -        return;
>> +        return true;
>>       }
>>         /*
>> @@ -431,7 +432,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>           error_report("IGD device %s hotplugged, ROM disabled, "
>>                        "legacy mode disabled", vdev->vbasedev.name);
>>           vdev->rom_read_failed = true;
>> -        return;
>> +        return true;
>>       }
>>         /*
>> @@ -444,7 +445,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>       if (ret) {
>>           error_report("IGD device %s does not support OpRegion access,"
>>                        "legacy mode disabled", vdev->vbasedev.name);
>> -        return;
>> +        return true;
>>       }
>>         ret = vfio_get_dev_region_info(&vdev->vbasedev,
>> @@ -453,7 +454,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>       if (ret) {
>>           error_report("IGD device %s does not support host bridge access,"
>>                        "legacy mode disabled", vdev->vbasedev.name);
>> -        return;
>> +        return true;
>>       }
>>         ret = vfio_get_dev_region_info(&vdev->vbasedev,
>> @@ -462,7 +463,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>       if (ret) {
>>           error_report("IGD device %s does not support LPC bridge access,"
>>                        "legacy mode disabled", vdev->vbasedev.name);
>> -        return;
>> +        return true;
>>       }
>>         gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4);
>> @@ -476,7 +477,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>           error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
>>           error_report("IGD device %s failed to enable VGA access, "
>>                        "legacy mode disabled", vdev->vbasedev.name);
>> -        return;
>> +        return true;
>>       }
>>         /* Create our LPC/ISA bridge */
>> @@ -484,7 +485,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>       if (ret) {
>>           error_report("IGD device %s failed to create LPC bridge, "
>>                        "legacy mode disabled", vdev->vbasedev.name);
>> -        return;
>> +        return true;
>>       }
>>         /* Stuff some host values into the VM PCI host bridge */
>> @@ -492,14 +493,14 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, 
>> int nr)
>>       if (ret) {
>>           error_report("IGD device %s failed to modify host bridge, "
>>                        "legacy mode disabled", vdev->vbasedev.name);
>> -        return;
>> +        return true;
>>       }
>>         /* Setup OpRegion access */
>>       if (!vfio_pci_igd_opregion_init(vdev, opregion, &err)) {
>>           error_append_hint(&err, "IGD legacy mode disabled\n");
>>           error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
>> -        return;
>> +        return true;
>>       }
>>         /*
>> @@ -561,4 +562,6 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int 
>> nr)
>>         trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name,
>>                                       (ggms_size + gms_size) / MiB);
>> +
>> +    return true;
>>   }
>> diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
>> index c40e3ca88f..b8379cb512 100644
>> --- a/hw/vfio/pci-quirks.c
>> +++ b/hw/vfio/pci-quirks.c
>> @@ -1169,6 +1169,11 @@ bool vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
>>    */
>>   bool vfio_config_quirk_setup(VFIOPCIDevice *vdev, Error **errp)
>>   {
>> +#ifdef CONFIG_VFIO_IGD
> 
> oh. We try to avoid such ifdef in QEMU. Only very specific and high level
> configs are discarded at compile time (KVM, LINUX, etc).

This ifdef has been in QEMU code, for only building igd-related code
into x86 target (VFIO_IGD is only seleted when PC_PCI=on, and I440FX/
Q35 selests PC_PCI). IMO using the ifdef here is reasonable, as IGD
quirks is a part of vfio-pci, but using QOM in furure would be a
good direction.

> One way to adress this case, would be to use QOM. Example below :
> 
>  
> Declare a base class :
>         #define TYPE_VFIO_PCI_QUIRK_PROVIDER "vfio-pci-quirk-provider"
>         OBJECT_DECLARE_TYPE(VFIOPCIQuirkProvider, VFIOPCIQuirkProviderClass,
>                         VFIO_PCI_QUIRK_PROVIDER)
>         struct VFIOPCIQuirkProviderClass {
>         ObjectClass parent;
>             bool (*probe)(VFIOPCIDevice *vdev, Error **errp);
>         bool (*setup)(VFIOPCIDevice *vdev, Error **errp);
>     };
>         static const TypeInfo vfio_pci_quirk_info = {
>         .name = TYPE_VFIO_PCI_QUIRK_PROVIDER,
>         .parent = TYPE_OBJECT,
>         .class_size = sizeof(VFIOPCIQuirkClass),
>         .abstract = true,
>     };
>         static void register_vfio_pci_quirk_type(void)
>     {
>         type_register_static(&vfio_pci_quirk_info);
>     }
>         type_init(register_vfio_pci_quirk_type)
> 
> 
> Declare one for IGD
>         static void vfio_pci_quirk_igd_class_init(ObjectClass *klass, void 
> *data)
>     {
>         VFIOPCIQuirkClass* vpqc = VFIO_PCI_QUIRK_PROVIDER_CLASS(klass);
>             vpqc->setup = vfio_probe_igd_quirk_probe;
>         vpqc->probe = vfio_probe_igd_quirk_probe;
>     }
>         static const TypeInfo vfio_pci_quirk_igd_info = {
>         .name = TYPE_VFIO_PCI_QUIRK_PROVIDER "-igd",
>         .parent = TYPE_VFIO_PCI_QUIRK_PROVIDER,
>         .class_init = vfio_pci_quirk_igd_class_init,
>         .class_size = sizeof(VFIOPCIQuirkClass),
>     };
>         static void vfio_pci_quirk_igd_register_types(void)
>     {
>         type_register_static(&vfio_pci_quirk_igd_info);
>     }
>         type_init(vfio_pci_quirk_igd_register_types)
> 
> 
> and in the common part, loop on all the classes to probe and setup :
> 
> 
>     static void vfio_pci_quirk_class_foreach(ObjectClass *klass, void *opaque)
>     {
>         VFIOPCIQuirkProviderClass* vpqc = 
> VFIO_PCI_QUIRK_PROVIDER_CLASS(klass);
>         Error *local_err = NULL;
>             vpqc->setup(opaque, &local_err);
>     }
>         bool vfio_config_quirk_setup(VFIOPCIDevice *vdev, Error **errp)
>     {
>         object_class_foreach(vfio_pci_quirk_class_foreach,
>                              TYPE_VFIO_PCI_QUIRK_PROVIDER, false, vdev);
>        ...
> 
> 
> 
> 
> Thanks,
> 
> C.
> 
> 


Reply via email to