@@ -617,6 +617,21 @@ static void fill_page_dma_32(struct i915_address_space *vm,
fill_page_dma(vm, p, (u64)v << 32 | v);
}
+static void setup_scratch_page_guards(struct i915_address_space *vm)
+{
+ struct i915_page_dma const *p = &vm->scratch_page;
+ u32 *scratch;
+ const unsigned int size = BIT(p->order) << PAGE_SHIFT;
+ const unsigned int last_idx = size / sizeof(*scratch) - 1;
+
+ scratch = kmap_atomic(p->page);
+
+ scratch[2] = MI_BATCH_BUFFER_END;
+ scratch[last_idx] = MI_BATCH_BUFFER_END;
+
+ kunmap_atomic(scratch);
+}
+
static int
setup_scratch_page(struct i915_address_space *vm, gfp_t gfp)
{
@@ -665,6 +680,9 @@ setup_scratch_page(struct i915_address_space *vm, gfp_t gfp)
vm->scratch_page.page = page;
vm->scratch_page.daddr = addr;
vm->scratch_page.order = order;
+
+ setup_scratch_page_guards(vm);
+
return 0;
unmap_page:
There have been cases where GPU engine has managed to run past execbuffer ending due to reasons unknown at that time: coherency problems, page table setup errors, hw glitches. Let's try to contain a wild engine head by putting batch buffer end commands into start and end of scratch page. Leave two nops at start of page so it would catch the eye on error dumps. Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Matthew Auld <matthew.auld@intel.com> Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> --- drivers/gpu/drm/i915/i915_gem_gtt.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)