qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Cédric Le Goater" <clg@redhat.com>
To: Tomita Moeko <tomitamoeko@gmail.com>,
	Alex Williamson <alex.williamson@redhat.com>
Cc: qemu-devel@nongnu.org, "Corvin Köhne" <corvin.koehne@gmail.com>
Subject: Re: [PATCH v3 07/10] vfio/igd: Decouple common quirks from legacy mode
Date: Mon, 10 Mar 2025 08:13:33 +0100	[thread overview]
Message-ID: <f394edb5-f8f0-4b5f-ab5f-e40c1e8c9f78@redhat.com> (raw)
In-Reply-To: <46b7c8ff-06b3-4e01-a00d-1a388a0bf6a3@gmail.com>

Tomita,

On 3/7/25 19:37, Tomita Moeko wrote:
> On 2025/3/7 6:49, Alex Williamson wrote:
>> On Fri,  7 Mar 2025 02:01:27 +0800
>> Tomita Moeko <tomitamoeko@gmail.com> wrote:
>>
>>> So far, IGD-specific quirks all require enabling legacy mode, which is
>>> toggled by assigning IGD to 00:02.0. However, some quirks, like the BDSM
>>> and GGC register quirks, should be applied to all supported IGD devices.
>>> A new config option, x-igd-legacy-mode=[on|off|auto], is introduced to
>>> control the legacy mode only quirks. The default value is "auto", which
>>> keeps current behavior that enables legacy mode implicitly and continues
>>> on error when all following conditions are met.
>>> * Machine type is i440fx
>>> * IGD device is at guest BDF 00:02.0
>>>
>>> If any one of the conditions above is not met, the default behavior is
>>> equivalent to "off", QEMU will fail immediately if any error occurs.
>>>
>>> Users can also use "on" to force enabling legacy mode. It checks if all
>>> the conditions above are met and set up legacy mode. QEMU will also fail
>>> immediately on error in this case.
>>>
>>> Additionally, the hotplug check in legacy mode is removed as hotplugging
>>> IGD device is never supported, and it will be checked when enabling the
>>> OpRegion quirk.
>>>
>>> Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com>
>>> ---
>>>   hw/vfio/igd.c | 127 +++++++++++++++++++++++++++++---------------------
>>>   hw/vfio/pci.c |   2 +
>>>   hw/vfio/pci.h |   1 +
>>>   3 files changed, 77 insertions(+), 53 deletions(-)
>>>
>>> diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c
>>> index f5e19f1241..ac096e2eb5 100644
>>> --- a/hw/vfio/igd.c
>>> +++ b/hw/vfio/igd.c
>>> @@ -15,6 +15,7 @@
>>>   #include "qemu/error-report.h"
>>>   #include "qapi/error.h"
>>>   #include "qapi/qmp/qerror.h"
>>> +#include "hw/boards.h"
>>>   #include "hw/hw.h"
>>>   #include "hw/nvram/fw_cfg.h"
>>>   #include "pci.h"
>>> @@ -432,9 +433,7 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
>>>        * bus address.
>>>        */
>>>       if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
>>> -        !vfio_is_vga(vdev) || nr != 0 ||
>>> -        &vdev->pdev != pci_find_device(pci_device_root_bus(&vdev->pdev),
>>> -                                       0, PCI_DEVFN(0x2, 0))) {
>>> +        !vfio_is_vga(vdev) || nr != 0) {
>>>           return;
>>>       }
>>>   
>>> @@ -482,14 +481,13 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
>>>       QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, bdsm_quirk, next);
>>>   }
>>>   
>>> -bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
>>> -                                 Error **errp G_GNUC_UNUSED)
>>> +bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp)
>>>   {
>>> -    g_autofree struct vfio_region_info *rom = NULL;
>>>       int ret, gen;
>>>       uint64_t gms_size;
>>>       uint64_t *bdsm_size;
>>>       uint32_t gmch;
>>> +    bool legacy_mode_enabled = false;
>>>       Error *err = NULL;
>>>   
>>>       /*
>>> @@ -498,9 +496,7 @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
>>>        * PCI bus address.
>>>        */
>>>       if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
>>> -        !vfio_is_vga(vdev) ||
>>> -        &vdev->pdev != pci_find_device(pci_device_root_bus(&vdev->pdev),
>>> -                                       0, PCI_DEVFN(0x2, 0))) {
>>> +        !vfio_is_vga(vdev)) {
>>>           return true;
>>>       }
>>>   
>>> @@ -516,56 +512,67 @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
>>>           return true;
>>>       }
>>>   
>>> -    /*
>>> -     * Most of what we're doing here is to enable the ROM to run, so if
>>> -     * there's no ROM, there's no point in setting up this quirk.
>>> -     * NB. We only seem to get BIOS ROMs, so a UEFI VM would need CSM support.
>>> -     */
>>> -    ret = vfio_get_region_info(&vdev->vbasedev,
>>> -                               VFIO_PCI_ROM_REGION_INDEX, &rom);
>>> -    if ((ret || !rom->size) && !vdev->pdev.romfile) {
>>> -        error_report("IGD device %s has no ROM, legacy mode disabled",
>>> -                     vdev->vbasedev.name);
>>> -        return true;
>>> -    }
>>> -
>>> -    /*
>>> -     * Ignore the hotplug corner case, mark the ROM failed, we can't
>>> -     * create the devices we need for legacy mode in the hotplug scenario.
>>> -     */
>>> -    if (vdev->pdev.qdev.hotplugged) {
>>> -        error_report("IGD device %s hotplugged, ROM disabled, "
>>> -                     "legacy mode disabled", vdev->vbasedev.name);
>>> -        vdev->rom_read_failed = true;
>>> -        return true;
>>> -    }
>>> -
>>>       gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4);
>>>   
>>>       /*
>>> -     * If IGD VGA Disable is clear (expected) and VGA is not already enabled,
>>> -     * try to enable it.  Probably shouldn't be using legacy mode without VGA,
>>> -     * but also no point in us enabling VGA if disabled in hardware.
>>> +     * For backward compatibilty, enable legacy mode when
>>> +     * - Machine type is i440fx (pc_piix)
>>> +     * - IGD device is at guest BDF 00:02.0
>>> +     * - Not manually disabled by x-igd-legacy-mode=off
>>>        */
>>> -    if (!(gmch & 0x2) && !vdev->vga && !vfio_populate_vga(vdev, &err)) {
>>> -        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 true;
>>> -    }
>>> +    if ((vdev->igd_legacy_mode != ON_OFF_AUTO_OFF) &&
>>> +        !strcmp(MACHINE_GET_CLASS(qdev_get_machine())->family, "pc_piix") &&
>>> +        (&vdev->pdev == pci_find_device(pci_device_root_bus(&vdev->pdev),
>>> +        0, PCI_DEVFN(0x2, 0)))) {
>>> +        /*
>>> +         * IGD legacy mode requires:
>>> +         * - VBIOS in ROM BAR or file
>>> +         * - VGA IO/MMIO ranges are claimed by IGD
>>> +         * - OpRegion
>>> +         * - Same LPC bridge and Host bridge VID/DID/SVID/SSID as host
>>> +         */
>>> +        g_autofree struct vfio_region_info *rom = NULL;
>>> +
>>> +        legacy_mode_enabled = true;
>>> +        warn_report("IGD legacy mode enabled, "
>>> +                    "use x-igd-legacy-mode=off to disable it if unwanted.");
>>
>> info_report() maybe?  These aren't great choices for a user, get a
>> warning for using the intended mode or silence that warning by
>> requiring experimental options that taint the VM relative to libvirt.
> 
> Got it. If possible, please help change this to info_report when
> applying.

done.


> 
>> Also, why do we list all the requirements then only test a few of them
>> before declaring we're using legacy mode?  It seems like the above
>> should be moved to the end of this branch.
> 
> Having i440fx machine type and BDF 00:02.0 are the must-have condition
> for considering enabling legacy mode, while others are the requirements
> for legacy mode itself. In this verison, legacy mode is equivalent to
>      romfile=oprom.bin,x-vga=on,x-igd-opregion=on,x-igd-lpc=on
> 
> BDF being 00:02.0 is a requirement of VBIOS, and hacking the LPC DID
> currently only works on i440fx. Though for Q35, we can overwrite the
> existing ICH9 LPC DID to make IGD driver happy, it won't break ACPI PM
> in recent guest kernel, and maybe later making it an option for Q35,
> its still too risky to make it an implicit default. That's why I prefer
> to check the must-have condtions first, then check other requirements
> when setting up them.
> 
> Setting the `legacy_mode_enabled` flag here is for error handling, as
> we have to keep the old "continue on error" behavior for legacy mode.

A ducomentation update is welcome ! Could you do that before hard-freeze ?

Thanks,

C.






>> Given the pending release deadline, maybe these aren't blockers, but
>> let's follow-up with something that assumes the user wants something
>> other than what they're doing.  Thanks,
>>
>> Alex
>>
> 
> Sure.
> 
> Moeko
>   
>>> +
>>> +        /*
>>> +         * Most of what we're doing here is to enable the ROM to run, so if
>>> +         * there's no ROM, there's no point in setting up this quirk.
>>> +         * NB. We only seem to get BIOS ROMs, so UEFI VM would need CSM support.
>>> +         */
>>> +        ret = vfio_get_region_info(&vdev->vbasedev,
>>> +                                   VFIO_PCI_ROM_REGION_INDEX, &rom);
>>> +        if ((ret || !rom->size) && !vdev->pdev.romfile) {
>>> +            error_setg(&err, "Device has no ROM");
>>> +            goto error;
>>> +        }
>>>   
>>> -    /* Setup OpRegion access */
>>> -    if (!vfio_pci_igd_setup_opregion(vdev, &err)) {
>>> -        error_append_hint(&err, "IGD legacy mode disabled\n");
>>> -        error_report_err(err);
>>> -        return true;
>>> -    }
>>> +        /*
>>> +         * If IGD VGA Disable is clear (expected) and VGA is not already
>>> +         * enabled, try to enable it. Probably shouldn't be using legacy mode
>>> +         * without VGA, but also no point in us enabling VGA if disabled in
>>> +         * hardware.
>>> +         */
>>> +        if (!(gmch & 0x2) && !vdev->vga && !vfio_populate_vga(vdev, &err)) {
>>> +            error_setg(&err, "Unable to enable VGA access");
>>> +            goto error;
>>> +        }
>>>   
>>> -    /* Setup LPC bridge / Host bridge PCI IDs */
>>> -    if (!vfio_pci_igd_setup_lpc_bridge(vdev, &err)) {
>>> -        error_append_hint(&err, "IGD legacy mode disabled\n");
>>> -        error_report_err(err);
>>> -        return true;
>>> +        /* Setup OpRegion access */
>>> +        if (!vfio_pci_igd_setup_opregion(vdev, &err)) {
>>> +            goto error;
>>> +        }
>>> +
>>> +        /* Setup LPC bridge / Host bridge PCI IDs */
>>> +        if (!vfio_pci_igd_setup_lpc_bridge(vdev, &err)) {
>>> +            goto error;
>>> +        }
>>> +    } else if (vdev->igd_legacy_mode == ON_OFF_AUTO_ON) {
>>> +        error_setg(&err,
>>> +                   "Machine is not i440fx or assigned BDF is not 00:02.0");
>>> +        goto error;
>>>       }
>>>   
>>>       /*
>>> @@ -627,4 +634,18 @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
>>>       trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, (gms_size / MiB));
>>>   
>>>       return true;
>>> +
>>> +error:
>>> +    /*
>>> +     * When legacy mode is implicity enabled, continue on error,
>>> +     * to keep compatibility
>>> +     */
>>> +    if (legacy_mode_enabled && (vdev->igd_legacy_mode == ON_OFF_AUTO_AUTO)) {
>>> +        error_report_err(err);
>>> +        error_report("IGD legacy mode disabled");
>>> +        return true;
>>> +    }
>>> +
>>> +    error_propagate(errp, err);
>>> +    return false;
>>>   }
>>> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
>>> index a58d555934..d5ff8c1ea8 100644
>>> --- a/hw/vfio/pci.c
>>> +++ b/hw/vfio/pci.c
>>> @@ -3363,6 +3363,8 @@ static const Property vfio_pci_dev_properties[] = {
>>>                       VFIO_FEATURE_ENABLE_REQ_BIT, true),
>>>       DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
>>>                       VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
>>> +    DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice,
>>> +                            igd_legacy_mode, ON_OFF_AUTO_AUTO),
>>>       DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
>>>                               vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
>>>       DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
>>> diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
>>> index 2e81f9eb19..aa67ceb346 100644
>>> --- a/hw/vfio/pci.h
>>> +++ b/hw/vfio/pci.h
>>> @@ -158,6 +158,7 @@ struct VFIOPCIDevice {
>>>       uint32_t display_xres;
>>>       uint32_t display_yres;
>>>       int32_t bootindex;
>>> +    OnOffAuto igd_legacy_mode;
>>>       uint32_t igd_gms;
>>>       OffAutoPCIBAR msix_relo;
>>>       uint8_t pm_cap;
>>
> 



  reply	other threads:[~2025-03-10  7:14 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-06 18:01 [PATCH v3 00/10] vfio/igd: Decoupling quirks with legacy mode Tomita Moeko
2025-03-06 18:01 ` [PATCH v3 01/10] vfio/igd: Remove GTT write quirk in IO BAR 4 Tomita Moeko
2025-03-06 18:01 ` [PATCH v3 02/10] vfio/igd: Do not include GTT stolen size in etc/igd-bdsm-size Tomita Moeko
2025-03-06 18:01 ` [PATCH v3 03/10] vfio/igd: Consolidate OpRegion initialization into a single function Tomita Moeko
2025-03-06 18:01 ` [PATCH v3 04/10] vfio/igd: Move LPC bridge initialization to a separate function Tomita Moeko
2025-03-06 18:01 ` [PATCH v3 05/10] vfio/pci: Add placeholder for device-specific config space quirks Tomita Moeko
2025-03-06 18:01 ` [PATCH v3 06/10] vfio/igd: Refactor vfio_probe_igd_bar4_quirk into pci config quirk Tomita Moeko
2025-03-06 18:01 ` [PATCH v3 07/10] vfio/igd: Decouple common quirks from legacy mode Tomita Moeko
2025-03-06 22:49   ` Alex Williamson
2025-03-07 18:37     ` Tomita Moeko
2025-03-10  7:13       ` Cédric Le Goater [this message]
2025-03-10  8:03         ` Tomita Moeko
2025-03-06 18:01 ` [PATCH v3 08/10] vfio/igd: Handle x-igd-opregion option in config quirk Tomita Moeko
2025-03-06 18:01 ` [PATCH v3 09/10] vfio/igd: Introduce x-igd-lpc option for LPC bridge ID quirk Tomita Moeko
2025-03-06 18:01 ` [PATCH v3 10/10] vfio/igd: Fix broken KVMGT OpRegion support Tomita Moeko
2025-03-06 22:49 ` [PATCH v3 00/10] vfio/igd: Decoupling quirks with legacy mode Alex Williamson
2025-03-07  7:17   ` Corvin Köhne
2025-03-07  8:04 ` Cédric Le Goater

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f394edb5-f8f0-4b5f-ab5f-e40c1e8c9f78@redhat.com \
    --to=clg@redhat.com \
    --cc=alex.williamson@redhat.com \
    --cc=corvin.koehne@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=tomitamoeko@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).