From nobody Mon Feb 9 17:05:03 2026 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.zoho.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 (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1496047033641867.358278935109; Mon, 29 May 2017 01:37:13 -0700 (PDT) Received: from localhost ([::1]:47474 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dFGAo-0008Mp-QZ for importer@patchew.org; Mon, 29 May 2017 04:37:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57029) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dFG73-0005hA-KT for qemu-devel@nongnu.org; Mon, 29 May 2017 04:33:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dFG72-0004uy-IS for qemu-devel@nongnu.org; Mon, 29 May 2017 04:33:17 -0400 Received: from mga02.intel.com ([134.134.136.20]:12385) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dFG72-0004sQ-6C for qemu-devel@nongnu.org; Mon, 29 May 2017 04:33:16 -0400 Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 May 2017 01:33:15 -0700 Received: from inno-nuc.bj.intel.com ([10.238.154.169]) by fmsmga004.fm.intel.com with ESMTP; 29 May 2017 01:33:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.38,413,1491289200"; d="scan'208";a="267607784" From: Zhi Wang To: qemu-devel@nongnu.org Date: Tue, 30 May 2017 01:30:33 +0800 Message-Id: <1496079043-26694-4-git-send-email-zhi.a.wang@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1496079043-26694-1-git-send-email-zhi.a.wang@intel.com> References: <1496079043-26694-1-git-send-email-zhi.a.wang@intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.20 Subject: [Qemu-devel] [RFC 3/6] vfio: Setup IGD stolen memory 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: kevin.tian@intel.com, daniel.vetter@ffwll.ch, joonas.lahtinen@linux.intel.com, zhenyuw@linux.intel.com, zhiyuan.lv@intel.com, chuanxiao.dong@intel.com, xiong.y.zhang@intel.com, Zhi Wang 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" We still keep using VM dedicated memory for isolation to support IGD stolen in the guest. Becuase of the PA of the stolen memory can not be moved after the system is powered-up, we wish the PA of the guest stolen memory can sit in the same PA of host. A new memory region is allocated, and the memory region will be marked as reserved in guest E820 table. We don't need to take care of GGMS, as the accesses to GGMS from HW bypass IOMMU. Suggested-by: Xiong Zhang Signed-off-by: Zhi Wang --- hw/vfio/pci-quirks.c | 83 ++++++++++++++++++------------------------------= ---- 1 file changed, 29 insertions(+), 54 deletions(-) diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c index e0a0c13..5a083c1 100644 --- a/hw/vfio/pci-quirks.c +++ b/hw/vfio/pci-quirks.c @@ -18,6 +18,7 @@ #include "pci.h" #include "trace.h" #include "intel-platform.h" +#include "hw/i386/pc.h" =20 /* Use uin32_t for vendor & device so PCI_ANY_ID expands and cannot match = hw */ static bool vfio_pci_is(VFIOPCIDevice *vdev, uint32_t vendor, uint32_t dev= ice) @@ -1362,9 +1363,10 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice = *vdev, int nr) VFIOQuirk *quirk; VFIOIGDQuirk *igd; const struct intel_device_info *info; + void *stolen; PCIDevice *lpc_bridge; - int i, ret, ggms_mb, gms_mb =3D 0, gen; - uint64_t *bdsm_size; + int i, ret; + uint64_t bdsm_size; uint32_t gmch; uint16_t cmd_orig, cmd; Error *err =3D NULL; @@ -1393,16 +1395,38 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice= *vdev, int nr) return; } =20 - gen =3D info->gen; - /* Setup our quirk to munge GTT addresses to the VM allocated buffer */ quirk =3D g_malloc0(sizeof(*quirk)); + quirk->mem =3D g_new0(MemoryRegion, 1); + quirk->nr_mem =3D 1; + igd =3D quirk->data =3D g_malloc0(sizeof(*igd)); igd->vdev =3D vdev; igd->index =3D ~0; igd->bdsm =3D vfio_pci_read_config(&vdev->pdev, IGD_BDSM, 4); igd->bdsm &=3D ~((1 << 20) - 1); /* 1MB aligned */ =20 + /* Setup stolen memory for IGD device. */ + gmch =3D vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4); + bdsm_size =3D info->get_stolen_size(gmch); + + stolen =3D qemu_memalign(bdsm_size, bdsm_size); + + memory_region_init_ram_ptr(&quirk->mem[0], OBJECT(vdev), + "vfio-igd-stolen", bdsm_size, stolen); + memory_region_add_subregion_overlap(get_system_memory(), + igd->bdsm, &quirk->mem[0], 1); + + e820_add_entry(igd->bdsm, bdsm_size, E820_RESERVED); + + /* GMCH is read-only, emulated */ + pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0); + pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0); + + /* BDSM is read-only, emulated */ + pci_set_long(vdev->pdev.wmask + IGD_BDSM, 0); + pci_set_long(vdev->emulated_config_bits + IGD_BDSM, ~0); + /* * We need to create an LPC/ISA bridge at PCI bus address 00:1f.0 that= we * can stuff host values into, so if there's already one there and it'= s not @@ -1472,8 +1496,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, @@ -1528,53 +1550,6 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice = *vdev, int nr) =20 QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); =20 - /* Determine the size of stolen memory needed for GTT */ - ggms_mb =3D (gmch >> (gen < 8 ? 8 : 6)) & 0x3; - if (gen > 6) { - ggms_mb =3D 1 << ggms_mb; - } - - /* - * 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 - * device at VM address 00:02.0. The base address of this reserved - * memory region must be written to the device BDSM regsiter at PCI - * config offset 0x5C. - */ - bdsm_size =3D g_malloc(sizeof(*bdsm_size)); - *bdsm_size =3D cpu_to_le64((ggms_mb + gms_mb) * 1024 * 1024); - fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size", - bdsm_size, sizeof(*bdsm_size)); - - /* 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); - pci_set_long(vdev->emulated_config_bits + IGD_BDSM, ~0); - /* * This IOBAR gives us access to GTTADR, which allows us to write to * the GTT itself. So let's go ahead and write zero to all the GTT @@ -1606,7 +1581,7 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *= vdev, int nr) vdev->vbasedev.name); } =20 - trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, ggms_mb + gms_mb); + trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, bdsm_size >> 20); =20 out: g_free(rom); --=20 2.7.4