All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Auld <matthew.auld@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Subject: [PATCH 5/9] drm/i915: make dsm struct resource centric
Date: Tue,  5 Dec 2017 21:02:45 +0000	[thread overview]
Message-ID: <20171205210249.8875-6-matthew.auld@intel.com> (raw)
In-Reply-To: <20171205210249.8875-1-matthew.auld@intel.com>

Now that we are using struct resource to track the stolen region, it is
more convenient if we track dsm in a resource as well.

v2: check range_overflow when writing to 32b registers (Chris)
    pepper in some comments (Chris)
v3: refit i915_stolen_to_dma()

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h        | 13 ++++--
 drivers/gpu/drm/i915/i915_gem_stolen.c | 84 +++++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_fbc.c       | 10 +++-
 drivers/gpu/drm/i915/intel_pm.c        | 17 +++++--
 4 files changed, 72 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 594fd14e66c5..39c8e99f3d3a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1537,9 +1537,6 @@ struct i915_gem_mm {
 	 */
 	struct pagevec wc_stash;
 
-	/** Usable portion of the GTT for GEM */
-	dma_addr_t stolen_base; /* limited to low memory (32-bit) */
-
 	/**
 	 * tmpfs instance used for shmem backed objects
 	 */
@@ -2253,6 +2250,16 @@ struct drm_i915_private {
 
 	const struct intel_device_info info;
 
+	/**
+	 * Data Stolen Memory - aka "i915 stolen memory" gives us the start and
+	 * end of stolen which we can optionally use to create GEM objects
+	 * backed by stolen memory. Note that ggtt->stolen_usable_size tells us
+	 * exactly how much of this we are actually allowed to use, given that
+	 * some portion of it is in fact reserved for use by hardware functions,
+	 * while ggtt->stolen_size gives us the total size of the stolen region.
+	 */
+	struct resource dsm;
+
 	void __iomem *regs;
 
 	struct intel_uncore uncore;
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index f8ac1438c35d..eb84db633a23 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -76,27 +76,27 @@ void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv,
 	mutex_unlock(&dev_priv->mm.stolen_lock);
 }
 
-static dma_addr_t i915_stolen_to_dma(struct drm_i915_private *dev_priv)
+static int i915_adjust_stolen(struct drm_i915_private *dev_priv,
+			      struct resource *dsm)
 {
 	struct i915_ggtt *ggtt = &dev_priv->ggtt;
-	dma_addr_t base = intel_graphics_stolen_res.start;
+	dma_addr_t base = dsm->start;
 	struct resource *r;
 
 	GEM_BUG_ON(overflows_type(intel_graphics_stolen_res.start, base));
 
 	if (base == 0 || add_overflows(base, ggtt->stolen_size))
-		return 0;
+		return -EINVAL;
 
 	/* make sure we don't clobber the GTT if it's within stolen memory */
 	if (INTEL_GEN(dev_priv) <= 4 &&
 	    !IS_G33(dev_priv) && !IS_PINEVIEW(dev_priv) && !IS_G4X(dev_priv)) {
-		struct {
-			dma_addr_t start, end;
-		} stolen[2] = {
-			{ .start = base, .end = base + ggtt->stolen_size, },
-			{ .start = base, .end = base + ggtt->stolen_size, },
+		struct resource stolen[2] = {
+			DEFINE_RES_MEM(base, ggtt->stolen_size),
+			DEFINE_RES_MEM(base, ggtt->stolen_size),
 		};
-		u64 ggtt_start, ggtt_end;
+		struct resource ggtt_res;
+		u64 ggtt_start;
 
 		ggtt_start = I915_READ(PGTBL_CTL);
 		if (IS_GEN4(dev_priv))
@@ -104,36 +104,31 @@ static dma_addr_t i915_stolen_to_dma(struct drm_i915_private *dev_priv)
 				     (ggtt_start & PGTBL_ADDRESS_HI_MASK) << 28;
 		else
 			ggtt_start &= PGTBL_ADDRESS_LO_MASK;
-		ggtt_end = ggtt_start + ggtt_total_entries(ggtt) * 4;
 
-		if (ggtt_start >= stolen[0].start && ggtt_start < stolen[0].end)
-			stolen[0].end = ggtt_start;
-		if (ggtt_end > stolen[1].start && ggtt_end <= stolen[1].end)
-			stolen[1].start = ggtt_end;
+		ggtt_res =
+			(struct resource) DEFINE_RES_MEM(ggtt_start,
+							 ggtt_total_entries(ggtt) * 4);
+
+		if (ggtt_res.start >= stolen[0].start && ggtt_res.start < stolen[0].end)
+			stolen[0].end = ggtt_res.start;
+		if (ggtt_res.end > stolen[1].start && ggtt_res.end <= stolen[1].end)
+			stolen[1].start = ggtt_res.end;
 
 		/* pick the larger of the two chunks */
-		if (stolen[0].end - stolen[0].start >
-		    stolen[1].end - stolen[1].start) {
-			base = stolen[0].start;
-			ggtt->stolen_size = stolen[0].end - stolen[0].start;
-		} else {
-			base = stolen[1].start;
-			ggtt->stolen_size = stolen[1].end - stolen[1].start;
-		}
+		if (resource_size(&stolen[0]) > resource_size(&stolen[1]))
+			*dsm = stolen[0];
+		else
+			*dsm = stolen[1];
+
+		ggtt->stolen_size = resource_size(dsm);
 
 		if (stolen[0].start != stolen[1].start ||
 		    stolen[0].end != stolen[1].end) {
-			dma_addr_t end = base + ggtt->stolen_size - 1;
-
-			DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n",
-				      (unsigned long long)ggtt_start,
-				      (unsigned long long)ggtt_end - 1);
-			DRM_DEBUG_KMS("Stolen memory adjusted to %pad - %pad\n",
-				      &base, &end);
+			DRM_DEBUG_KMS("GTT within stolen memory at %pR\n", &ggtt_res);
+			DRM_DEBUG_KMS("Stolen memory adjusted to %pR\n", dsm);
 		}
 	}
 
-
 	/* Verify that nothing else uses this physical address. Stolen
 	 * memory should be reserved by the BIOS and hidden from the
 	 * kernel. So if the region is already marked as busy, something
@@ -159,15 +154,14 @@ static dma_addr_t i915_stolen_to_dma(struct drm_i915_private *dev_priv)
 		 * range. Apparently this works.
 		 */
 		if (r == NULL && !IS_GEN3(dev_priv)) {
-			dma_addr_t end = base + ggtt->stolen_size;
+			DRM_ERROR("conflict detected with stolen region: %pR\n",
+				  dsm);
 
-			DRM_ERROR("conflict detected with stolen region: [%pad - %pad]\n",
-				  &base, &end);
-			base = 0;
+			return -EBUSY;
 		}
 	}
 
-	return base;
+	return 0;
 }
 
 void i915_gem_cleanup_stolen(struct drm_device *dev)
@@ -187,7 +181,7 @@ static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv,
 	uint32_t reg_val = I915_READ(IS_GM45(dev_priv) ?
 				     CTG_STOLEN_RESERVED :
 				     ELK_STOLEN_RESERVED);
-	dma_addr_t stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size;
+	dma_addr_t stolen_top = dev_priv->dsm.start + ggtt->stolen_size;
 
 	if ((reg_val & G4X_STOLEN_RESERVED_ENABLE) == 0) {
 		*base = 0;
@@ -318,7 +312,7 @@ static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv,
 		return;
 	}
 
-	stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size;
+	stolen_top = dev_priv->dsm.start + ggtt->stolen_size;
 
 	*base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
 
@@ -354,11 +348,15 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
 	if (ggtt->stolen_size == 0)
 		return 0;
 
-	dev_priv->mm.stolen_base = i915_stolen_to_dma(dev_priv);
-	if (dev_priv->mm.stolen_base == 0)
+	dev_priv->dsm = intel_graphics_stolen_res;
+
+	if (i915_adjust_stolen(dev_priv, &dev_priv->dsm))
 		return 0;
 
-	stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size;
+	GEM_BUG_ON(dev_priv->dsm.start == 0);
+	GEM_BUG_ON(ggtt->stolen_size > resource_size(&dev_priv->dsm));
+
+	stolen_top = dev_priv->dsm.end + 1;
 	reserved_base = 0;
 	reserved_size = 0;
 
@@ -399,12 +397,12 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
 		reserved_base = stolen_top;
 	}
 
-	if (reserved_base < dev_priv->mm.stolen_base ||
+	if (reserved_base < dev_priv->dsm.start ||
 	    reserved_base + reserved_size > stolen_top) {
 		dma_addr_t reserved_top = reserved_base + reserved_size;
 		DRM_ERROR("Stolen reserved area [%pad - %pad] outside stolen memory [%pad - %pad]\n",
 			  &reserved_base, &reserved_top,
-			  &dev_priv->mm.stolen_base, &stolen_top);
+			  &dev_priv->dsm.start, &stolen_top);
 		return 0;
 	}
 
@@ -462,7 +460,7 @@ i915_pages_create_for_stolen(struct drm_device *dev,
 	sg->offset = 0;
 	sg->length = size;
 
-	sg_dma_address(sg) = (dma_addr_t)dev_priv->mm.stolen_base + offset;
+	sg_dma_address(sg) = (dma_addr_t)dev_priv->dsm.start + offset;
 	sg_dma_len(sg) = size;
 
 	return st;
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 4aefc658a5cf..a291bb965e2e 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -615,10 +615,16 @@ static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
 
 		fbc->compressed_llb = compressed_llb;
 
+		GEM_BUG_ON(range_overflows_t(u64, dev_priv->dsm.start,
+					     fbc->compressed_fb.start,
+					     U32_MAX));
+		GEM_BUG_ON(range_overflows_t(u64, dev_priv->dsm.start,
+					     fbc->compressed_llb->start,
+					     U32_MAX));
 		I915_WRITE(FBC_CFB_BASE,
-			   dev_priv->mm.stolen_base + fbc->compressed_fb.start);
+			   dev_priv->dsm.start + fbc->compressed_fb.start);
 		I915_WRITE(FBC_LL_BASE,
-			   dev_priv->mm.stolen_base + compressed_llb->start);
+			   dev_priv->dsm.start + compressed_llb->start);
 	}
 
 	DRM_DEBUG_KMS("reserved %llu bytes of contiguous stolen space for FBC, threshold: %d\n",
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 67f326230a7e..2fa2d82f61f2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7020,7 +7020,7 @@ static void valleyview_check_pctx(struct drm_i915_private *dev_priv)
 {
 	unsigned long pctx_addr = I915_READ(VLV_PCBR) & ~4095;
 
-	WARN_ON(pctx_addr != dev_priv->mm.stolen_base +
+	WARN_ON(pctx_addr != dev_priv->dsm.start +
 			     dev_priv->vlv_pctx->stolen->start);
 }
 
@@ -7043,7 +7043,12 @@ static void cherryview_setup_pctx(struct drm_i915_private *dev_priv)
 	pcbr = I915_READ(VLV_PCBR);
 	if ((pcbr >> VLV_PCBR_ADDR_SHIFT) == 0) {
 		DRM_DEBUG_DRIVER("BIOS didn't set up PCBR, fixing up\n");
-		paddr = (dev_priv->mm.stolen_base +
+
+		GEM_BUG_ON(range_overflows_t(resource_size_t,
+					     dev_priv->dsm.start,
+					     (ggtt->stolen_size - pctx_size),
+					     U32_MAX));
+		paddr = (dev_priv->dsm.start +
 			 (ggtt->stolen_size - pctx_size));
 
 		pctx_paddr = (paddr & (~4095));
@@ -7065,7 +7070,7 @@ static void valleyview_setup_pctx(struct drm_i915_private *dev_priv)
 		/* BIOS set it up already, grab the pre-alloc'd space */
 		int pcbr_offset;
 
-		pcbr_offset = (pcbr & (~4095)) - dev_priv->mm.stolen_base;
+		pcbr_offset = (pcbr & (~4095)) - dev_priv->dsm.start;
 		pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv,
 								      pcbr_offset,
 								      I915_GTT_OFFSET_NONE,
@@ -7089,7 +7094,11 @@ static void valleyview_setup_pctx(struct drm_i915_private *dev_priv)
 		goto out;
 	}
 
-	pctx_paddr = dev_priv->mm.stolen_base + pctx->stolen->start;
+	GEM_BUG_ON(range_overflows_t(u64,
+				     dev_priv->dsm.start,
+				     pctx->stolen->start,
+				     U32_MAX));
+	pctx_paddr = dev_priv->dsm.start + pctx->stolen->start;
 	I915_WRITE(VLV_PCBR, pctx_paddr);
 
 out:
-- 
2.14.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2017-12-05 21:03 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-05 21:02 [PATCH 0/9] make stolen resource centric Matthew Auld
2017-12-05 21:02 ` [PATCH 1/9] x86/early-quirks: Extend Intel graphics stolen memory placement to 64bit Matthew Auld
2017-12-05 21:02 ` [PATCH 2/9] x86/early-quirks: replace the magical increment start values Matthew Auld
2017-12-05 21:02   ` Matthew Auld
2017-12-05 21:02 ` [PATCH 3/9] x86/early-quirks: reverse the if ladders Matthew Auld
2017-12-05 21:02   ` Matthew Auld
2017-12-05 21:08   ` Ville Syrjälä
2017-12-05 21:08     ` Ville Syrjälä
2017-12-05 21:02 ` [PATCH 4/9] drm/i915: nuke the duplicated stolen discovery Matthew Auld
2017-12-05 21:02 ` Matthew Auld [this message]
2017-12-05 23:30   ` [PATCH 5/9] drm/i915: make dsm struct resource centric Chris Wilson
2017-12-05 21:02 ` [PATCH 6/9] drm/i915: make reserved " Matthew Auld
2017-12-05 23:27   ` Chris Wilson
2017-12-05 21:02 ` [PATCH 7/9] drm/i915: make mappable " Matthew Auld
2017-12-05 23:26   ` Chris Wilson
2017-12-05 21:02 ` [PATCH 8/9] drm/i915: prefer resource_size_t for everything stolen Matthew Auld
2017-12-05 23:22   ` Chris Wilson
2017-12-05 21:02 ` [PATCH 9/9] drm/i915: use stolen_usable_size for the range sanity check Matthew Auld
2017-12-05 21:25 ` ✓ Fi.CI.BAT: success for make stolen resource centric (rev4) Patchwork
2017-12-05 22:50 ` ✗ Fi.CI.IGT: failure " Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2017-12-07 12:28 [PATCH 0/9] make stolen resource centric Matthew Auld
2017-12-07 12:28 ` [PATCH 5/9] drm/i915: make dsm struct " Matthew Auld

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=20171205210249.8875-6-matthew.auld@intel.com \
    --to=matthew.auld@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=paulo.r.zanoni@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.