From: Ben Widawsky <benjamin.widawsky@xxxxxxxxxxxxxxx> While the context is not being used, we can make the PTEs invalid, so nothing can accidentally corrupt it. Systems tend to have a lot of trouble when the context gets corrupted. NOTE: This is a slightly different patch than what I posted to Bugzilla. References: https://bugs.freedesktop.org/show_bug.cgi?id=75724 Signed-off-by: Ben Widawsky <ben@xxxxxxxxxxxx> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem_context.c | 56 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 5474489..b913ef6 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -545,6 +545,58 @@ i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id) return ctx; } +static void +_ctx_ptes(struct intel_ring_buffer *ring, + struct i915_hw_context *ctx, + bool valid) +{ + const size_t ptes = ctx->obj->base.size >> PAGE_SHIFT; + const u32 base = i915_gem_obj_ggtt_offset(ctx->obj); + struct sg_page_iter sg_iter; + struct i915_address_space *vm = ctx->vm; + int i = 0; + + BUG_ON(!i915_gem_obj_is_pinned(ctx->obj)); + + if (intel_ring_begin(ring, round_up(ptes * 3, 2))) { + DRM_ERROR("Could not protect context object.\n"); + return; + } + + for_each_sg_page(ctx->obj->pages->sgl, &sg_iter, ctx->obj->pages->nents, 0) { + u32 pte = vm->pte_encode(sg_page_iter_dma_address(&sg_iter), + ctx->obj->cache_level, + valid); + intel_ring_emit(ring, MI_UPDATE_GTT | (1<<22)); + /* The docs contradict themselves on the offset. They say dword + * offset, yet the low 12 bits MBZ. */ + intel_ring_emit(ring, (base & PAGE_MASK) + i); + intel_ring_emit(ring, pte); + i+=PAGE_SIZE; + } + + if (i & PAGE_SHIFT) + intel_ring_emit(ring, MI_NOOP); + + intel_ring_advance(ring); +} + +static void +enable_ctx_ptes(struct intel_ring_buffer *ring, + struct i915_hw_context *ctx) +{ + if (INTEL_INFO(ring->dev)->gen < 8) + _ctx_ptes(ring, ctx, true); +} + +static void +disable_ctx_ptes(struct intel_ring_buffer *ring, + struct i915_hw_context *ctx) +{ + if (INTEL_INFO(ring->dev)->gen < 8) + _ctx_ptes(ring, ctx, false); +} + static inline int mi_set_context(struct intel_ring_buffer *ring, struct i915_hw_context *new_context, @@ -568,6 +620,8 @@ mi_set_context(struct intel_ring_buffer *ring, if (!IS_HASWELL(ring->dev) && INTEL_INFO(ring->dev)->gen < 8) flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN); + enable_ctx_ptes(ring, new_context); + ret = intel_ring_begin(ring, 6); if (ret) return ret; @@ -595,6 +649,8 @@ mi_set_context(struct intel_ring_buffer *ring, intel_ring_advance(ring); + disable_ctx_ptes(ring, new_context); + return ret; } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8c382a5..aa95e20 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -368,7 +368,7 @@ #define MI_TOPOLOGY_FILTER MI_INSTR(0x0D, 0) #define MI_LOAD_SCAN_LINES_EXCL MI_INSTR(0x13, 0) #define MI_URB_CLEAR MI_INSTR(0x19, 0) -#define MI_UPDATE_GTT MI_INSTR(0x23, 0) +#define MI_UPDATE_GTT MI_INSTR(0x23, 1) #define MI_CLFLUSH MI_INSTR(0x27, 0) #define MI_REPORT_PERF_COUNT MI_INSTR(0x28, 0) #define MI_REPORT_PERF_COUNT_GGTT (1<<0) -- 1.8.3.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx