All of lore.kernel.org
 help / color / mirror / Atom feed
From: Xiong Zhang <xiong.y.zhang@intel.com>
To: joonas.lahtinen@linux.intel.com, kevin.tian@intel.com,
	daniel.vetter@intel.com, zhenyuw@linux.intel.com,
	jani.nikula@linux.intel.com, alex.williamson@redhat.com
Cc: intel-gfx@lists.freedesktop.org,
	intel-gvt-dev@lists.freedesktop.org, stable@vger.kernel.org,
	Xiong Zhang <xiong.y.zhang@intel.com>
Subject: [PATCH V6] drm/i915: Disable stolen memory when i915 runs in guest vm
Date: Tue, 25 Apr 2017 18:34:45 +0800	[thread overview]
Message-ID: <1493116501-29327-1-git-send-email-xiong.y.zhang@intel.com> (raw)

Stolen memory isn't a standard pci resource and exists in RMRR which has
identity mapping in iommu table when host boot up, so IGD could access
stolen memory in host OS. While according to 'commit c875d2c1b808
("iommu/vt-d: Exclude devices using RMRRs from IOMMU API domains")',RMRR
isn't supported by kvm, then both EPT and guest iommu domain table lack
of maaping for stolen memory in kvm IGD passthrough environment. If IGD
access stolen memory in such environment, many iommu exceptions exist in
host dmesg and gpu hang exists also.
DMAR: [DMA Read] Request device [00:02.0] fault addr da012000
[fault reason 05] PTE Write access is not set
DMAR: [DMA Read] Request device [00:02.0] fault addr da2df000
[fault reason 06] PTE Read access is not set

So stolen memory should be disabled in KVM IGD passthrough environment,
this patch detects such environment through the existence of qemu emulated
isa bridge.

Stolen memory exists in kernel for a long time, and this patch depends
on INTEL_PCH_QEMU_DEVICE_ID_TYPE which was introduced in v4.5 kernel,
so this patch should be backported into v4.5 kernel and later.

v2:GVT-g may run in non qemu (Zhenyu)
v3:Make commit message clear (Daniel)
v4:Fix typo
v5:Exclude P2X as it is used for VMware (Joonas)
v6:Handle real ISA bridge assigned to guest also (Joonas)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99025
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99028

Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.com>
Cc: stable@vger.kernel.org # 4.5+
---
 drivers/gpu/drm/i915/i915_drv.c        | 39 +++++++++++++++++++++++++++-------
 drivers/gpu/drm/i915/i915_drv.h        |  1 +
 drivers/gpu/drm/i915/i915_gem_stolen.c |  4 ++--
 3 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index cc7393e..c0e8968 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -164,31 +164,42 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
 	 *
 	 * In some virtualized environments (e.g. XEN), there is irrelevant
 	 * ISA bridge in the system. To work reliably, we should scan trhough
-	 * all the ISA bridge devices and check for the first match, instead
+	 * all the ISA bridge devices and check for all the match, instead
 	 * of only checking the first one.
+	 *
+	 * If both the real ISA bridge and IGD are assigned to one guest, this
+	 * guest will have two matched ISA bridges: real and emulatated. We
+	 * couldn't guarantee which one is detected first, so we scan all the
+	 * match, instead of only checking the first match. Real one take
+	 * precedence over emulated to set pch_type and pch_id.Emulated one is
+	 * used to disable stolen memory.Finally pci_get_class() will return
+	 * NULL to exit loop and deference the last matched pch.
 	 */
 	while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
 		if (pch->vendor == PCI_VENDOR_ID_INTEL) {
 			unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
-			dev_priv->pch_id = id;
 
 			if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_IBX;
+				dev_priv->pch_id = id;
 				DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
 				WARN_ON(!IS_GEN5(dev_priv));
 			} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_CPT;
+				dev_priv->pch_id = id;
 				DRM_DEBUG_KMS("Found CougarPoint PCH\n");
 				WARN_ON(!(IS_GEN6(dev_priv) ||
 					IS_IVYBRIDGE(dev_priv)));
 			} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
 				/* PantherPoint is CPT compatible */
 				dev_priv->pch_type = PCH_CPT;
+				dev_priv->pch_id = id;
 				DRM_DEBUG_KMS("Found PantherPoint PCH\n");
 				WARN_ON(!(IS_GEN6(dev_priv) ||
 					IS_IVYBRIDGE(dev_priv)));
 			} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_LPT;
+				dev_priv->pch_id = id;
 				DRM_DEBUG_KMS("Found LynxPoint PCH\n");
 				WARN_ON(!IS_HASWELL(dev_priv) &&
 					!IS_BROADWELL(dev_priv));
