[igt-dev] [PATCH i-g-t] tests/i915: Add test for unaligned detiler fences

Chris Wilson chris at chris-wilson.co.uk
Mon Jan 13 17:50:09 UTC 2020


Quoting Imre Deak (2020-01-13 17:21:20)
> Add a test to check the detiling on a buffer with a size that isn't
> aligned to the detiler fence stride we add for the buffer. While writes
> beyond the last full tile row may target an address beyond the buffer's
> size, we still expect that such writes will not lead to a corruption
> on memory pages that are not owned by the process performing the write.
> 
> The reason for this test: on TGL such writes lead to random memory
> corruption in memory not belonging to the process. This should be
> prevented ensuring that we keep pages that user space can access
> (padding the object size to be tile-row size aligned) reserved in the
> GTT address space until userspace can write through the fenced region.

This is going through a different IP block and driver paths than the
original bug. When we are using a fence, we create a vma that is
sufficient to include the last tile row. When we create a vma for the
display, we don't ask for that...

--- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c
@@ -344,19 +344,24 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
 	 * put it anyway and hope that userspace can cope (but always first
 	 * try to preserve the existing ABI).
 	 */
-	vma = ERR_PTR(-ENOSPC);
-	if ((flags & PIN_MAPPABLE) == 0 &&
-	    (!view || view->type == I915_GGTT_VIEW_NORMAL))
-		vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment,
-					       flags |
-					       PIN_MAPPABLE |
-					       PIN_NONBLOCK);
-	if (IS_ERR(vma))
-		vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, flags);
+	vma = i915_vma_instance(obj, &i915->ggtt.vm, view);
 	if (IS_ERR(vma))
 		return vma;

-	vma->display_alignment = max_t(u64, vma->display_alignment, alignment);
+	alignment = max(vma->display_alignment, alignment);
+
+	ret = -ENOSPC;
+	if ((flags & PIN_MAPPABLE) == 0 &&
+	    vma->ggtt_view.type == I915_GGTT_VIEW_NORMAL)
+		ret = i915_vma_pin(vma,
+				   alignment, vma->fence_size,
+				   flags | PIN_MAPPABLE | PIN_NONBLOCK);
+	if (ret == -ENOSPC)
+		ret = i915_vma_pin(vma, alignment, vma->fence_size, flags);
+	if (ret)
+		return ERR_PTR(ret);
+
+	vma->display_alignment = alignment;

 	i915_gem_object_flush_if_display(obj);

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 17d7c525ea5c..57df22b809fa 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -619,7 +619,7 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)
 	GEM_BUG_ON(drm_mm_node_allocated(&vma->node));

 	size = max(size, vma->size);
-	alignment = max(alignment, vma->display_alignment);
+	alignment = max_t(typeof(alignment), alignment, vma->display_alignment);
 	if (flags & PIN_MAPPABLE) {
 		size = max_t(typeof(size), size, vma->fence_size);
 		alignment = max_t(typeof(alignment),
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h b/drivers/gpu/drm/i915/i915_vma_types.h
index e0942efd5236..2cf642ecbd7d 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -182,7 +182,6 @@ struct i915_vma {
 	struct i915_fence_reg *fence;

 	u64 size;
-	u64 display_alignment;
 	struct i915_page_sizes page_sizes;

 	/* mmap-offset associated with fencing for this vma */
@@ -190,6 +189,7 @@ struct i915_vma {

 	u32 fence_size;
 	u32 fence_alignment;
+	u32 display_alignment;

 	/**
 	 * Count of the number of times this vma has been opened by different

The partial fencing interaction with HW and peeking at the pages behind
should be covered by selftests -- as we want to peek at physical pages.
Mostly done already.
-Chris


More information about the igt-dev mailing list