From nobody Sun Apr 28 13:54:49 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 15234243863971006.2820698059201; Tue, 10 Apr 2018 22:26:26 -0700 (PDT) Received: from localhost ([::1]:51389 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f68Gt-0006Ob-Oc for importer@patchew.org; Wed, 11 Apr 2018 01:26:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47572) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f68Fq-0005sL-QJ for qemu-devel@nongnu.org; Wed, 11 Apr 2018 01:25:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f68Fn-0002d1-Jq for qemu-devel@nongnu.org; Wed, 11 Apr 2018 01:25:10 -0400 Received: from mga01.intel.com ([192.55.52.88]:17456) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1f68Fn-0002ae-7D for qemu-devel@nongnu.org; Wed, 11 Apr 2018 01:25:07 -0400 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Apr 2018 22:25:04 -0700 Received: from test-optiplex-7040.bj.intel.com ([10.238.154.174]) by orsmga002.jf.intel.com with ESMTP; 10 Apr 2018 22:25:02 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,434,1517904000"; d="scan'208";a="49820473" From: Xiong Zhang To: qemu-devel@nongnu.org Date: Wed, 11 Apr 2018 13:24:10 +0800 Message-Id: <1523424250-3835-1-git-send-email-xiong.y.zhang@intel.com> X-Mailer: git-send-email 2.7.4 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 192.55.52.88 Subject: [Qemu-devel] [PATCH] vfio/pci-quirks.c: Make stolen memory size adjustable for igd VFIO X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiong Zhang , alex.williamson@redhat.com, zhi.a.wang@intel.com, zhenyuw@linux.intel.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Currenly linux guest with kernel above 3.19 couldn't boot up on igd passthrough env. The root case is i915 driver use stolen memory, but qemu vfio doesn't support it. This patch set stolen memory size to zero default, so guest i915 won't use it. But this breaks old windows igd driver which will be unloaded once it see zero stolen memory size. Then this patch also use x-igd-gms option to adjust stolen memory size. New windows igd driver fixes this and could work with zero stolen memory size. Finally with this patch, Linux guest and windows guest with igd driver above 15.45.4860 could work successfully, windows guest with igd driver below 15.45.4860 should add x-igd-gms=3D* option. Signed-off-by: Xiong Zhang --- hw/vfio/pci-quirks.c | 95 ++++++++++++++++++++++++++++--------------------= ---- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c index 60ad5fb..6e9ed7f 100644 --- a/hw/vfio/pci-quirks.c +++ b/hw/vfio/pci-quirks.c @@ -1372,14 +1372,60 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice= *vdev, int nr) uint16_t cmd_orig, cmd; Error *err =3D NULL; =20 + /* This must be an Intel VGA device. */ + if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) || + !vfio_is_vga(vdev) || nr !=3D 4) { + return; + } + /* - * 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. + * IGD is not a standard, they like to change their specs often. We + * only attempt to support back to SandBridge and we hope that newer + * devices maintain compatibility with generation 8. */ - if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) || - !vfio_is_vga(vdev) || nr !=3D 4 || - &vdev->pdev !=3D pci_find_device(pci_device_root_bus(&vdev->pdev), + gen =3D igd_gen(vdev); + if (gen !=3D 6 && gen !=3D 8) { + error_report("IGD device %s is unsupported by IGD quirks, " + "try SandyBridge or newer", vdev->vbasedev.name); + return; + } + + /* + * Regardless of running in UPT or legacy mode, the guest graphics + * driver may attempt to use stolen memory, however only legacy mode + * has BIOS support for reserving stolen memory in the guest VM. + * Emulate the GMCH register in all cases and zero out the stolen + * memory size here. + */ + gmch =3D vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4); + gmch &=3D ~((gen < 8 ? 0x1f : 0xff) << (gen < 8 ? 3 : 8)); + + /* + * Assume we have no GMS memory, but allow it to be overrided by device + * option (experimental). Old windows igd driver must see non-zero sto= len + * memory size, otherwise it will be unloaded. New igd windows driver = fix + * this issue and could load with zero stolen memory size. + */ + if (vdev->igd_gms) { + if (vdev->igd_gms <=3D 0x10) { + gms_mb =3D vdev->igd_gms * 32; + gmch |=3D vdev->igd_gms << (gen < 8 ? 3 : 8); + } else { + error_report("Unsupported IGD GMS value 0x%x", vdev->igd_gms); + vdev->igd_gms =3D 0; + } + } + + /* GMCH is read-only, emulated */ + pci_set_long(vdev->pdev.config + IGD_GMCH, gmch); + pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0); + pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0); + + /* + * This must be at address 00:02.0 for us to even onsider enabling + * legacy mode. The vBIOS has dependencies on the PCI bus address. + */ + if (&vdev->pdev !=3D pci_find_device(pci_device_root_bus(&vdev->pdev), 0, PCI_DEVFN(0x2, 0))) { return; } @@ -1399,18 +1445,6 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice = *vdev, int nr) } =20 /* - * IGD is not a standard, they like to change their specs often. We - * only attempt to support back to SandBridge and we hope that newer - * devices maintain compatibility with generation 8. - */ - gen =3D igd_gen(vdev); - if (gen !=3D 6 && gen !=3D 8) { - error_report("IGD device %s is unsupported in legacy mode, " - "try SandyBridge or newer", vdev->vbasedev.name); - return; - } - - /* * 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 supp= ort. @@ -1465,8 +1499,6 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *= vdev, int nr) goto out; } =20 - gmch =3D vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4); - /* * If IGD VGA Disable is clear (expected) and VGA is not already enabl= ed, * try to enable it. Probably shouldn't be using legacy mode without = VGA, @@ -1532,24 +1564,6 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice = *vdev, int nr) } =20 /* - * Assume we have no GMS memory, but allow it to be overrided by device - * option (experimental). The spec doesn't actually allow zero GMS wh= en - * when IVD (IGD VGA Disable) is clear, but the claim is that it's unu= sed, - * so let's not waste VM memory for it. - */ - gmch &=3D ~((gen < 8 ? 0x1f : 0xff) << (gen < 8 ? 3 : 8)); - - if (vdev->igd_gms) { - if (vdev->igd_gms <=3D 0x10) { - gms_mb =3D vdev->igd_gms * 32; - gmch |=3D vdev->igd_gms << (gen < 8 ? 3 : 8); - } else { - error_report("Unsupported IGD GMS value 0x%x", vdev->igd_gms); - vdev->igd_gms =3D 0; - } - } - - /* * Request reserved memory for stolen memory via fw_cfg. VM firmware * must allocate a 1MB aligned reserved memory region below 4GB with * the requested size (in bytes) for use by the Intel PCI class VGA @@ -1562,11 +1576,6 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice = *vdev, int nr) fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size", bdsm_size, sizeof(*bdsm_size)); =20 - /* GMCH is read-only, emulated */ - pci_set_long(vdev->pdev.config + IGD_GMCH, gmch); - pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0); - pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0); - /* BDSM is read-write, emulated. The BIOS needs to be able to write i= t */ pci_set_long(vdev->pdev.config + IGD_BDSM, 0); pci_set_long(vdev->pdev.wmask + IGD_BDSM, ~0); --=20 2.7.4