cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

selftest_lrc.c (39275B)


      1// SPDX-License-Identifier: MIT
      2/*
      3 * Copyright © 2018 Intel Corporation
      4 */
      5
      6#include <linux/prime_numbers.h>
      7
      8#include "gem/i915_gem_internal.h"
      9
     10#include "i915_selftest.h"
     11#include "intel_engine_heartbeat.h"
     12#include "intel_engine_pm.h"
     13#include "intel_reset.h"
     14#include "intel_ring.h"
     15#include "selftest_engine_heartbeat.h"
     16#include "selftests/i915_random.h"
     17#include "selftests/igt_flush_test.h"
     18#include "selftests/igt_live_test.h"
     19#include "selftests/igt_spinner.h"
     20#include "selftests/lib_sw_fence.h"
     21#include "shmem_utils.h"
     22
     23#include "gem/selftests/igt_gem_utils.h"
     24#include "gem/selftests/mock_context.h"
     25
     26#define CS_GPR(engine, n) ((engine)->mmio_base + 0x600 + (n) * 4)
     27#define NUM_GPR 16
     28#define NUM_GPR_DW (NUM_GPR * 2) /* each GPR is 2 dwords */
     29
     30static struct i915_vma *create_scratch(struct intel_gt *gt)
     31{
     32	return __vm_create_scratch_for_read_pinned(&gt->ggtt->vm, PAGE_SIZE);
     33}
     34
     35static bool is_active(struct i915_request *rq)
     36{
     37	if (i915_request_is_active(rq))
     38		return true;
     39
     40	if (i915_request_on_hold(rq))
     41		return true;
     42
     43	if (i915_request_has_initial_breadcrumb(rq) && i915_request_started(rq))
     44		return true;
     45
     46	return false;
     47}
     48
     49static int wait_for_submit(struct intel_engine_cs *engine,
     50			   struct i915_request *rq,
     51			   unsigned long timeout)
     52{
     53	/* Ignore our own attempts to suppress excess tasklets */
     54	tasklet_hi_schedule(&engine->sched_engine->tasklet);
     55
     56	timeout += jiffies;
     57	do {
     58		bool done = time_after(jiffies, timeout);
     59
     60		if (i915_request_completed(rq)) /* that was quick! */
     61			return 0;
     62
     63		/* Wait until the HW has acknowleged the submission (or err) */
     64		intel_engine_flush_submission(engine);
     65		if (!READ_ONCE(engine->execlists.pending[0]) && is_active(rq))
     66			return 0;
     67
     68		if (done)
     69			return -ETIME;
     70
     71		cond_resched();
     72	} while (1);
     73}
     74
     75static int emit_semaphore_signal(struct intel_context *ce, void *slot)
     76{
     77	const u32 offset =
     78		i915_ggtt_offset(ce->engine->status_page.vma) +
     79		offset_in_page(slot);
     80	struct i915_request *rq;
     81	u32 *cs;
     82
     83	rq = intel_context_create_request(ce);
     84	if (IS_ERR(rq))
     85		return PTR_ERR(rq);
     86
     87	cs = intel_ring_begin(rq, 4);
     88	if (IS_ERR(cs)) {
     89		i915_request_add(rq);
     90		return PTR_ERR(cs);
     91	}
     92
     93	*cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
     94	*cs++ = offset;
     95	*cs++ = 0;
     96	*cs++ = 1;
     97
     98	intel_ring_advance(rq, cs);
     99
    100	rq->sched.attr.priority = I915_PRIORITY_BARRIER;
    101	i915_request_add(rq);
    102	return 0;
    103}
    104
    105static int context_flush(struct intel_context *ce, long timeout)
    106{
    107	struct i915_request *rq;
    108	struct dma_fence *fence;
    109	int err = 0;
    110
    111	rq = intel_engine_create_kernel_request(ce->engine);
    112	if (IS_ERR(rq))
    113		return PTR_ERR(rq);
    114
    115	fence = i915_active_fence_get(&ce->timeline->last_request);
    116	if (fence) {
    117		i915_request_await_dma_fence(rq, fence);
    118		dma_fence_put(fence);
    119	}
    120
    121	rq = i915_request_get(rq);
    122	i915_request_add(rq);
    123	if (i915_request_wait(rq, 0, timeout) < 0)
    124		err = -ETIME;
    125	i915_request_put(rq);
    126
    127	rmb(); /* We know the request is written, make sure all state is too! */
    128	return err;
    129}
    130
    131static int get_lri_mask(struct intel_engine_cs *engine, u32 lri)
    132{
    133	if ((lri & MI_LRI_LRM_CS_MMIO) == 0)
    134		return ~0u;
    135
    136	if (GRAPHICS_VER(engine->i915) < 12)
    137		return 0xfff;
    138
    139	switch (engine->class) {
    140	default:
    141	case RENDER_CLASS:
    142	case COMPUTE_CLASS:
    143		return 0x07ff;
    144	case COPY_ENGINE_CLASS:
    145		return 0x0fff;
    146	case VIDEO_DECODE_CLASS:
    147	case VIDEO_ENHANCEMENT_CLASS:
    148		return 0x3fff;
    149	}
    150}
    151
    152static int live_lrc_layout(void *arg)
    153{
    154	struct intel_gt *gt = arg;
    155	struct intel_engine_cs *engine;
    156	enum intel_engine_id id;
    157	u32 *lrc;
    158	int err;
    159
    160	/*
    161	 * Check the registers offsets we use to create the initial reg state
    162	 * match the layout saved by HW.
    163	 */
    164
    165	lrc = (u32 *)__get_free_page(GFP_KERNEL); /* requires page alignment */
    166	if (!lrc)
    167		return -ENOMEM;
    168	GEM_BUG_ON(offset_in_page(lrc));
    169
    170	err = 0;
    171	for_each_engine(engine, gt, id) {
    172		u32 *hw;
    173		int dw;
    174
    175		if (!engine->default_state)
    176			continue;
    177
    178		hw = shmem_pin_map(engine->default_state);
    179		if (IS_ERR(hw)) {
    180			err = PTR_ERR(hw);
    181			break;
    182		}
    183		hw += LRC_STATE_OFFSET / sizeof(*hw);
    184
    185		__lrc_init_regs(memset(lrc, POISON_INUSE, PAGE_SIZE),
    186				engine->kernel_context, engine, true);
    187
    188		dw = 0;
    189		do {
    190			u32 lri = READ_ONCE(hw[dw]);
    191			u32 lri_mask;
    192
    193			if (lri == 0) {
    194				dw++;
    195				continue;
    196			}
    197
    198			if (lrc[dw] == 0) {
    199				pr_debug("%s: skipped instruction %x at dword %d\n",
    200					 engine->name, lri, dw);
    201				dw++;
    202				continue;
    203			}
    204
    205			if ((lri & GENMASK(31, 23)) != MI_INSTR(0x22, 0)) {
    206				pr_err("%s: Expected LRI command at dword %d, found %08x\n",
    207				       engine->name, dw, lri);
    208				err = -EINVAL;
    209				break;
    210			}
    211
    212			if (lrc[dw] != lri) {
    213				pr_err("%s: LRI command mismatch at dword %d, expected %08x found %08x\n",
    214				       engine->name, dw, lri, lrc[dw]);
    215				err = -EINVAL;
    216				break;
    217			}
    218
    219			/*
    220			 * When bit 19 of MI_LOAD_REGISTER_IMM instruction
    221			 * opcode is set on Gen12+ devices, HW does not
    222			 * care about certain register address offsets, and
    223			 * instead check the following for valid address
    224			 * ranges on specific engines:
    225			 * RCS && CCS: BITS(0 - 10)
    226			 * BCS: BITS(0 - 11)
    227			 * VECS && VCS: BITS(0 - 13)
    228			 */
    229			lri_mask = get_lri_mask(engine, lri);
    230
    231			lri &= 0x7f;
    232			lri++;
    233			dw++;
    234
    235			while (lri) {
    236				u32 offset = READ_ONCE(hw[dw]);
    237
    238				if ((offset ^ lrc[dw]) & lri_mask) {
    239					pr_err("%s: Different registers found at dword %d, expected %x, found %x\n",
    240					       engine->name, dw, offset, lrc[dw]);
    241					err = -EINVAL;
    242					break;
    243				}
    244
    245				/*
    246				 * Skip over the actual register value as we
    247				 * expect that to differ.
    248				 */
    249				dw += 2;
    250				lri -= 2;
    251			}
    252		} while (!err && (lrc[dw] & ~BIT(0)) != MI_BATCH_BUFFER_END);
    253
    254		if (err) {
    255			pr_info("%s: HW register image:\n", engine->name);
    256			igt_hexdump(hw, PAGE_SIZE);
    257
    258			pr_info("%s: SW register image:\n", engine->name);
    259			igt_hexdump(lrc, PAGE_SIZE);
    260		}
    261
    262		shmem_unpin_map(engine->default_state, hw);
    263		if (err)
    264			break;
    265	}
    266
    267	free_page((unsigned long)lrc);
    268	return err;
    269}
    270
    271static int find_offset(const u32 *lri, u32 offset)
    272{
    273	int i;
    274
    275	for (i = 0; i < PAGE_SIZE / sizeof(u32); i++)
    276		if (lri[i] == offset)
    277			return i;
    278
    279	return -1;
    280}
    281
    282static int live_lrc_fixed(void *arg)
    283{
    284	struct intel_gt *gt = arg;
    285	struct intel_engine_cs *engine;
    286	enum intel_engine_id id;
    287	int err = 0;
    288
    289	/*
    290	 * Check the assumed register offsets match the actual locations in
    291	 * the context image.
    292	 */
    293
    294	for_each_engine(engine, gt, id) {
    295		const struct {
    296			u32 reg;
    297			u32 offset;
    298			const char *name;
    299		} tbl[] = {
    300			{
    301				i915_mmio_reg_offset(RING_START(engine->mmio_base)),
    302				CTX_RING_START - 1,
    303				"RING_START"
    304			},
    305			{
    306				i915_mmio_reg_offset(RING_CTL(engine->mmio_base)),
    307				CTX_RING_CTL - 1,
    308				"RING_CTL"
    309			},
    310			{
    311				i915_mmio_reg_offset(RING_HEAD(engine->mmio_base)),
    312				CTX_RING_HEAD - 1,
    313				"RING_HEAD"
    314			},
    315			{
    316				i915_mmio_reg_offset(RING_TAIL(engine->mmio_base)),
    317				CTX_RING_TAIL - 1,
    318				"RING_TAIL"
    319			},
    320			{
    321				i915_mmio_reg_offset(RING_MI_MODE(engine->mmio_base)),
    322				lrc_ring_mi_mode(engine),
    323				"RING_MI_MODE"
    324			},
    325			{
    326				i915_mmio_reg_offset(RING_BBSTATE(engine->mmio_base)),
    327				CTX_BB_STATE - 1,
    328				"BB_STATE"
    329			},
    330			{
    331				i915_mmio_reg_offset(RING_BB_PER_CTX_PTR(engine->mmio_base)),
    332				lrc_ring_wa_bb_per_ctx(engine),
    333				"RING_BB_PER_CTX_PTR"
    334			},
    335			{
    336				i915_mmio_reg_offset(RING_INDIRECT_CTX(engine->mmio_base)),
    337				lrc_ring_indirect_ptr(engine),
    338				"RING_INDIRECT_CTX_PTR"
    339			},
    340			{
    341				i915_mmio_reg_offset(RING_INDIRECT_CTX_OFFSET(engine->mmio_base)),
    342				lrc_ring_indirect_offset(engine),
    343				"RING_INDIRECT_CTX_OFFSET"
    344			},
    345			{
    346				i915_mmio_reg_offset(RING_CTX_TIMESTAMP(engine->mmio_base)),
    347				CTX_TIMESTAMP - 1,
    348				"RING_CTX_TIMESTAMP"
    349			},
    350			{
    351				i915_mmio_reg_offset(GEN8_RING_CS_GPR(engine->mmio_base, 0)),
    352				lrc_ring_gpr0(engine),
    353				"RING_CS_GPR0"
    354			},
    355			{
    356				i915_mmio_reg_offset(RING_CMD_BUF_CCTL(engine->mmio_base)),
    357				lrc_ring_cmd_buf_cctl(engine),
    358				"RING_CMD_BUF_CCTL"
    359			},
    360			{ },
    361		}, *t;
    362		u32 *hw;
    363
    364		if (!engine->default_state)
    365			continue;
    366
    367		hw = shmem_pin_map(engine->default_state);
    368		if (IS_ERR(hw)) {
    369			err = PTR_ERR(hw);
    370			break;
    371		}
    372		hw += LRC_STATE_OFFSET / sizeof(*hw);
    373
    374		for (t = tbl; t->name; t++) {
    375			int dw = find_offset(hw, t->reg);
    376
    377			if (dw != t->offset) {
    378				pr_err("%s: Offset for %s [0x%x] mismatch, found %x, expected %x\n",
    379				       engine->name,
    380				       t->name,
    381				       t->reg,
    382				       dw,
    383				       t->offset);
    384				err = -EINVAL;
    385			}
    386		}
    387
    388		shmem_unpin_map(engine->default_state, hw);
    389	}
    390
    391	return err;
    392}
    393
    394static int __live_lrc_state(struct intel_engine_cs *engine,
    395			    struct i915_vma *scratch)
    396{
    397	struct intel_context *ce;
    398	struct i915_request *rq;
    399	struct i915_gem_ww_ctx ww;
    400	enum {
    401		RING_START_IDX = 0,
    402		RING_TAIL_IDX,
    403		MAX_IDX
    404	};
    405	u32 expected[MAX_IDX];
    406	u32 *cs;
    407	int err;
    408	int n;
    409
    410	ce = intel_context_create(engine);
    411	if (IS_ERR(ce))
    412		return PTR_ERR(ce);
    413
    414	i915_gem_ww_ctx_init(&ww, false);
    415retry:
    416	err = i915_gem_object_lock(scratch->obj, &ww);
    417	if (!err)
    418		err = intel_context_pin_ww(ce, &ww);
    419	if (err)
    420		goto err_put;
    421
    422	rq = i915_request_create(ce);
    423	if (IS_ERR(rq)) {
    424		err = PTR_ERR(rq);
    425		goto err_unpin;
    426	}
    427
    428	cs = intel_ring_begin(rq, 4 * MAX_IDX);
    429	if (IS_ERR(cs)) {
    430		err = PTR_ERR(cs);
    431		i915_request_add(rq);
    432		goto err_unpin;
    433	}
    434
    435	*cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
    436	*cs++ = i915_mmio_reg_offset(RING_START(engine->mmio_base));
    437	*cs++ = i915_ggtt_offset(scratch) + RING_START_IDX * sizeof(u32);
    438	*cs++ = 0;
    439
    440	expected[RING_START_IDX] = i915_ggtt_offset(ce->ring->vma);
    441
    442	*cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
    443	*cs++ = i915_mmio_reg_offset(RING_TAIL(engine->mmio_base));
    444	*cs++ = i915_ggtt_offset(scratch) + RING_TAIL_IDX * sizeof(u32);
    445	*cs++ = 0;
    446
    447	err = i915_request_await_object(rq, scratch->obj, true);
    448	if (!err)
    449		err = i915_vma_move_to_active(scratch, rq, EXEC_OBJECT_WRITE);
    450
    451	i915_request_get(rq);
    452	i915_request_add(rq);
    453	if (err)
    454		goto err_rq;
    455
    456	intel_engine_flush_submission(engine);
    457	expected[RING_TAIL_IDX] = ce->ring->tail;
    458
    459	if (i915_request_wait(rq, 0, HZ / 5) < 0) {
    460		err = -ETIME;
    461		goto err_rq;
    462	}
    463
    464	cs = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB);
    465	if (IS_ERR(cs)) {
    466		err = PTR_ERR(cs);
    467		goto err_rq;
    468	}
    469
    470	for (n = 0; n < MAX_IDX; n++) {
    471		if (cs[n] != expected[n]) {
    472			pr_err("%s: Stored register[%d] value[0x%x] did not match expected[0x%x]\n",
    473			       engine->name, n, cs[n], expected[n]);
    474			err = -EINVAL;
    475			break;
    476		}
    477	}
    478
    479	i915_gem_object_unpin_map(scratch->obj);
    480
    481err_rq:
    482	i915_request_put(rq);
    483err_unpin:
    484	intel_context_unpin(ce);
    485err_put:
    486	if (err == -EDEADLK) {
    487		err = i915_gem_ww_ctx_backoff(&ww);
    488		if (!err)
    489			goto retry;
    490	}
    491	i915_gem_ww_ctx_fini(&ww);
    492	intel_context_put(ce);
    493	return err;
    494}
    495
    496static int live_lrc_state(void *arg)
    497{
    498	struct intel_gt *gt = arg;
    499	struct intel_engine_cs *engine;
    500	struct i915_vma *scratch;
    501	enum intel_engine_id id;
    502	int err = 0;
    503
    504	/*
    505	 * Check the live register state matches what we expect for this
    506	 * intel_context.
    507	 */
    508
    509	scratch = create_scratch(gt);
    510	if (IS_ERR(scratch))
    511		return PTR_ERR(scratch);
    512
    513	for_each_engine(engine, gt, id) {
    514		err = __live_lrc_state(engine, scratch);
    515		if (err)
    516			break;
    517	}
    518
    519	if (igt_flush_test(gt->i915))
    520		err = -EIO;
    521
    522	i915_vma_unpin_and_release(&scratch, 0);
    523	return err;
    524}
    525
    526static int gpr_make_dirty(struct intel_context *ce)
    527{
    528	struct i915_request *rq;
    529	u32 *cs;
    530	int n;
    531
    532	rq = intel_context_create_request(ce);
    533	if (IS_ERR(rq))
    534		return PTR_ERR(rq);
    535
    536	cs = intel_ring_begin(rq, 2 * NUM_GPR_DW + 2);
    537	if (IS_ERR(cs)) {
    538		i915_request_add(rq);
    539		return PTR_ERR(cs);
    540	}
    541
    542	*cs++ = MI_LOAD_REGISTER_IMM(NUM_GPR_DW);
    543	for (n = 0; n < NUM_GPR_DW; n++) {
    544		*cs++ = CS_GPR(ce->engine, n);
    545		*cs++ = STACK_MAGIC;
    546	}
    547	*cs++ = MI_NOOP;
    548
    549	intel_ring_advance(rq, cs);
    550
    551	rq->sched.attr.priority = I915_PRIORITY_BARRIER;
    552	i915_request_add(rq);
    553
    554	return 0;
    555}
    556
    557static struct i915_request *
    558__gpr_read(struct intel_context *ce, struct i915_vma *scratch, u32 *slot)
    559{
    560	const u32 offset =
    561		i915_ggtt_offset(ce->engine->status_page.vma) +
    562		offset_in_page(slot);
    563	struct i915_request *rq;
    564	u32 *cs;
    565	int err;
    566	int n;
    567
    568	rq = intel_context_create_request(ce);
    569	if (IS_ERR(rq))
    570		return rq;
    571
    572	cs = intel_ring_begin(rq, 6 + 4 * NUM_GPR_DW);
    573	if (IS_ERR(cs)) {
    574		i915_request_add(rq);
    575		return ERR_CAST(cs);
    576	}
    577
    578	*cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
    579	*cs++ = MI_NOOP;
    580
    581	*cs++ = MI_SEMAPHORE_WAIT |
    582		MI_SEMAPHORE_GLOBAL_GTT |
    583		MI_SEMAPHORE_POLL |
    584		MI_SEMAPHORE_SAD_NEQ_SDD;
    585	*cs++ = 0;
    586	*cs++ = offset;
    587	*cs++ = 0;
    588
    589	for (n = 0; n < NUM_GPR_DW; n++) {
    590		*cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
    591		*cs++ = CS_GPR(ce->engine, n);
    592		*cs++ = i915_ggtt_offset(scratch) + n * sizeof(u32);
    593		*cs++ = 0;
    594	}
    595
    596	i915_vma_lock(scratch);
    597	err = i915_request_await_object(rq, scratch->obj, true);
    598	if (!err)
    599		err = i915_vma_move_to_active(scratch, rq, EXEC_OBJECT_WRITE);
    600	i915_vma_unlock(scratch);
    601
    602	i915_request_get(rq);
    603	i915_request_add(rq);
    604	if (err) {
    605		i915_request_put(rq);
    606		rq = ERR_PTR(err);
    607	}
    608
    609	return rq;
    610}
    611
    612static int __live_lrc_gpr(struct intel_engine_cs *engine,
    613			  struct i915_vma *scratch,
    614			  bool preempt)
    615{
    616	u32 *slot = memset32(engine->status_page.addr + 1000, 0, 4);
    617	struct intel_context *ce;
    618	struct i915_request *rq;
    619	u32 *cs;
    620	int err;
    621	int n;
    622
    623	if (GRAPHICS_VER(engine->i915) < 9 && engine->class != RENDER_CLASS)
    624		return 0; /* GPR only on rcs0 for gen8 */
    625
    626	err = gpr_make_dirty(engine->kernel_context);
    627	if (err)
    628		return err;
    629
    630	ce = intel_context_create(engine);
    631	if (IS_ERR(ce))
    632		return PTR_ERR(ce);
    633
    634	rq = __gpr_read(ce, scratch, slot);
    635	if (IS_ERR(rq)) {
    636		err = PTR_ERR(rq);
    637		goto err_put;
    638	}
    639
    640	err = wait_for_submit(engine, rq, HZ / 2);
    641	if (err)
    642		goto err_rq;
    643
    644	if (preempt) {
    645		err = gpr_make_dirty(engine->kernel_context);
    646		if (err)
    647			goto err_rq;
    648
    649		err = emit_semaphore_signal(engine->kernel_context, slot);
    650		if (err)
    651			goto err_rq;
    652
    653		err = wait_for_submit(engine, rq, HZ / 2);
    654		if (err)
    655			goto err_rq;
    656	} else {
    657		slot[0] = 1;
    658		wmb();
    659	}
    660
    661	if (i915_request_wait(rq, 0, HZ / 5) < 0) {
    662		err = -ETIME;
    663		goto err_rq;
    664	}
    665
    666	cs = i915_gem_object_pin_map_unlocked(scratch->obj, I915_MAP_WB);
    667	if (IS_ERR(cs)) {
    668		err = PTR_ERR(cs);
    669		goto err_rq;
    670	}
    671
    672	for (n = 0; n < NUM_GPR_DW; n++) {
    673		if (cs[n]) {
    674			pr_err("%s: GPR[%d].%s was not zero, found 0x%08x!\n",
    675			       engine->name,
    676			       n / 2, n & 1 ? "udw" : "ldw",
    677			       cs[n]);
    678			err = -EINVAL;
    679			break;
    680		}
    681	}
    682
    683	i915_gem_object_unpin_map(scratch->obj);
    684
    685err_rq:
    686	memset32(&slot[0], -1, 4);
    687	wmb();
    688	i915_request_put(rq);
    689err_put:
    690	intel_context_put(ce);
    691	return err;
    692}
    693
    694static int live_lrc_gpr(void *arg)
    695{
    696	struct intel_gt *gt = arg;
    697	struct intel_engine_cs *engine;
    698	struct i915_vma *scratch;
    699	enum intel_engine_id id;
    700	int err = 0;
    701
    702	/*
    703	 * Check that GPR registers are cleared in new contexts as we need
    704	 * to avoid leaking any information from previous contexts.
    705	 */
    706
    707	scratch = create_scratch(gt);
    708	if (IS_ERR(scratch))
    709		return PTR_ERR(scratch);
    710
    711	for_each_engine(engine, gt, id) {
    712		st_engine_heartbeat_disable(engine);
    713
    714		err = __live_lrc_gpr(engine, scratch, false);
    715		if (err)
    716			goto err;
    717
    718		err = __live_lrc_gpr(engine, scratch, true);
    719		if (err)
    720			goto err;
    721
    722err:
    723		st_engine_heartbeat_enable(engine);
    724		if (igt_flush_test(gt->i915))
    725			err = -EIO;
    726		if (err)
    727			break;
    728	}
    729
    730	i915_vma_unpin_and_release(&scratch, 0);
    731	return err;
    732}
    733
    734static struct i915_request *
    735create_timestamp(struct intel_context *ce, void *slot, int idx)
    736{
    737	const u32 offset =
    738		i915_ggtt_offset(ce->engine->status_page.vma) +
    739		offset_in_page(slot);
    740	struct i915_request *rq;
    741	u32 *cs;
    742	int err;
    743
    744	rq = intel_context_create_request(ce);
    745	if (IS_ERR(rq))
    746		return rq;
    747
    748	cs = intel_ring_begin(rq, 10);
    749	if (IS_ERR(cs)) {
    750		err = PTR_ERR(cs);
    751		goto err;
    752	}
    753
    754	*cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
    755	*cs++ = MI_NOOP;
    756
    757	*cs++ = MI_SEMAPHORE_WAIT |
    758		MI_SEMAPHORE_GLOBAL_GTT |
    759		MI_SEMAPHORE_POLL |
    760		MI_SEMAPHORE_SAD_NEQ_SDD;
    761	*cs++ = 0;
    762	*cs++ = offset;
    763	*cs++ = 0;
    764
    765	*cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT;
    766	*cs++ = i915_mmio_reg_offset(RING_CTX_TIMESTAMP(rq->engine->mmio_base));
    767	*cs++ = offset + idx * sizeof(u32);
    768	*cs++ = 0;
    769
    770	intel_ring_advance(rq, cs);
    771
    772	err = 0;
    773err:
    774	i915_request_get(rq);
    775	i915_request_add(rq);
    776	if (err) {
    777		i915_request_put(rq);
    778		return ERR_PTR(err);
    779	}
    780
    781	return rq;
    782}
    783
    784struct lrc_timestamp {
    785	struct intel_engine_cs *engine;
    786	struct intel_context *ce[2];
    787	u32 poison;
    788};
    789
    790static bool timestamp_advanced(u32 start, u32 end)
    791{
    792	return (s32)(end - start) > 0;
    793}
    794
    795static int __lrc_timestamp(const struct lrc_timestamp *arg, bool preempt)
    796{
    797	u32 *slot = memset32(arg->engine->status_page.addr + 1000, 0, 4);
    798	struct i915_request *rq;
    799	u32 timestamp;
    800	int err = 0;
    801
    802	arg->ce[0]->lrc_reg_state[CTX_TIMESTAMP] = arg->poison;
    803	rq = create_timestamp(arg->ce[0], slot, 1);
    804	if (IS_ERR(rq))
    805		return PTR_ERR(rq);
    806
    807	err = wait_for_submit(rq->engine, rq, HZ / 2);
    808	if (err)
    809		goto err;
    810
    811	if (preempt) {
    812		arg->ce[1]->lrc_reg_state[CTX_TIMESTAMP] = 0xdeadbeef;
    813		err = emit_semaphore_signal(arg->ce[1], slot);
    814		if (err)
    815			goto err;
    816	} else {
    817		slot[0] = 1;
    818		wmb();
    819	}
    820
    821	/* And wait for switch to kernel (to save our context to memory) */
    822	err = context_flush(arg->ce[0], HZ / 2);
    823	if (err)
    824		goto err;
    825
    826	if (!timestamp_advanced(arg->poison, slot[1])) {
    827		pr_err("%s(%s): invalid timestamp on restore, context:%x, request:%x\n",
    828		       arg->engine->name, preempt ? "preempt" : "simple",
    829		       arg->poison, slot[1]);
    830		err = -EINVAL;
    831	}
    832
    833	timestamp = READ_ONCE(arg->ce[0]->lrc_reg_state[CTX_TIMESTAMP]);
    834	if (!timestamp_advanced(slot[1], timestamp)) {
    835		pr_err("%s(%s): invalid timestamp on save, request:%x, context:%x\n",
    836		       arg->engine->name, preempt ? "preempt" : "simple",
    837		       slot[1], timestamp);
    838		err = -EINVAL;
    839	}
    840
    841err:
    842	memset32(slot, -1, 4);
    843	i915_request_put(rq);
    844	return err;
    845}
    846
    847static int live_lrc_timestamp(void *arg)
    848{
    849	struct lrc_timestamp data = {};
    850	struct intel_gt *gt = arg;
    851	enum intel_engine_id id;
    852	const u32 poison[] = {
    853		0,
    854		S32_MAX,
    855		(u32)S32_MAX + 1,
    856		U32_MAX,
    857	};
    858
    859	/*
    860	 * We want to verify that the timestamp is saved and restore across
    861	 * context switches and is monotonic.
    862	 *
    863	 * So we do this with a little bit of LRC poisoning to check various
    864	 * boundary conditions, and see what happens if we preempt the context
    865	 * with a second request (carrying more poison into the timestamp).
    866	 */
    867
    868	for_each_engine(data.engine, gt, id) {
    869		int i, err = 0;
    870
    871		st_engine_heartbeat_disable(data.engine);
    872
    873		for (i = 0; i < ARRAY_SIZE(data.ce); i++) {
    874			struct intel_context *tmp;
    875
    876			tmp = intel_context_create(data.engine);
    877			if (IS_ERR(tmp)) {
    878				err = PTR_ERR(tmp);
    879				goto err;
    880			}
    881
    882			err = intel_context_pin(tmp);
    883			if (err) {
    884				intel_context_put(tmp);
    885				goto err;
    886			}
    887
    888			data.ce[i] = tmp;
    889		}
    890
    891		for (i = 0; i < ARRAY_SIZE(poison); i++) {
    892			data.poison = poison[i];
    893
    894			err = __lrc_timestamp(&data, false);
    895			if (err)
    896				break;
    897
    898			err = __lrc_timestamp(&data, true);
    899			if (err)
    900				break;
    901		}
    902
    903err:
    904		st_engine_heartbeat_enable(data.engine);
    905		for (i = 0; i < ARRAY_SIZE(data.ce); i++) {
    906			if (!data.ce[i])
    907				break;
    908
    909			intel_context_unpin(data.ce[i]);
    910			intel_context_put(data.ce[i]);
    911		}
    912
    913		if (igt_flush_test(gt->i915))
    914			err = -EIO;
    915		if (err)
    916			return err;
    917	}
    918
    919	return 0;
    920}
    921
    922static struct i915_vma *
    923create_user_vma(struct i915_address_space *vm, unsigned long size)
    924{
    925	struct drm_i915_gem_object *obj;
    926	struct i915_vma *vma;
    927	int err;
    928
    929	obj = i915_gem_object_create_internal(vm->i915, size);
    930	if (IS_ERR(obj))
    931		return ERR_CAST(obj);
    932
    933	vma = i915_vma_instance(obj, vm, NULL);
    934	if (IS_ERR(vma)) {
    935		i915_gem_object_put(obj);
    936		return vma;
    937	}
    938
    939	err = i915_vma_pin(vma, 0, 0, PIN_USER);
    940	if (err) {
    941		i915_gem_object_put(obj);
    942		return ERR_PTR(err);
    943	}
    944
    945	return vma;
    946}
    947
    948static u32 safe_poison(u32 offset, u32 poison)
    949{
    950	/*
    951	 * Do not enable predication as it will nop all subsequent commands,
    952	 * not only disabling the tests (by preventing all the other SRM) but
    953	 * also preventing the arbitration events at the end of the request.
    954	 */
    955	if (offset == i915_mmio_reg_offset(RING_PREDICATE_RESULT(0)))
    956		poison &= ~REG_BIT(0);
    957
    958	return poison;
    959}
    960
    961static struct i915_vma *
    962store_context(struct intel_context *ce, struct i915_vma *scratch)
    963{
    964	struct i915_vma *batch;
    965	u32 dw, x, *cs, *hw;
    966	u32 *defaults;
    967
    968	batch = create_user_vma(ce->vm, SZ_64K);
    969	if (IS_ERR(batch))
    970		return batch;
    971
    972	cs = i915_gem_object_pin_map_unlocked(batch->obj, I915_MAP_WC);
    973	if (IS_ERR(cs)) {
    974		i915_vma_put(batch);
    975		return ERR_CAST(cs);
    976	}
    977
    978	defaults = shmem_pin_map(ce->engine->default_state);
    979	if (!defaults) {
    980		i915_gem_object_unpin_map(batch->obj);
    981		i915_vma_put(batch);
    982		return ERR_PTR(-ENOMEM);
    983	}
    984
    985	x = 0;
    986	dw = 0;
    987	hw = defaults;
    988	hw += LRC_STATE_OFFSET / sizeof(*hw);
    989	do {
    990		u32 len = hw[dw] & 0x7f;
    991
    992		if (hw[dw] == 0) {
    993			dw++;
    994			continue;
    995		}
    996
    997		if ((hw[dw] & GENMASK(31, 23)) != MI_INSTR(0x22, 0)) {
    998			dw += len + 2;
    999			continue;
   1000		}
   1001
   1002		dw++;
   1003		len = (len + 1) / 2;
   1004		while (len--) {
   1005			*cs++ = MI_STORE_REGISTER_MEM_GEN8;
   1006			*cs++ = hw[dw];
   1007			*cs++ = lower_32_bits(scratch->node.start + x);
   1008			*cs++ = upper_32_bits(scratch->node.start + x);
   1009
   1010			dw += 2;
   1011			x += 4;
   1012		}
   1013	} while (dw < PAGE_SIZE / sizeof(u32) &&
   1014		 (hw[dw] & ~BIT(0)) != MI_BATCH_BUFFER_END);
   1015
   1016	*cs++ = MI_BATCH_BUFFER_END;
   1017
   1018	shmem_unpin_map(ce->engine->default_state, defaults);
   1019
   1020	i915_gem_object_flush_map(batch->obj);
   1021	i915_gem_object_unpin_map(batch->obj);
   1022
   1023	return batch;
   1024}
   1025
   1026static int move_to_active(struct i915_request *rq,
   1027			  struct i915_vma *vma,
   1028			  unsigned int flags)
   1029{
   1030	int err;
   1031
   1032	i915_vma_lock(vma);
   1033	err = i915_request_await_object(rq, vma->obj, flags);
   1034	if (!err)
   1035		err = i915_vma_move_to_active(vma, rq, flags);
   1036	i915_vma_unlock(vma);
   1037
   1038	return err;
   1039}
   1040
   1041static struct i915_request *
   1042record_registers(struct intel_context *ce,
   1043		 struct i915_vma *before,
   1044		 struct i915_vma *after,
   1045		 u32 *sema)
   1046{
   1047	struct i915_vma *b_before, *b_after;
   1048	struct i915_request *rq;
   1049	u32 *cs;
   1050	int err;
   1051
   1052	b_before = store_context(ce, before);
   1053	if (IS_ERR(b_before))
   1054		return ERR_CAST(b_before);
   1055
   1056	b_after = store_context(ce, after);
   1057	if (IS_ERR(b_after)) {
   1058		rq = ERR_CAST(b_after);
   1059		goto err_before;
   1060	}
   1061
   1062	rq = intel_context_create_request(ce);
   1063	if (IS_ERR(rq))
   1064		goto err_after;
   1065
   1066	err = move_to_active(rq, before, EXEC_OBJECT_WRITE);
   1067	if (err)
   1068		goto err_rq;
   1069
   1070	err = move_to_active(rq, b_before, 0);
   1071	if (err)
   1072		goto err_rq;
   1073
   1074	err = move_to_active(rq, after, EXEC_OBJECT_WRITE);
   1075	if (err)
   1076		goto err_rq;
   1077
   1078	err = move_to_active(rq, b_after, 0);
   1079	if (err)
   1080		goto err_rq;
   1081
   1082	cs = intel_ring_begin(rq, 14);
   1083	if (IS_ERR(cs)) {
   1084		err = PTR_ERR(cs);
   1085		goto err_rq;
   1086	}
   1087
   1088	*cs++ = MI_ARB_ON_OFF | MI_ARB_DISABLE;
   1089	*cs++ = MI_BATCH_BUFFER_START_GEN8 | BIT(8);
   1090	*cs++ = lower_32_bits(b_before->node.start);
   1091	*cs++ = upper_32_bits(b_before->node.start);
   1092
   1093	*cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
   1094	*cs++ = MI_SEMAPHORE_WAIT |
   1095		MI_SEMAPHORE_GLOBAL_GTT |
   1096		MI_SEMAPHORE_POLL |
   1097		MI_SEMAPHORE_SAD_NEQ_SDD;
   1098	*cs++ = 0;
   1099	*cs++ = i915_ggtt_offset(ce->engine->status_page.vma) +
   1100		offset_in_page(sema);
   1101	*cs++ = 0;
   1102	*cs++ = MI_NOOP;
   1103
   1104	*cs++ = MI_ARB_ON_OFF | MI_ARB_DISABLE;
   1105	*cs++ = MI_BATCH_BUFFER_START_GEN8 | BIT(8);
   1106	*cs++ = lower_32_bits(b_after->node.start);
   1107	*cs++ = upper_32_bits(b_after->node.start);
   1108
   1109	intel_ring_advance(rq, cs);
   1110
   1111	WRITE_ONCE(*sema, 0);
   1112	i915_request_get(rq);
   1113	i915_request_add(rq);
   1114err_after:
   1115	i915_vma_put(b_after);
   1116err_before:
   1117	i915_vma_put(b_before);
   1118	return rq;
   1119
   1120err_rq:
   1121	i915_request_add(rq);
   1122	rq = ERR_PTR(err);
   1123	goto err_after;
   1124}
   1125
   1126static struct i915_vma *load_context(struct intel_context *ce, u32 poison)
   1127{
   1128	struct i915_vma *batch;
   1129	u32 dw, *cs, *hw;
   1130	u32 *defaults;
   1131
   1132	batch = create_user_vma(ce->vm, SZ_64K);
   1133	if (IS_ERR(batch))
   1134		return batch;
   1135
   1136	cs = i915_gem_object_pin_map_unlocked(batch->obj, I915_MAP_WC);
   1137	if (IS_ERR(cs)) {
   1138		i915_vma_put(batch);
   1139		return ERR_CAST(cs);
   1140	}
   1141
   1142	defaults = shmem_pin_map(ce->engine->default_state);
   1143	if (!defaults) {
   1144		i915_gem_object_unpin_map(batch->obj);
   1145		i915_vma_put(batch);
   1146		return ERR_PTR(-ENOMEM);
   1147	}
   1148
   1149	dw = 0;
   1150	hw = defaults;
   1151	hw += LRC_STATE_OFFSET / sizeof(*hw);
   1152	do {
   1153		u32 len = hw[dw] & 0x7f;
   1154
   1155		if (hw[dw] == 0) {
   1156			dw++;
   1157			continue;
   1158		}
   1159
   1160		if ((hw[dw] & GENMASK(31, 23)) != MI_INSTR(0x22, 0)) {
   1161			dw += len + 2;
   1162			continue;
   1163		}
   1164
   1165		dw++;
   1166		len = (len + 1) / 2;
   1167		*cs++ = MI_LOAD_REGISTER_IMM(len);
   1168		while (len--) {
   1169			*cs++ = hw[dw];
   1170			*cs++ = safe_poison(hw[dw] & get_lri_mask(ce->engine,
   1171								  MI_LRI_LRM_CS_MMIO),
   1172					    poison);
   1173			dw += 2;
   1174		}
   1175	} while (dw < PAGE_SIZE / sizeof(u32) &&
   1176		 (hw[dw] & ~BIT(0)) != MI_BATCH_BUFFER_END);
   1177
   1178	*cs++ = MI_BATCH_BUFFER_END;
   1179
   1180	shmem_unpin_map(ce->engine->default_state, defaults);
   1181
   1182	i915_gem_object_flush_map(batch->obj);
   1183	i915_gem_object_unpin_map(batch->obj);
   1184
   1185	return batch;
   1186}
   1187
   1188static int poison_registers(struct intel_context *ce, u32 poison, u32 *sema)
   1189{
   1190	struct i915_request *rq;
   1191	struct i915_vma *batch;
   1192	u32 *cs;
   1193	int err;
   1194
   1195	batch = load_context(ce, poison);
   1196	if (IS_ERR(batch))
   1197		return PTR_ERR(batch);
   1198
   1199	rq = intel_context_create_request(ce);
   1200	if (IS_ERR(rq)) {
   1201		err = PTR_ERR(rq);
   1202		goto err_batch;
   1203	}
   1204
   1205	err = move_to_active(rq, batch, 0);
   1206	if (err)
   1207		goto err_rq;
   1208
   1209	cs = intel_ring_begin(rq, 8);
   1210	if (IS_ERR(cs)) {
   1211		err = PTR_ERR(cs);
   1212		goto err_rq;
   1213	}
   1214
   1215	*cs++ = MI_ARB_ON_OFF | MI_ARB_DISABLE;
   1216	*cs++ = MI_BATCH_BUFFER_START_GEN8 | BIT(8);
   1217	*cs++ = lower_32_bits(batch->node.start);
   1218	*cs++ = upper_32_bits(batch->node.start);
   1219
   1220	*cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
   1221	*cs++ = i915_ggtt_offset(ce->engine->status_page.vma) +
   1222		offset_in_page(sema);
   1223	*cs++ = 0;
   1224	*cs++ = 1;
   1225
   1226	intel_ring_advance(rq, cs);
   1227
   1228	rq->sched.attr.priority = I915_PRIORITY_BARRIER;
   1229err_rq:
   1230	i915_request_add(rq);
   1231err_batch:
   1232	i915_vma_put(batch);
   1233	return err;
   1234}
   1235
   1236static bool is_moving(u32 a, u32 b)
   1237{
   1238	return a != b;
   1239}
   1240
   1241static int compare_isolation(struct intel_engine_cs *engine,
   1242			     struct i915_vma *ref[2],
   1243			     struct i915_vma *result[2],
   1244			     struct intel_context *ce,
   1245			     u32 poison)
   1246{
   1247	u32 x, dw, *hw, *lrc;
   1248	u32 *A[2], *B[2];
   1249	u32 *defaults;
   1250	int err = 0;
   1251
   1252	A[0] = i915_gem_object_pin_map_unlocked(ref[0]->obj, I915_MAP_WC);
   1253	if (IS_ERR(A[0]))
   1254		return PTR_ERR(A[0]);
   1255
   1256	A[1] = i915_gem_object_pin_map_unlocked(ref[1]->obj, I915_MAP_WC);
   1257	if (IS_ERR(A[1])) {
   1258		err = PTR_ERR(A[1]);
   1259		goto err_A0;
   1260	}
   1261
   1262	B[0] = i915_gem_object_pin_map_unlocked(result[0]->obj, I915_MAP_WC);
   1263	if (IS_ERR(B[0])) {
   1264		err = PTR_ERR(B[0]);
   1265		goto err_A1;
   1266	}
   1267
   1268	B[1] = i915_gem_object_pin_map_unlocked(result[1]->obj, I915_MAP_WC);
   1269	if (IS_ERR(B[1])) {
   1270		err = PTR_ERR(B[1]);
   1271		goto err_B0;
   1272	}
   1273
   1274	lrc = i915_gem_object_pin_map_unlocked(ce->state->obj,
   1275					       i915_coherent_map_type(engine->i915,
   1276								      ce->state->obj,
   1277								      false));
   1278	if (IS_ERR(lrc)) {
   1279		err = PTR_ERR(lrc);
   1280		goto err_B1;
   1281	}
   1282	lrc += LRC_STATE_OFFSET / sizeof(*hw);
   1283
   1284	defaults = shmem_pin_map(ce->engine->default_state);
   1285	if (!defaults) {
   1286		err = -ENOMEM;
   1287		goto err_lrc;
   1288	}
   1289
   1290	x = 0;
   1291	dw = 0;
   1292	hw = defaults;
   1293	hw += LRC_STATE_OFFSET / sizeof(*hw);
   1294	do {
   1295		u32 len = hw[dw] & 0x7f;
   1296
   1297		if (hw[dw] == 0) {
   1298			dw++;
   1299			continue;
   1300		}
   1301
   1302		if ((hw[dw] & GENMASK(31, 23)) != MI_INSTR(0x22, 0)) {
   1303			dw += len + 2;
   1304			continue;
   1305		}
   1306
   1307		dw++;
   1308		len = (len + 1) / 2;
   1309		while (len--) {
   1310			if (!is_moving(A[0][x], A[1][x]) &&
   1311			    (A[0][x] != B[0][x] || A[1][x] != B[1][x])) {
   1312				switch (hw[dw] & 4095) {
   1313				case 0x30: /* RING_HEAD */
   1314				case 0x34: /* RING_TAIL */
   1315					break;
   1316
   1317				default:
   1318					pr_err("%s[%d]: Mismatch for register %4x, default %08x, reference %08x, result (%08x, %08x), poison %08x, context %08x\n",
   1319					       engine->name, dw,
   1320					       hw[dw], hw[dw + 1],
   1321					       A[0][x], B[0][x], B[1][x],
   1322					       poison, lrc[dw + 1]);
   1323					err = -EINVAL;
   1324				}
   1325			}
   1326			dw += 2;
   1327			x++;
   1328		}
   1329	} while (dw < PAGE_SIZE / sizeof(u32) &&
   1330		 (hw[dw] & ~BIT(0)) != MI_BATCH_BUFFER_END);
   1331
   1332	shmem_unpin_map(ce->engine->default_state, defaults);
   1333err_lrc:
   1334	i915_gem_object_unpin_map(ce->state->obj);
   1335err_B1:
   1336	i915_gem_object_unpin_map(result[1]->obj);
   1337err_B0:
   1338	i915_gem_object_unpin_map(result[0]->obj);
   1339err_A1:
   1340	i915_gem_object_unpin_map(ref[1]->obj);
   1341err_A0:
   1342	i915_gem_object_unpin_map(ref[0]->obj);
   1343	return err;
   1344}
   1345
   1346static int __lrc_isolation(struct intel_engine_cs *engine, u32 poison)
   1347{
   1348	u32 *sema = memset32(engine->status_page.addr + 1000, 0, 1);
   1349	struct i915_vma *ref[2], *result[2];
   1350	struct intel_context *A, *B;
   1351	struct i915_request *rq;
   1352	int err;
   1353
   1354	A = intel_context_create(engine);
   1355	if (IS_ERR(A))
   1356		return PTR_ERR(A);
   1357
   1358	B = intel_context_create(engine);
   1359	if (IS_ERR(B)) {
   1360		err = PTR_ERR(B);
   1361		goto err_A;
   1362	}
   1363
   1364	ref[0] = create_user_vma(A->vm, SZ_64K);
   1365	if (IS_ERR(ref[0])) {
   1366		err = PTR_ERR(ref[0]);
   1367		goto err_B;
   1368	}
   1369
   1370	ref[1] = create_user_vma(A->vm, SZ_64K);
   1371	if (IS_ERR(ref[1])) {
   1372		err = PTR_ERR(ref[1]);
   1373		goto err_ref0;
   1374	}
   1375
   1376	rq = record_registers(A, ref[0], ref[1], sema);
   1377	if (IS_ERR(rq)) {
   1378		err = PTR_ERR(rq);
   1379		goto err_ref1;
   1380	}
   1381
   1382	WRITE_ONCE(*sema, 1);
   1383	wmb();
   1384
   1385	if (i915_request_wait(rq, 0, HZ / 2) < 0) {
   1386		i915_request_put(rq);
   1387		err = -ETIME;
   1388		goto err_ref1;
   1389	}
   1390	i915_request_put(rq);
   1391
   1392	result[0] = create_user_vma(A->vm, SZ_64K);
   1393	if (IS_ERR(result[0])) {
   1394		err = PTR_ERR(result[0]);
   1395		goto err_ref1;
   1396	}
   1397
   1398	result[1] = create_user_vma(A->vm, SZ_64K);
   1399	if (IS_ERR(result[1])) {
   1400		err = PTR_ERR(result[1]);
   1401		goto err_result0;
   1402	}
   1403
   1404	rq = record_registers(A, result[0], result[1], sema);
   1405	if (IS_ERR(rq)) {
   1406		err = PTR_ERR(rq);
   1407		goto err_result1;
   1408	}
   1409
   1410	err = poison_registers(B, poison, sema);
   1411	if (err) {
   1412		WRITE_ONCE(*sema, -1);
   1413		i915_request_put(rq);
   1414		goto err_result1;
   1415	}
   1416
   1417	if (i915_request_wait(rq, 0, HZ / 2) < 0) {
   1418		i915_request_put(rq);
   1419		err = -ETIME;
   1420		goto err_result1;
   1421	}
   1422	i915_request_put(rq);
   1423
   1424	err = compare_isolation(engine, ref, result, A, poison);
   1425
   1426err_result1:
   1427	i915_vma_put(result[1]);
   1428err_result0:
   1429	i915_vma_put(result[0]);
   1430err_ref1:
   1431	i915_vma_put(ref[1]);
   1432err_ref0:
   1433	i915_vma_put(ref[0]);
   1434err_B:
   1435	intel_context_put(B);
   1436err_A:
   1437	intel_context_put(A);
   1438	return err;
   1439}
   1440
   1441static bool skip_isolation(const struct intel_engine_cs *engine)
   1442{
   1443	if (engine->class == COPY_ENGINE_CLASS && GRAPHICS_VER(engine->i915) == 9)
   1444		return true;
   1445
   1446	if (engine->class == RENDER_CLASS && GRAPHICS_VER(engine->i915) == 11)
   1447		return true;
   1448
   1449	return false;
   1450}
   1451
   1452static int live_lrc_isolation(void *arg)
   1453{
   1454	struct intel_gt *gt = arg;
   1455	struct intel_engine_cs *engine;
   1456	enum intel_engine_id id;
   1457	const u32 poison[] = {
   1458		STACK_MAGIC,
   1459		0x3a3a3a3a,
   1460		0x5c5c5c5c,
   1461		0xffffffff,
   1462		0xffff0000,
   1463	};
   1464	int err = 0;
   1465
   1466	/*
   1467	 * Our goal is try and verify that per-context state cannot be
   1468	 * tampered with by another non-privileged client.
   1469	 *
   1470	 * We take the list of context registers from the LRI in the default
   1471	 * context image and attempt to modify that list from a remote context.
   1472	 */
   1473
   1474	for_each_engine(engine, gt, id) {
   1475		int i;
   1476
   1477		/* Just don't even ask */
   1478		if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST_BROKEN) &&
   1479		    skip_isolation(engine))
   1480			continue;
   1481
   1482		intel_engine_pm_get(engine);
   1483		for (i = 0; i < ARRAY_SIZE(poison); i++) {
   1484			int result;
   1485
   1486			result = __lrc_isolation(engine, poison[i]);
   1487			if (result && !err)
   1488				err = result;
   1489
   1490			result = __lrc_isolation(engine, ~poison[i]);
   1491			if (result && !err)
   1492				err = result;
   1493		}
   1494		intel_engine_pm_put(engine);
   1495		if (igt_flush_test(gt->i915)) {
   1496			err = -EIO;
   1497			break;
   1498		}
   1499	}
   1500
   1501	return err;
   1502}
   1503
   1504static int indirect_ctx_submit_req(struct intel_context *ce)
   1505{
   1506	struct i915_request *rq;
   1507	int err = 0;
   1508
   1509	rq = intel_context_create_request(ce);
   1510	if (IS_ERR(rq))
   1511		return PTR_ERR(rq);
   1512
   1513	i915_request_get(rq);
   1514	i915_request_add(rq);
   1515
   1516	if (i915_request_wait(rq, 0, HZ / 5) < 0)
   1517		err = -ETIME;
   1518
   1519	i915_request_put(rq);
   1520
   1521	return err;
   1522}
   1523
   1524#define CTX_BB_CANARY_OFFSET (3 * 1024)
   1525#define CTX_BB_CANARY_INDEX  (CTX_BB_CANARY_OFFSET / sizeof(u32))
   1526
   1527static u32 *
   1528emit_indirect_ctx_bb_canary(const struct intel_context *ce, u32 *cs)
   1529{
   1530	*cs++ = MI_STORE_REGISTER_MEM_GEN8 |
   1531		MI_SRM_LRM_GLOBAL_GTT |
   1532		MI_LRI_LRM_CS_MMIO;
   1533	*cs++ = i915_mmio_reg_offset(RING_START(0));
   1534	*cs++ = i915_ggtt_offset(ce->state) +
   1535		context_wa_bb_offset(ce) +
   1536		CTX_BB_CANARY_OFFSET;
   1537	*cs++ = 0;
   1538
   1539	return cs;
   1540}
   1541
   1542static void
   1543indirect_ctx_bb_setup(struct intel_context *ce)
   1544{
   1545	u32 *cs = context_indirect_bb(ce);
   1546
   1547	cs[CTX_BB_CANARY_INDEX] = 0xdeadf00d;
   1548
   1549	setup_indirect_ctx_bb(ce, ce->engine, emit_indirect_ctx_bb_canary);
   1550}
   1551
   1552static bool check_ring_start(struct intel_context *ce)
   1553{
   1554	const u32 * const ctx_bb = (void *)(ce->lrc_reg_state) -
   1555		LRC_STATE_OFFSET + context_wa_bb_offset(ce);
   1556
   1557	if (ctx_bb[CTX_BB_CANARY_INDEX] == ce->lrc_reg_state[CTX_RING_START])
   1558		return true;
   1559
   1560	pr_err("ring start mismatch: canary 0x%08x vs state 0x%08x\n",
   1561	       ctx_bb[CTX_BB_CANARY_INDEX],
   1562	       ce->lrc_reg_state[CTX_RING_START]);
   1563
   1564	return false;
   1565}
   1566
   1567static int indirect_ctx_bb_check(struct intel_context *ce)
   1568{
   1569	int err;
   1570
   1571	err = indirect_ctx_submit_req(ce);
   1572	if (err)
   1573		return err;
   1574
   1575	if (!check_ring_start(ce))
   1576		return -EINVAL;
   1577
   1578	return 0;
   1579}
   1580
   1581static int __live_lrc_indirect_ctx_bb(struct intel_engine_cs *engine)
   1582{
   1583	struct intel_context *a, *b;
   1584	int err;
   1585
   1586	a = intel_context_create(engine);
   1587	if (IS_ERR(a))
   1588		return PTR_ERR(a);
   1589	err = intel_context_pin(a);
   1590	if (err)
   1591		goto put_a;
   1592
   1593	b = intel_context_create(engine);
   1594	if (IS_ERR(b)) {
   1595		err = PTR_ERR(b);
   1596		goto unpin_a;
   1597	}
   1598	err = intel_context_pin(b);
   1599	if (err)
   1600		goto put_b;
   1601
   1602	/* We use the already reserved extra page in context state */
   1603	if (!a->wa_bb_page) {
   1604		GEM_BUG_ON(b->wa_bb_page);
   1605		GEM_BUG_ON(GRAPHICS_VER(engine->i915) == 12);
   1606		goto unpin_b;
   1607	}
   1608
   1609	/*
   1610	 * In order to test that our per context bb is truly per context,
   1611	 * and executes at the intended spot on context restoring process,
   1612	 * make the batch store the ring start value to memory.
   1613	 * As ring start is restored apriori of starting the indirect ctx bb and
   1614	 * as it will be different for each context, it fits to this purpose.
   1615	 */
   1616	indirect_ctx_bb_setup(a);
   1617	indirect_ctx_bb_setup(b);
   1618
   1619	err = indirect_ctx_bb_check(a);
   1620	if (err)
   1621		goto unpin_b;
   1622
   1623	err = indirect_ctx_bb_check(b);
   1624
   1625unpin_b:
   1626	intel_context_unpin(b);
   1627put_b:
   1628	intel_context_put(b);
   1629unpin_a:
   1630	intel_context_unpin(a);
   1631put_a:
   1632	intel_context_put(a);
   1633
   1634	return err;
   1635}
   1636
   1637static int live_lrc_indirect_ctx_bb(void *arg)
   1638{
   1639	struct intel_gt *gt = arg;
   1640	struct intel_engine_cs *engine;
   1641	enum intel_engine_id id;
   1642	int err = 0;
   1643
   1644	for_each_engine(engine, gt, id) {
   1645		intel_engine_pm_get(engine);
   1646		err = __live_lrc_indirect_ctx_bb(engine);
   1647		intel_engine_pm_put(engine);
   1648
   1649		if (igt_flush_test(gt->i915))
   1650			err = -EIO;
   1651
   1652		if (err)
   1653			break;
   1654	}
   1655
   1656	return err;
   1657}
   1658
   1659static void garbage_reset(struct intel_engine_cs *engine,
   1660			  struct i915_request *rq)
   1661{
   1662	const unsigned int bit = I915_RESET_ENGINE + engine->id;
   1663	unsigned long *lock = &engine->gt->reset.flags;
   1664
   1665	local_bh_disable();
   1666	if (!test_and_set_bit(bit, lock)) {
   1667		tasklet_disable(&engine->sched_engine->tasklet);
   1668
   1669		if (!rq->fence.error)
   1670			__intel_engine_reset_bh(engine, NULL);
   1671
   1672		tasklet_enable(&engine->sched_engine->tasklet);
   1673		clear_and_wake_up_bit(bit, lock);
   1674	}
   1675	local_bh_enable();
   1676}
   1677
   1678static struct i915_request *garbage(struct intel_context *ce,
   1679				    struct rnd_state *prng)
   1680{
   1681	struct i915_request *rq;
   1682	int err;
   1683
   1684	err = intel_context_pin(ce);
   1685	if (err)
   1686		return ERR_PTR(err);
   1687
   1688	prandom_bytes_state(prng,
   1689			    ce->lrc_reg_state,
   1690			    ce->engine->context_size -
   1691			    LRC_STATE_OFFSET);
   1692
   1693	rq = intel_context_create_request(ce);
   1694	if (IS_ERR(rq)) {
   1695		err = PTR_ERR(rq);
   1696		goto err_unpin;
   1697	}
   1698
   1699	i915_request_get(rq);
   1700	i915_request_add(rq);
   1701	return rq;
   1702
   1703err_unpin:
   1704	intel_context_unpin(ce);
   1705	return ERR_PTR(err);
   1706}
   1707
   1708static int __lrc_garbage(struct intel_engine_cs *engine, struct rnd_state *prng)
   1709{
   1710	struct intel_context *ce;
   1711	struct i915_request *hang;
   1712	int err = 0;
   1713
   1714	ce = intel_context_create(engine);
   1715	if (IS_ERR(ce))
   1716		return PTR_ERR(ce);
   1717
   1718	hang = garbage(ce, prng);
   1719	if (IS_ERR(hang)) {
   1720		err = PTR_ERR(hang);
   1721		goto err_ce;
   1722	}
   1723
   1724	if (wait_for_submit(engine, hang, HZ / 2)) {
   1725		i915_request_put(hang);
   1726		err = -ETIME;
   1727		goto err_ce;
   1728	}
   1729
   1730	intel_context_set_banned(ce);
   1731	garbage_reset(engine, hang);
   1732
   1733	intel_engine_flush_submission(engine);
   1734	if (!hang->fence.error) {
   1735		i915_request_put(hang);
   1736		pr_err("%s: corrupted context was not reset\n",
   1737		       engine->name);
   1738		err = -EINVAL;
   1739		goto err_ce;
   1740	}
   1741
   1742	if (i915_request_wait(hang, 0, HZ / 2) < 0) {
   1743		pr_err("%s: corrupted context did not recover\n",
   1744		       engine->name);
   1745		i915_request_put(hang);
   1746		err = -EIO;
   1747		goto err_ce;
   1748	}
   1749	i915_request_put(hang);
   1750
   1751err_ce:
   1752	intel_context_put(ce);
   1753	return err;
   1754}
   1755
   1756static int live_lrc_garbage(void *arg)
   1757{
   1758	struct intel_gt *gt = arg;
   1759	struct intel_engine_cs *engine;
   1760	enum intel_engine_id id;
   1761
   1762	/*
   1763	 * Verify that we can recover if one context state is completely
   1764	 * corrupted.
   1765	 */
   1766
   1767	if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST_BROKEN))
   1768		return 0;
   1769
   1770	for_each_engine(engine, gt, id) {
   1771		I915_RND_STATE(prng);
   1772		int err = 0, i;
   1773
   1774		if (!intel_has_reset_engine(engine->gt))
   1775			continue;
   1776
   1777		intel_engine_pm_get(engine);
   1778		for (i = 0; i < 3; i++) {
   1779			err = __lrc_garbage(engine, &prng);
   1780			if (err)
   1781				break;
   1782		}
   1783		intel_engine_pm_put(engine);
   1784
   1785		if (igt_flush_test(gt->i915))
   1786			err = -EIO;
   1787		if (err)
   1788			return err;
   1789	}
   1790
   1791	return 0;
   1792}
   1793
   1794static int __live_pphwsp_runtime(struct intel_engine_cs *engine)
   1795{
   1796	struct intel_context *ce;
   1797	struct i915_request *rq;
   1798	IGT_TIMEOUT(end_time);
   1799	int err;
   1800
   1801	ce = intel_context_create(engine);
   1802	if (IS_ERR(ce))
   1803		return PTR_ERR(ce);
   1804
   1805	ce->stats.runtime.num_underflow = 0;
   1806	ce->stats.runtime.max_underflow = 0;
   1807
   1808	do {
   1809		unsigned int loop = 1024;
   1810
   1811		while (loop) {
   1812			rq = intel_context_create_request(ce);
   1813			if (IS_ERR(rq)) {
   1814				err = PTR_ERR(rq);
   1815				goto err_rq;
   1816			}
   1817
   1818			if (--loop == 0)
   1819				i915_request_get(rq);
   1820
   1821			i915_request_add(rq);
   1822		}
   1823
   1824		if (__igt_timeout(end_time, NULL))
   1825			break;
   1826
   1827		i915_request_put(rq);
   1828	} while (1);
   1829
   1830	err = i915_request_wait(rq, 0, HZ / 5);
   1831	if (err < 0) {
   1832		pr_err("%s: request not completed!\n", engine->name);
   1833		goto err_wait;
   1834	}
   1835
   1836	igt_flush_test(engine->i915);
   1837
   1838	pr_info("%s: pphwsp runtime %lluns, average %lluns\n",
   1839		engine->name,
   1840		intel_context_get_total_runtime_ns(ce),
   1841		intel_context_get_avg_runtime_ns(ce));
   1842
   1843	err = 0;
   1844	if (ce->stats.runtime.num_underflow) {
   1845		pr_err("%s: pphwsp underflow %u time(s), max %u cycles!\n",
   1846		       engine->name,
   1847		       ce->stats.runtime.num_underflow,
   1848		       ce->stats.runtime.max_underflow);
   1849		GEM_TRACE_DUMP();
   1850		err = -EOVERFLOW;
   1851	}
   1852
   1853err_wait:
   1854	i915_request_put(rq);
   1855err_rq:
   1856	intel_context_put(ce);
   1857	return err;
   1858}
   1859
   1860static int live_pphwsp_runtime(void *arg)
   1861{
   1862	struct intel_gt *gt = arg;
   1863	struct intel_engine_cs *engine;
   1864	enum intel_engine_id id;
   1865	int err = 0;
   1866
   1867	/*
   1868	 * Check that cumulative context runtime as stored in the pphwsp[16]
   1869	 * is monotonic.
   1870	 */
   1871
   1872	for_each_engine(engine, gt, id) {
   1873		err = __live_pphwsp_runtime(engine);
   1874		if (err)
   1875			break;
   1876	}
   1877
   1878	if (igt_flush_test(gt->i915))
   1879		err = -EIO;
   1880
   1881	return err;
   1882}
   1883
   1884int intel_lrc_live_selftests(struct drm_i915_private *i915)
   1885{
   1886	static const struct i915_subtest tests[] = {
   1887		SUBTEST(live_lrc_layout),
   1888		SUBTEST(live_lrc_fixed),
   1889		SUBTEST(live_lrc_state),
   1890		SUBTEST(live_lrc_gpr),
   1891		SUBTEST(live_lrc_isolation),
   1892		SUBTEST(live_lrc_timestamp),
   1893		SUBTEST(live_lrc_garbage),
   1894		SUBTEST(live_pphwsp_runtime),
   1895		SUBTEST(live_lrc_indirect_ctx_bb),
   1896	};
   1897
   1898	if (!HAS_LOGICAL_RING_CONTEXTS(i915))
   1899		return 0;
   1900
   1901	return intel_gt_live_subtests(tests, to_gt(i915));
   1902}