[Intel-gfx] [PATCH 2/2] drm/i915: Prevent loading of uninitialized context garbage
Chris Wilson
chris at chris-wilson.co.uk
Thu Aug 8 21:00:26 CEST 2013
The extended state bits are stored in the LCA register and affect all
updates to the LCA register - i.e. the state on the old context is saved
when SAVE_EX_STATE_EN is currently set in the old context address before
the update, and the new context is restored when RESTORE_EX_STATE_EN is
set in the new context address. This is irrespective of the
RESTORE_INHIBIT flag in the MI_SET_CONTEXT.
Hence, upon initial loading the contents of the extended state is read
from uninitialised data. To workaround this, on first load we do a dummy
load without the mandatory RESTORE_EX_STATE_EN bit so that the real load
causes us to initialise the extended state of the context before it is
then loaded by the LCA update.
v2: Split out the introduction of the variable length MI_SET_CONTEXT
command sequence.
References: https://bugs.freedesktop.org/show_bug.cgi?id=64073
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Ben Widawsky <ben at bwidawsk.net>
---
drivers/gpu/drm/i915/i915_gem_context.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 8a7b61e..a57d49a 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -367,6 +367,8 @@ mi_set_context(struct intel_ring_buffer *ring,
case 5: len += 2;
break;
}
+ if (!new_context->is_initialized)
+ len += 2;
ret = intel_ring_begin(ring, len);
if (ret)
@@ -382,6 +384,22 @@ mi_set_context(struct intel_ring_buffer *ring,
break;
}
+ if (!new_context->is_initialized) {
+ /* The GPU tries to restore the extended state irrespective
+ * of RestoreInhibit (since it is part of the LCA switch
+ * itself rather than the MI_SET_CONTEXT command).
+ * Since the initial contents may be garbage we do a dummy
+ * load first then set the mandatory flag for any future
+ * ring context switches.
+ */
+ intel_ring_emit(ring, MI_SET_CONTEXT);
+ intel_ring_emit(ring,
+ i915_gem_obj_ggtt_offset(new_context->obj) |
+ MI_MM_SPACE_GTT |
+ MI_SAVE_EXT_STATE_EN |
+ hw_flags);
+ }
+
intel_ring_emit(ring, MI_NOOP);
intel_ring_emit(ring, MI_SET_CONTEXT);
intel_ring_emit(ring, i915_gem_obj_ggtt_offset(new_context->obj) |
--
1.8.4.rc1
More information about the Intel-gfx
mailing list