From 82d71e31ae9d85586099f2eb94902a9dfa55e81a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jan 2020 11:51:33 +0000 Subject: drm/i915/gt: Poison GTT scratch pages Using a clear page for scratch means that we have relatively benign errors in case it is accidentally used, but that can be rather too benign for debugging. If we poison the scratch, ideally it quickly results in an obvious error. v2: Set each page individually just in case we are using highmem for our scratch page. v3: Pick a new scratch register as MI_STORE_REGISTER_MEM does not work with GPR0 on gen7, unbelievably. v4: Haswell still considers 3DPRIM a privileged register! Suggested-by: Mika Kuoppala Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Matthew Auld Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20200124115133.53360-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/gt/intel_gtt.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/gpu/drm/i915/gt/intel_gtt.c') diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c index 45d8e0019a8e..bb9a6e638175 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.c +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c @@ -299,6 +299,25 @@ fill_page_dma(const struct i915_page_dma *p, const u64 val, unsigned int count) kunmap_atomic(memset64(kmap_atomic(p->page), val, count)); } +static void poison_scratch_page(struct page *page, unsigned long size) +{ + if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) + return; + + GEM_BUG_ON(!IS_ALIGNED(size, PAGE_SIZE)); + + do { + void *vaddr; + + vaddr = kmap(page); + memset(vaddr, POISON_FREE, PAGE_SIZE); + kunmap(page); + + page = pfn_to_page(page_to_pfn(page) + 1); + size -= PAGE_SIZE; + } while (size); +} + int setup_scratch_page(struct i915_address_space *vm, gfp_t gfp) { unsigned long size; @@ -331,6 +350,17 @@ int setup_scratch_page(struct i915_address_space *vm, gfp_t gfp) if (unlikely(!page)) goto skip; + /* + * Use a non-zero scratch page for debugging. + * + * We want a value that should be reasonably obvious + * to spot in the error state, while also causing a GPU hang + * if executed. We prefer using a clear page in production, so + * should it ever be accidentally used, the effect should be + * fairly benign. + */ + poison_scratch_page(page, size); + addr = dma_map_page_attrs(vm->dma, page, 0, size, PCI_DMA_BIDIRECTIONAL, -- cgit