[Intel-gfx] [PATCH] [RFC] drm/i915: VMA ops sanitizer

Ben Widawsky benjamin.widawsky at intel.com
Fri Dec 20 21:44:01 CET 2013


Provide some simple checks to make sure things haven't completely blown
up. Once the PPGTT is mostly stable, these checks can be removed.

These are primarily meant to catch cases where our software tracking
(drm_mm) somehow got out of sync with what we expect of the hardware.
Or, cases where we've corrupted the VMA.

Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 3ba5664..6fecf98 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -70,6 +70,28 @@ typedef gen8_gtt_pte_t gen8_ppgtt_pde_t;
 #define PPAT_CACHED_INDEX		_PAGE_PAT /* WB LLCeLLC */
 #define PPAT_DISPLAY_ELLC_INDEX		_PAGE_PCD /* WT eLLC */
 
+/* The latter two cases are for wraparound */
+static void sanitize_bind_vma(const struct i915_vma *vma,
+			      const uint64_t entry)
+{
+	/* Low bits set */
+	BUG_ON(vma->node.start && !entry);
+
+	/* Zero sized objects won't exist */
+	BUG_ON(!vma->node.size);
+
+	/* Using below usable */
+	BUG_ON(vma->node.start < vma->vm->start);
+
+	/* Too big */
+	BUG_ON((vma->node.start + vma->node.size) > vma->vm->total);
+
+	/* Wrap */
+	BUG_ON((vma->node.start + vma->node.size) < vma->node.start);
+}
+
+#define sanitize_unbind_vma sanitize_bind_vma
+
 static void ppgtt_bind_vma(struct i915_vma *vma,
 			   enum i915_cache_level cache_level,
 			   u32 flags);
@@ -1010,17 +1032,19 @@ ppgtt_bind_vma(struct i915_vma *vma,
 	       enum i915_cache_level cache_level,
 	       u32 flags)
 {
-	const unsigned long entry = vma->node.start >> PAGE_SHIFT;
+	const uint64_t entry = vma->node.start >> PAGE_SHIFT;
 
 	WARN_ON(flags);
+	sanitize_bind_vma(vma, entry);
 
 	vma->vm->insert_entries(vma->vm, vma->obj->pages, entry, cache_level);
 }
 
 static void ppgtt_unbind_vma(struct i915_vma *vma)
 {
-	const unsigned long entry = vma->node.start >> PAGE_SHIFT;
+	const uint64_t entry = vma->node.start >> PAGE_SHIFT;
 
+	sanitize_bind_vma(vma, entry);
 	vma->vm->clear_range(vma->vm,
 			     entry,
 			     vma->obj->base.size >> PAGE_SHIFT,
@@ -1322,6 +1346,8 @@ static void i915_ggtt_bind_vma(struct i915_vma *vma,
 		AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY;
 
 	BUG_ON(!i915_is_ggtt(vma->vm));
+	sanitize_bind_vma(vma, entry);
+
 	intel_gtt_insert_sg_entries(vma->obj->pages, entry, flags);
 	vma->obj->has_global_gtt_mapping = 1;
 }
@@ -1340,6 +1366,8 @@ static void i915_ggtt_unbind_vma(struct i915_vma *vma)
 	const unsigned int size = vma->obj->base.size >> PAGE_SHIFT;
 
 	BUG_ON(!i915_is_ggtt(vma->vm));
+	sanitize_unbind_vma(vma, first);
+
 	vma->obj->has_global_gtt_mapping = 0;
 	intel_gtt_clear_range(first, size);
 }
@@ -1353,6 +1381,8 @@ static void ggtt_bind_vma(struct i915_vma *vma,
 	struct drm_i915_gem_object *obj = vma->obj;
 	const unsigned long entry = vma->node.start >> PAGE_SHIFT;
 
+	sanitize_bind_vma(vma, entry);
+
 	/* If there is no aliasing PPGTT, or the caller needs a global mapping,
 	 * or we have a global mapping already but the cacheability flags have
 	 * changed, set the global PTEs.
@@ -1390,6 +1420,8 @@ static void ggtt_unbind_vma(struct i915_vma *vma)
 	struct drm_i915_gem_object *obj = vma->obj;
 	const unsigned long entry = vma->node.start >> PAGE_SHIFT;
 
+	sanitize_unbind_vma(vma, entry);
+
 	if (obj->has_global_gtt_mapping) {
 		vma->vm->clear_range(vma->vm, entry,
 				     vma->obj->base.size >> PAGE_SHIFT,
-- 
1.8.5.2




More information about the Intel-gfx mailing list