@@ -426,15 +426,8 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr)
VFIOConfigMirrorQuirk *ggc_mirror, *bdsm_mirror;
int gen;
- /*
- * This must be an Intel VGA device at address 00:02.0 for us to even
- * consider enabling legacy mode. Some driver have dependencies on the PCI
- * 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,24 +475,15 @@ 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)
{
int gen;
uint64_t gms_size;
uint64_t *bdsm_size;
uint32_t gmch;
- Error *err = NULL;
- /*
- * This must be an Intel VGA device at address 00:02.0 for us to even
- * consider enabling legacy mode. The vBIOS has dependencies on the
- * 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;
}
@@ -510,23 +494,19 @@ bool vfio_probe_igd_config_quirk(VFIOPCIDevice *vdev,
*/
gen = igd_gen(vdev);
if (gen == -1) {
- error_report("IGD device %s is unsupported in legacy mode, "
- "try SandyBridge or newer", vdev->vbasedev.name);
return true;
}
/* 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 ((vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) &&
+ !vfio_pci_igd_setup_opregion(vdev, errp)) {
+ return false;
}
/* 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;
+ if ((vdev->features & VFIO_FEATURE_ENABLE_IGD_LPC) &&
+ !vfio_pci_igd_setup_lpc_bridge(vdev, errp)) {
+ return false;
}
gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4);
@@ -3136,15 +3136,6 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
vfio_bar_quirk_setup(vdev, i);
}
-#ifdef CONFIG_VFIO_IGD
- if (!vdev->igd_opregion &&
- vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) {
- if (!vfio_pci_igd_setup_opregion(vdev, errp)) {
- goto out_unset_idev;
- }
- }
-#endif
-
/* QEMU emulates all of MSI & MSIX */
if (pdev->cap_present & QEMU_PCI_CAP_MSIX) {
memset(vdev->emulated_config_bits + pdev->msix_cap, 0xff,
@@ -3363,6 +3354,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_BIT("x-igd-lpc", VFIOPCIDevice, features,
+ VFIO_FEATURE_ENABLE_IGD_LPC_BIT, false),
DEFINE_PROP_ON_OFF_AUTO("enable-migration", VFIOPCIDevice,
vbasedev.enable_migration, ON_OFF_AUTO_AUTO),
DEFINE_PROP_BOOL("migration-events", VFIOPCIDevice,
@@ -154,6 +154,9 @@ struct VFIOPCIDevice {
#define VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT 2
#define VFIO_FEATURE_ENABLE_IGD_OPREGION \
(1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT)
+#define VFIO_FEATURE_ENABLE_IGD_LPC_BIT 3
+#define VFIO_FEATURE_ENABLE_IGD_LPC \
+ (1 << VFIO_FEATURE_ENABLE_IGD_LPC_BIT)
OnOffAuto display;
uint32_t display_xres;
uint32_t display_yres;
IGD-specific quirks are implicitly enabled by legacy mode, which is toggled by assigning IGD to 00:02.0. This patch replaces legacy mode with explicit options for these quirks. The OpRegion quirk is merged to the exisiting x-igd-opregion option, while a new option x-igd-lpc is defined for the LPC bridge / Host bridge ID quirk. The BDSM and GGC register quirks is applied to all known IGD devices. BDSM register, which contains HPA (meaningless to guest), is initialized to 0. GGC register is just a copy if x-igd-gms is not specified. Unlike legacy mode, these options do not require IGD BDF being 00:02.0, but guest drivers like EFI GOP driver still hardcodes the BDF. It is highly recommended to assign IGD to 00:02.0. Signed-off-by: Tomita Moeko <tomitamoeko@gmail.com> --- hw/vfio/igd.c | 38 +++++++++----------------------------- hw/vfio/pci.c | 11 ++--------- hw/vfio/pci.h | 3 +++ 3 files changed, 14 insertions(+), 38 deletions(-)