@@ -196,6 +207,7 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
 					IS_BDW_ULT(dev_priv));
 			} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_LPT;
+				dev_priv->pch_id = id;
 				DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
 				WARN_ON(!IS_HASWELL(dev_priv) &&
 					!IS_BROADWELL(dev_priv));
@@ -203,16 +215,19 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
 					!IS_BDW_ULT(dev_priv));
 			} else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_SPT;
+				dev_priv->pch_id = id;
 				DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
 				WARN_ON(!IS_SKYLAKE(dev_priv) &&
 					!IS_KABYLAKE(dev_priv));
 			} else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_SPT;
+				dev_priv->pch_id = id;
 				DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
 				WARN_ON(!IS_SKYLAKE(dev_priv) &&
 					!IS_KABYLAKE(dev_priv));
 			} else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_KBP;
+				dev_priv->pch_id = id;
 				DRM_DEBUG_KMS("Found KabyPoint PCH\n");
 				WARN_ON(!IS_SKYLAKE(dev_priv) &&
 					!IS_KABYLAKE(dev_priv));
@@ -223,18 +238,26 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
 					    PCI_SUBVENDOR_ID_REDHAT_QUMRANET &&
 				    pch->subsystem_device ==
 					    PCI_SUBDEVICE_ID_QEMU)) {
-				dev_priv->pch_type =
-					intel_virt_detect_pch(dev_priv);
+				/*
+				 * P2X is used for VMware, exclude it
+				 */
+				if (id != INTEL_PCH_P2X_DEVICE_ID_TYPE)
+					dev_priv->disable_stolen = true;
+				/*
+				 * Real PCH still hasn't been detected
+				 */
+				if (!HAS_PCH_SPLIT(dev_priv)) {
+					dev_priv->pch_type =
+						intel_virt_detect_pch(dev_priv);
+					dev_priv->pch_id = id;
+				}
 			} else
 				continue;
 
-			break;
 		}
 	}
-	if (!pch)
+	if (!HAS_PCH_SPLIT(dev_priv))
 		DRM_DEBUG_KMS("No PCH found.\n");
-
-	pci_dev_put(pch);
 }
 
 static int i915_getparam(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 357b6c6..3b8e067 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2132,6 +2132,7 @@ struct drm_i915_private {
 	struct intel_uncore uncore;
 
 	struct i915_virtual_gpu vgpu;
+	bool disable_stolen;
 
 	struct intel_gvt *gvt;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index f3abdc2..bffeae7 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -409,8 +409,8 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
 
 	mutex_init(&dev_priv->mm.stolen_lock);
 
-	if (intel_vgpu_active(dev_priv)) {
-		DRM_INFO("iGVT-g active, disabling use of stolen memory\n");
+	if (dev_priv->disable_stolen || intel_vgpu_active(dev_priv)) {
+		DRM_INFO("Running in guest, disabling use of stolen memory\n");
 		return 0;
 	}
 
-- 
2.7.4

             reply	other threads:[~2017-04-25 10:27 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-25 10:34 Xiong Zhang [this message]
2017-04-25 11:42 ` ✓ Fi.CI.BAT: success for drm/i915: Disable stolen memory when i915 runs in guest vm Patchwork
2017-04-25 12:06 ` [PATCH V6] " Joonas Lahtinen
2017-04-25 12:06   ` Joonas Lahtinen
2017-04-27  5:54   ` Zhang, Xiong Y
2017-05-05  9:14     ` Joonas Lahtinen
     [not found]   ` <8082FF9BCB2B054996454E47167FF4EC1C4D0CAA@SHSMSX104.ccr.corp.intel.com>
2017-05-03  9:22     ` Zhang, Xiong Y
2017-05-03  9:22       ` Zhang, Xiong Y
2017-05-05  9:21       ` Joonas Lahtinen
2017-05-05  9:21         ` Joonas Lahtinen
2017-05-06  2:58         ` Zhang, Xiong Y
2017-05-08 10:07           ` Joonas Lahtinen
2017-05-08 10:07             ` Joonas Lahtinen
2017-05-08 15:01             ` Alex Williamson

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=1493116501-29327-1-git-send-email-xiong.y.zhang@intel.com \
    --to=xiong.y.zhang@intel.com \
    --cc=alex.williamson@redhat.com \
    --cc=daniel.vetter@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-gvt-dev@lists.freedesktop.org \
    --cc=jani.nikula@linux.intel.com \
    --cc=joonas.lahtinen@linux.intel.com \
    --cc=kevin.tian@intel.com \
    --cc=stable@vger.kernel.org \
    --cc=zhenyuw@linux.intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.