Skip to content

Commit

Permalink
drm/i915/execlists: Verify context register state before execution
Browse files Browse the repository at this point in the history
Check that the context's ring register state still matches our
expectations prior to execution.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191102125739.24626-1-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Nov 2, 2019
1 parent 3881376 commit b0b1024
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 19 deletions.
71 changes: 57 additions & 14 deletions drivers/gpu/drm/i915/gt/intel_lrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,58 @@ static void intel_engine_context_out(struct intel_engine_cs *engine)
write_sequnlock_irqrestore(&engine->stats.lock, flags);
}

static int lrc_ring_mi_mode(const struct intel_engine_cs *engine)
{
if (INTEL_GEN(engine->i915) >= 12)
return 0x60;
else if (INTEL_GEN(engine->i915) >= 9)
return 0x54;
else if (engine->class == RENDER_CLASS)
return 0x58;
else
return -1;
}

static void
execlists_check_context(const struct intel_context *ce,
const struct intel_engine_cs *engine)
{
const struct intel_ring *ring = ce->ring;
u32 *regs = ce->lrc_reg_state;
bool valid = true;
int x;

if (regs[CTX_RING_START] != i915_ggtt_offset(ring->vma)) {
pr_err("%s: context submitted with incorrect RING_START [%08x], expected %08x\n",
engine->name,
regs[CTX_RING_START],
i915_ggtt_offset(ring->vma));
regs[CTX_RING_START] = i915_ggtt_offset(ring->vma);
valid = false;
}

if ((regs[CTX_RING_CTL] & ~(RING_WAIT | RING_WAIT_SEMAPHORE)) !=
(RING_CTL_SIZE(ring->size) | RING_VALID)) {
pr_err("%s: context submitted with incorrect RING_CTL [%08x], expected %08x\n",
engine->name,
regs[CTX_RING_CTL],
(u32)(RING_CTL_SIZE(ring->size) | RING_VALID));
regs[CTX_RING_CTL] = RING_CTL_SIZE(ring->size) | RING_VALID;
valid = false;
}

x = lrc_ring_mi_mode(engine);
if (x != -1 && regs[x + 1] & (regs[x + 1] >> 16) & STOP_RING) {
pr_err("%s: context submitted with STOP_RING [%08x] in RING_MI_MODE\n",
engine->name, regs[x + 1]);
regs[x + 1] &= ~STOP_RING;
regs[x + 1] |= STOP_RING << 16;
valid = false;
}

WARN_ONCE(!valid, "Invalid lrc state found before submission\n");
}

static inline struct intel_engine_cs *
__execlists_schedule_in(struct i915_request *rq)
{
Expand All @@ -998,6 +1050,9 @@ __execlists_schedule_in(struct i915_request *rq)

intel_context_get(ce);

if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
execlists_check_context(ce, rq->engine);

if (ce->tag) {
/* Use a fixed tag for OA and friends */
ce->lrc_desc |= (u64)ce->tag << 32;
Expand Down Expand Up @@ -2353,7 +2408,7 @@ __execlists_update_reg_state(const struct intel_context *ce,
GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->head));
GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->tail));

regs[CTX_RING_BUFFER_START] = i915_ggtt_offset(ring->vma);
regs[CTX_RING_START] = i915_ggtt_offset(ring->vma);
regs[CTX_RING_HEAD] = ring->head;
regs[CTX_RING_TAIL] = ring->tail;

Expand Down Expand Up @@ -2940,18 +2995,6 @@ static void reset_csb_pointers(struct intel_engine_cs *engine)
&execlists->csb_status[reset_value]);
}

static int lrc_ring_mi_mode(const struct intel_engine_cs *engine)
{
if (INTEL_GEN(engine->i915) >= 12)
return 0x60;
else if (INTEL_GEN(engine->i915) >= 9)
return 0x54;
else if (engine->class == RENDER_CLASS)
return 0x58;
else
return -1;
}

static void __execlists_reset_reg_state(const struct intel_context *ce,
const struct intel_engine_cs *engine)
{
Expand Down Expand Up @@ -3885,7 +3928,7 @@ static void init_common_reg_state(u32 * const regs,
_MASKED_BIT_DISABLE(CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT |
CTX_CTRL_RS_CTX_ENABLE);

regs[CTX_RING_BUFFER_CONTROL] = RING_CTL_SIZE(ring->size) | RING_VALID;
regs[CTX_RING_CTL] = RING_CTL_SIZE(ring->size) | RING_VALID;
regs[CTX_BB_STATE] = RING_BB_PPGTT;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/i915/gt/intel_lrc_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#define CTX_CONTEXT_CONTROL (0x02 + 1)
#define CTX_RING_HEAD (0x04 + 1)
#define CTX_RING_TAIL (0x06 + 1)
#define CTX_RING_BUFFER_START (0x08 + 1)
#define CTX_RING_BUFFER_CONTROL (0x0a + 1)
#define CTX_RING_START (0x08 + 1)
#define CTX_RING_CTL (0x0a + 1)
#define CTX_BB_STATE (0x10 + 1)
#define CTX_BB_PER_CTX_PTR (0x18 + 1)
#define CTX_PDP3_UDW (0x24 + 1)
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/i915/gt/selftest_lrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3207,12 +3207,12 @@ static int live_lrc_fixed(void *arg)
} tbl[] = {
{
i915_mmio_reg_offset(RING_START(engine->mmio_base)),
CTX_RING_BUFFER_START - 1,
CTX_RING_START - 1,
"RING_START"
},
{
i915_mmio_reg_offset(RING_CTL(engine->mmio_base)),
CTX_RING_BUFFER_CONTROL - 1,
CTX_RING_CTL - 1,
"RING_CTL"
},
{
Expand All @@ -3231,7 +3231,7 @@ static int live_lrc_fixed(void *arg)
"RING_MI_MODE"
},
{
engine->mmio_base + 0x110,
i915_mmio_reg_offset(RING_BBSTATE(engine->mmio_base)),
CTX_BB_STATE - 1,
"BB_STATE"
},
Expand Down

0 comments on commit b0b1024

Please sign in to comment.