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;
>>
>
next prev parent 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).