Skip to content

Commit

Permalink
drm/i915/selftests: Check that GPR are cleared for new contexts
Browse files Browse the repository at this point in the history
We want the general purpose registers to be clear in all new contexts so
that we can be confident that no information is leaked from one to the
next.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191014090757.32111-7-chris@chris-wilson.co.uk
  • Loading branch information
Chris Wilson committed Oct 14, 2019
1 parent 9c27462 commit 9506c23
Showing 1 changed file with 166 additions and 19 deletions.
185 changes: 166 additions & 19 deletions drivers/gpu/drm/i915/gt/selftest_lrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#include "gem/selftests/igt_gem_utils.h"
#include "gem/selftests/mock_context.h"

#define CS_GPR(engine, n) ((engine)->mmio_base + 0x600 + (n) * 4)
#define NUM_GPR_DW (16 * 2) /* each GPR is 2 dwords */

static struct i915_vma *create_scratch(struct intel_gt *gt)
{
struct drm_i915_gem_object *obj;
Expand Down Expand Up @@ -2107,16 +2110,14 @@ static int preserved_virtual_engine(struct drm_i915_private *i915,
struct intel_engine_cs **siblings,
unsigned int nsibling)
{
#define CS_GPR(engine, n) ((engine)->mmio_base + 0x600 + (n) * 4)

struct i915_request *last = NULL;
struct i915_gem_context *ctx;
struct intel_context *ve;
struct i915_vma *scratch;
struct igt_live_test t;
const int num_gpr = 16 * 2; /* each GPR is 2 dwords */
unsigned int n;
int err = 0;
u32 *cs;

ctx = kernel_context(i915);
if (!ctx)
Expand All @@ -2142,10 +2143,9 @@ static int preserved_virtual_engine(struct drm_i915_private *i915,
if (err)
goto out_unpin;

for (n = 0; n < num_gpr; n++) {
for (n = 0; n < NUM_GPR_DW; n++) {
struct intel_engine_cs *engine = siblings[n % nsibling];
struct i915_request *rq;
u32 *cs;

rq = i915_request_create(ve);
if (IS_ERR(rq)) {
Expand All @@ -2169,7 +2169,7 @@ static int preserved_virtual_engine(struct drm_i915_private *i915,
*cs++ = 0;

*cs++ = MI_LOAD_REGISTER_IMM(1);
*cs++ = CS_GPR(engine, (n + 1) % num_gpr);
*cs++ = CS_GPR(engine, (n + 1) % NUM_GPR_DW);
*cs++ = n + 1;

*cs++ = MI_NOOP;
Expand All @@ -2182,21 +2182,26 @@ static int preserved_virtual_engine(struct drm_i915_private *i915,

if (i915_request_wait(last, 0, HZ / 5) < 0) {
err = -ETIME;
} else {
u32 *map = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB);
goto out_end;
}

for (n = 0; n < num_gpr; n++) {
if (map[n] != n) {
pr_err("Incorrect value[%d] found for GPR[%d]\n",
map[n], n);
err = -EINVAL;
break;
}
}
cs = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB);
if (IS_ERR(cs)) {
err = PTR_ERR(cs);
goto out_end;
}

i915_gem_object_unpin_map(scratch->obj);
for (n = 0; n < NUM_GPR_DW; n++) {
if (cs[n] != n) {
pr_err("Incorrect value[%d] found for GPR[%d]\n",
cs[n], n);
err = -EINVAL;
break;
}
}

i915_gem_object_unpin_map(scratch->obj);

out_end:
if (igt_live_test_end(&t))
err = -EIO;
Expand All @@ -2210,8 +2215,6 @@ static int preserved_virtual_engine(struct drm_i915_private *i915,
out_close:
kernel_context_close(ctx);
return err;

#undef CS_GPR
}

static int live_virtual_preserved(void *arg)
Expand Down Expand Up @@ -2724,11 +2727,155 @@ static int live_lrc_state(void *arg)
return err;
}

static int gpr_make_dirty(struct intel_engine_cs *engine)
{
struct i915_request *rq;
u32 *cs;
int n;

rq = i915_request_create(engine->kernel_context);
if (IS_ERR(rq))
return PTR_ERR(rq);

cs = intel_ring_begin(rq, 2 * NUM_GPR_DW + 2);
if (IS_ERR(cs)) {
i915_request_add(rq);
return PTR_ERR(cs);
}

*cs++ = MI_LOAD_REGISTER_IMM(NUM_GPR_DW);
for (n = 0; n < NUM_GPR_DW; n++) {
*cs++ = CS_GPR(engine, n);
*cs++ = STACK_MAGIC;
}
*cs++ = MI_NOOP;

intel_ring_advance(rq, cs);
i915_request_add(rq);

return 0;
}

static int __live_gpr_clear(struct i915_gem_context *fixme,
struct intel_engine_cs *engine,
struct i915_vma *scratch)
{
struct intel_context *ce;
struct i915_request *rq;
u32 *cs;
int err;
int n;

if (INTEL_GEN(engine->i915) < 9 && engine->class != RENDER_CLASS)
return 0; /* GPR only on rcs0 for gen8 */

err = gpr_make_dirty(engine);
if (err)
return err;

ce = intel_context_create(fixme, engine);
if (IS_ERR(ce))
return PTR_ERR(ce);

rq = intel_context_create_request(ce);
if (IS_ERR(rq)) {
err = PTR_ERR(rq);
goto err_put;
}

cs = intel_ring_begin(rq, 4 * NUM_GPR_DW);
if (IS_ERR(cs)) {
err = PTR_ERR(cs);
i915_request_add(rq);
goto err_put;
}

for (n = 0; n < NUM_GPR_DW; n++) {
*cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
*cs++ = CS_GPR(engine, n);
*cs++ = i915_ggtt_offset(scratch) + n * sizeof(u32);
*cs++ = 0;
}

i915_request_get(rq);
i915_request_add(rq);

if (i915_request_wait(rq, 0, HZ / 5) < 0) {
err = -ETIME;
goto err_rq;
}

cs = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB);
if (IS_ERR(cs)) {
err = PTR_ERR(cs);
goto err_rq;
}

for (n = 0; n < NUM_GPR_DW; n++) {
if (cs[n]) {
pr_err("%s: GPR[%d].%s was not zero, found 0x%08x!\n",
engine->name,
n / 2, n & 1 ? "udw" : "ldw",
cs[n]);
err = -EINVAL;
break;
}
}

i915_gem_object_unpin_map(scratch->obj);

err_rq:
i915_request_put(rq);
err_put:
intel_context_put(ce);
return err;
}

static int live_gpr_clear(void *arg)
{
struct intel_gt *gt = arg;
struct intel_engine_cs *engine;
struct i915_gem_context *fixme;
struct i915_vma *scratch;
enum intel_engine_id id;
int err = 0;

/*
* Check that GPR registers are cleared in new contexts as we need
* to avoid leaking any information from previous contexts.
*/

fixme = kernel_context(gt->i915);
if (!fixme)
return -ENOMEM;

scratch = create_scratch(gt);
if (IS_ERR(scratch)) {
err = PTR_ERR(scratch);
goto out_close;
}

for_each_engine(engine, gt->i915, id) {
err = __live_gpr_clear(fixme, engine, scratch);
if (err)
break;
}

if (igt_flush_test(gt->i915))
err = -EIO;

i915_vma_unpin_and_release(&scratch, 0);
out_close:
kernel_context_close(fixme);
return err;
}

int intel_lrc_live_selftests(struct drm_i915_private *i915)
{
static const struct i915_subtest tests[] = {
SUBTEST(live_lrc_layout),
SUBTEST(live_lrc_state),
SUBTEST(live_gpr_clear),
};

if (!HAS_LOGICAL_RING_CONTEXTS(i915))
Expand Down

0 comments on commit 9506c23

Please sign in to comment.