Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1/*
   2 * SPDX-License-Identifier: MIT
   3 *
   4 * Copyright © 2018 Intel Corporation
   5 */
   6
   7#include "gem/i915_gem_pm.h"
   8#include "gt/intel_engine_user.h"
   9#include "gt/intel_gt.h"
  10#include "i915_selftest.h"
  11#include "intel_reset.h"
  12
  13#include "selftests/igt_flush_test.h"
  14#include "selftests/igt_reset.h"
  15#include "selftests/igt_spinner.h"
  16#include "selftests/mock_drm.h"
  17
  18#include "gem/selftests/igt_gem_utils.h"
  19#include "gem/selftests/mock_context.h"
  20
  21static const struct wo_register {
  22	enum intel_platform platform;
  23	u32 reg;
  24} wo_registers[] = {
  25	{ INTEL_GEMINILAKE, 0x731c }
  26};
  27
  28struct wa_lists {
  29	struct i915_wa_list gt_wa_list;
  30	struct {
  31		struct i915_wa_list wa_list;
  32		struct i915_wa_list ctx_wa_list;
  33	} engine[I915_NUM_ENGINES];
  34};
  35
  36static int request_add_sync(struct i915_request *rq, int err)
  37{
  38	i915_request_get(rq);
  39	i915_request_add(rq);
  40	if (i915_request_wait(rq, 0, HZ / 5) < 0)
  41		err = -EIO;
  42	i915_request_put(rq);
  43
  44	return err;
  45}
  46
  47static int request_add_spin(struct i915_request *rq, struct igt_spinner *spin)
  48{
  49	int err = 0;
  50
  51	i915_request_get(rq);
  52	i915_request_add(rq);
  53	if (spin && !igt_wait_for_spinner(spin, rq))
  54		err = -ETIMEDOUT;
  55	i915_request_put(rq);
  56
  57	return err;
  58}
  59
  60static void
  61reference_lists_init(struct intel_gt *gt, struct wa_lists *lists)
  62{
  63	struct intel_engine_cs *engine;
  64	enum intel_engine_id id;
  65
  66	memset(lists, 0, sizeof(*lists));
  67
  68	wa_init_start(&lists->gt_wa_list, "GT_REF", "global");
  69	gt_init_workarounds(gt->i915, &lists->gt_wa_list);
  70	wa_init_finish(&lists->gt_wa_list);
  71
  72	for_each_engine(engine, gt, id) {
  73		struct i915_wa_list *wal = &lists->engine[id].wa_list;
  74
  75		wa_init_start(wal, "REF", engine->name);
  76		engine_init_workarounds(engine, wal);
  77		wa_init_finish(wal);
  78
  79		__intel_engine_init_ctx_wa(engine,
  80					   &lists->engine[id].ctx_wa_list,
  81					   "CTX_REF");
  82	}
  83}
  84
  85static void
  86reference_lists_fini(struct intel_gt *gt, struct wa_lists *lists)
  87{
  88	struct intel_engine_cs *engine;
  89	enum intel_engine_id id;
  90
  91	for_each_engine(engine, gt, id)
  92		intel_wa_list_free(&lists->engine[id].wa_list);
  93
  94	intel_wa_list_free(&lists->gt_wa_list);
  95}
  96
  97static struct drm_i915_gem_object *
  98read_nonprivs(struct i915_gem_context *ctx, struct intel_engine_cs *engine)
  99{
 100	const u32 base = engine->mmio_base;
 101	struct drm_i915_gem_object *result;
 102	struct i915_request *rq;
 103	struct i915_vma *vma;
 104	u32 srm, *cs;
 105	int err;
 106	int i;
 107
 108	result = i915_gem_object_create_internal(engine->i915, PAGE_SIZE);
 109	if (IS_ERR(result))
 110		return result;
 111
 112	i915_gem_object_set_cache_coherency(result, I915_CACHE_LLC);
 113
 114	cs = i915_gem_object_pin_map(result, I915_MAP_WB);
 115	if (IS_ERR(cs)) {
 116		err = PTR_ERR(cs);
 117		goto err_obj;
 118	}
 119	memset(cs, 0xc5, PAGE_SIZE);
 120	i915_gem_object_flush_map(result);
 121	i915_gem_object_unpin_map(result);
 122
 123	vma = i915_vma_instance(result, &engine->gt->ggtt->vm, NULL);
 124	if (IS_ERR(vma)) {
 125		err = PTR_ERR(vma);
 126		goto err_obj;
 127	}
 128
 129	err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL);
 130	if (err)
 131		goto err_obj;
 132
 133	rq = igt_request_alloc(ctx, engine);
 134	if (IS_ERR(rq)) {
 135		err = PTR_ERR(rq);
 136		goto err_pin;
 137	}
 138
 139	i915_vma_lock(vma);
 140	err = i915_request_await_object(rq, vma->obj, true);
 141	if (err == 0)
 142		err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
 143	i915_vma_unlock(vma);
 144	if (err)
 145		goto err_req;
 146
 147	srm = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
 148	if (INTEL_GEN(ctx->i915) >= 8)
 149		srm++;
 150
 151	cs = intel_ring_begin(rq, 4 * RING_MAX_NONPRIV_SLOTS);
 152	if (IS_ERR(cs)) {
 153		err = PTR_ERR(cs);
 154		goto err_req;
 155	}
 156
 157	for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) {
 158		*cs++ = srm;
 159		*cs++ = i915_mmio_reg_offset(RING_FORCE_TO_NONPRIV(base, i));
 160		*cs++ = i915_ggtt_offset(vma) + sizeof(u32) * i;
 161		*cs++ = 0;
 162	}
 163	intel_ring_advance(rq, cs);
 164
 165	i915_request_add(rq);
 166	i915_vma_unpin(vma);
 167
 168	return result;
 169
 170err_req:
 171	i915_request_add(rq);
 172err_pin:
 173	i915_vma_unpin(vma);
 174err_obj:
 175	i915_gem_object_put(result);
 176	return ERR_PTR(err);
 177}
 178
 179static u32
 180get_whitelist_reg(const struct intel_engine_cs *engine, unsigned int i)
 181{
 182	i915_reg_t reg = i < engine->whitelist.count ?
 183			 engine->whitelist.list[i].reg :
 184			 RING_NOPID(engine->mmio_base);
 185
 186	return i915_mmio_reg_offset(reg);
 187}
 188
 189static void
 190print_results(const struct intel_engine_cs *engine, const u32 *results)
 191{
 192	unsigned int i;
 193
 194	for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) {
 195		u32 expected = get_whitelist_reg(engine, i);
 196		u32 actual = results[i];
 197
 198		pr_info("RING_NONPRIV[%d]: expected 0x%08x, found 0x%08x\n",
 199			i, expected, actual);
 200	}
 201}
 202
 203static int check_whitelist(struct i915_gem_context *ctx,
 204			   struct intel_engine_cs *engine)
 205{
 206	struct drm_i915_gem_object *results;
 207	struct intel_wedge_me wedge;
 208	u32 *vaddr;
 209	int err;
 210	int i;
 211
 212	results = read_nonprivs(ctx, engine);
 213	if (IS_ERR(results))
 214		return PTR_ERR(results);
 215
 216	err = 0;
 217	i915_gem_object_lock(results);
 218	intel_wedge_on_timeout(&wedge, engine->gt, HZ / 5) /* safety net! */
 219		err = i915_gem_object_set_to_cpu_domain(results, false);
 220	i915_gem_object_unlock(results);
 221	if (intel_gt_is_wedged(engine->gt))
 222		err = -EIO;
 223	if (err)
 224		goto out_put;
 225
 226	vaddr = i915_gem_object_pin_map(results, I915_MAP_WB);
 227	if (IS_ERR(vaddr)) {
 228		err = PTR_ERR(vaddr);
 229		goto out_put;
 230	}
 231
 232	for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++) {
 233		u32 expected = get_whitelist_reg(engine, i);
 234		u32 actual = vaddr[i];
 235
 236		if (expected != actual) {
 237			print_results(engine, vaddr);
 238			pr_err("Invalid RING_NONPRIV[%d], expected 0x%08x, found 0x%08x\n",
 239			       i, expected, actual);
 240
 241			err = -EINVAL;
 242			break;
 243		}
 244	}
 245
 246	i915_gem_object_unpin_map(results);
 247out_put:
 248	i915_gem_object_put(results);
 249	return err;
 250}
 251
 252static int do_device_reset(struct intel_engine_cs *engine)
 253{
 254	intel_gt_reset(engine->gt, engine->mask, "live_workarounds");
 255	return 0;
 256}
 257
 258static int do_engine_reset(struct intel_engine_cs *engine)
 259{
 260	return intel_engine_reset(engine, "live_workarounds");
 261}
 262
 263static int
 264switch_to_scratch_context(struct intel_engine_cs *engine,
 265			  struct igt_spinner *spin)
 266{
 267	struct intel_context *ce;
 268	struct i915_request *rq;
 269	int err = 0;
 270
 271	ce = intel_context_create(engine);
 272	if (IS_ERR(ce))
 273		return PTR_ERR(ce);
 274
 275	rq = igt_spinner_create_request(spin, ce, MI_NOOP);
 276	intel_context_put(ce);
 277
 278	if (IS_ERR(rq)) {
 279		spin = NULL;
 280		err = PTR_ERR(rq);
 281		goto err;
 282	}
 283
 284	err = request_add_spin(rq, spin);
 285err:
 286	if (err && spin)
 287		igt_spinner_end(spin);
 288
 289	return err;
 290}
 291
 292static int check_whitelist_across_reset(struct intel_engine_cs *engine,
 293					int (*reset)(struct intel_engine_cs *),
 294					const char *name)
 295{
 296	struct drm_i915_private *i915 = engine->i915;
 297	struct i915_gem_context *ctx, *tmp;
 298	struct igt_spinner spin;
 299	intel_wakeref_t wakeref;
 300	int err;
 301
 302	pr_info("Checking %d whitelisted registers on %s (RING_NONPRIV) [%s]\n",
 303		engine->whitelist.count, engine->name, name);
 304
 305	ctx = kernel_context(i915);
 306	if (IS_ERR(ctx))
 307		return PTR_ERR(ctx);
 308
 309	err = igt_spinner_init(&spin, engine->gt);
 310	if (err)
 311		goto out_ctx;
 312
 313	err = check_whitelist(ctx, engine);
 314	if (err) {
 315		pr_err("Invalid whitelist *before* %s reset!\n", name);
 316		goto out_spin;
 317	}
 318
 319	err = switch_to_scratch_context(engine, &spin);
 320	if (err)
 321		goto out_spin;
 322
 323	with_intel_runtime_pm(engine->uncore->rpm, wakeref)
 324		err = reset(engine);
 325
 326	igt_spinner_end(&spin);
 327
 328	if (err) {
 329		pr_err("%s reset failed\n", name);
 330		goto out_spin;
 331	}
 332
 333	err = check_whitelist(ctx, engine);
 334	if (err) {
 335		pr_err("Whitelist not preserved in context across %s reset!\n",
 336		       name);
 337		goto out_spin;
 338	}
 339
 340	tmp = kernel_context(i915);
 341	if (IS_ERR(tmp)) {
 342		err = PTR_ERR(tmp);
 343		goto out_spin;
 344	}
 345	kernel_context_close(ctx);
 346	ctx = tmp;
 347
 348	err = check_whitelist(ctx, engine);
 349	if (err) {
 350		pr_err("Invalid whitelist *after* %s reset in fresh context!\n",
 351		       name);
 352		goto out_spin;
 353	}
 354
 355out_spin:
 356	igt_spinner_fini(&spin);
 357out_ctx:
 358	kernel_context_close(ctx);
 359	return err;
 360}
 361
 362static struct i915_vma *create_batch(struct i915_address_space *vm)
 363{
 364	struct drm_i915_gem_object *obj;
 365	struct i915_vma *vma;
 366	int err;
 367
 368	obj = i915_gem_object_create_internal(vm->i915, 16 * PAGE_SIZE);
 369	if (IS_ERR(obj))
 370		return ERR_CAST(obj);
 371
 372	vma = i915_vma_instance(obj, vm, NULL);
 373	if (IS_ERR(vma)) {
 374		err = PTR_ERR(vma);
 375		goto err_obj;
 376	}
 377
 378	err = i915_vma_pin(vma, 0, 0, PIN_USER);
 379	if (err)
 380		goto err_obj;
 381
 382	return vma;
 383
 384err_obj:
 385	i915_gem_object_put(obj);
 386	return ERR_PTR(err);
 387}
 388
 389static u32 reg_write(u32 old, u32 new, u32 rsvd)
 390{
 391	if (rsvd == 0x0000ffff) {
 392		old &= ~(new >> 16);
 393		old |= new & (new >> 16);
 394	} else {
 395		old &= ~rsvd;
 396		old |= new & rsvd;
 397	}
 398
 399	return old;
 400}
 401
 402static bool wo_register(struct intel_engine_cs *engine, u32 reg)
 403{
 404	enum intel_platform platform = INTEL_INFO(engine->i915)->platform;
 405	int i;
 406
 407	if ((reg & RING_FORCE_TO_NONPRIV_ACCESS_MASK) ==
 408	     RING_FORCE_TO_NONPRIV_ACCESS_WR)
 409		return true;
 410
 411	for (i = 0; i < ARRAY_SIZE(wo_registers); i++) {
 412		if (wo_registers[i].platform == platform &&
 413		    wo_registers[i].reg == reg)
 414			return true;
 415	}
 416
 417	return false;
 418}
 419
 420static bool timestamp(const struct intel_engine_cs *engine, u32 reg)
 421{
 422	reg = (reg - engine->mmio_base) & ~RING_FORCE_TO_NONPRIV_ACCESS_MASK;
 423	switch (reg) {
 424	case 0x358:
 425	case 0x35c:
 426	case 0x3a8:
 427		return true;
 428
 429	default:
 430		return false;
 431	}
 432}
 433
 434static bool ro_register(u32 reg)
 435{
 436	if ((reg & RING_FORCE_TO_NONPRIV_ACCESS_MASK) ==
 437	     RING_FORCE_TO_NONPRIV_ACCESS_RD)
 438		return true;
 439
 440	return false;
 441}
 442
 443static int whitelist_writable_count(struct intel_engine_cs *engine)
 444{
 445	int count = engine->whitelist.count;
 446	int i;
 447
 448	for (i = 0; i < engine->whitelist.count; i++) {
 449		u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);
 450
 451		if (ro_register(reg))
 452			count--;
 453	}
 454
 455	return count;
 456}
 457
 458static int check_dirty_whitelist(struct intel_context *ce)
 459{
 460	const u32 values[] = {
 461		0x00000000,
 462		0x01010101,
 463		0x10100101,
 464		0x03030303,
 465		0x30300303,
 466		0x05050505,
 467		0x50500505,
 468		0x0f0f0f0f,
 469		0xf00ff00f,
 470		0x10101010,
 471		0xf0f01010,
 472		0x30303030,
 473		0xa0a03030,
 474		0x50505050,
 475		0xc0c05050,
 476		0xf0f0f0f0,
 477		0x11111111,
 478		0x33333333,
 479		0x55555555,
 480		0x0000ffff,
 481		0x00ff00ff,
 482		0xff0000ff,
 483		0xffff00ff,
 484		0xffffffff,
 485	};
 486	struct intel_engine_cs *engine = ce->engine;
 487	struct i915_vma *scratch;
 488	struct i915_vma *batch;
 489	int err = 0, i, v;
 490	u32 *cs, *results;
 491
 492	scratch = create_scratch(ce->vm, 2 * ARRAY_SIZE(values) + 1);
 493	if (IS_ERR(scratch))
 494		return PTR_ERR(scratch);
 495
 496	batch = create_batch(ce->vm);
 497	if (IS_ERR(batch)) {
 498		err = PTR_ERR(batch);
 499		goto out_scratch;
 500	}
 501
 502	for (i = 0; i < engine->whitelist.count; i++) {
 503		u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);
 504		u64 addr = scratch->node.start;
 505		struct i915_request *rq;
 506		u32 srm, lrm, rsvd;
 507		u32 expect;
 508		int idx;
 509		bool ro_reg;
 510
 511		if (wo_register(engine, reg))
 512			continue;
 513
 514		if (timestamp(engine, reg))
 515			continue; /* timestamps are expected to autoincrement */
 516
 517		ro_reg = ro_register(reg);
 518
 519		/* Clear non priv flags */
 520		reg &= RING_FORCE_TO_NONPRIV_ADDRESS_MASK;
 521
 522		srm = MI_STORE_REGISTER_MEM;
 523		lrm = MI_LOAD_REGISTER_MEM;
 524		if (INTEL_GEN(engine->i915) >= 8)
 525			lrm++, srm++;
 526
 527		pr_debug("%s: Writing garbage to %x\n",
 528			 engine->name, reg);
 529
 530		cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC);
 531		if (IS_ERR(cs)) {
 532			err = PTR_ERR(cs);
 533			goto out_batch;
 534		}
 535
 536		/* SRM original */
 537		*cs++ = srm;
 538		*cs++ = reg;
 539		*cs++ = lower_32_bits(addr);
 540		*cs++ = upper_32_bits(addr);
 541
 542		idx = 1;
 543		for (v = 0; v < ARRAY_SIZE(values); v++) {
 544			/* LRI garbage */
 545			*cs++ = MI_LOAD_REGISTER_IMM(1);
 546			*cs++ = reg;
 547			*cs++ = values[v];
 548
 549			/* SRM result */
 550			*cs++ = srm;
 551			*cs++ = reg;
 552			*cs++ = lower_32_bits(addr + sizeof(u32) * idx);
 553			*cs++ = upper_32_bits(addr + sizeof(u32) * idx);
 554			idx++;
 555		}
 556		for (v = 0; v < ARRAY_SIZE(values); v++) {
 557			/* LRI garbage */
 558			*cs++ = MI_LOAD_REGISTER_IMM(1);
 559			*cs++ = reg;
 560			*cs++ = ~values[v];
 561
 562			/* SRM result */
 563			*cs++ = srm;
 564			*cs++ = reg;
 565			*cs++ = lower_32_bits(addr + sizeof(u32) * idx);
 566			*cs++ = upper_32_bits(addr + sizeof(u32) * idx);
 567			idx++;
 568		}
 569		GEM_BUG_ON(idx * sizeof(u32) > scratch->size);
 570
 571		/* LRM original -- don't leave garbage in the context! */
 572		*cs++ = lrm;
 573		*cs++ = reg;
 574		*cs++ = lower_32_bits(addr);
 575		*cs++ = upper_32_bits(addr);
 576
 577		*cs++ = MI_BATCH_BUFFER_END;
 578
 579		i915_gem_object_flush_map(batch->obj);
 580		i915_gem_object_unpin_map(batch->obj);
 581		intel_gt_chipset_flush(engine->gt);
 582
 583		rq = intel_context_create_request(ce);
 584		if (IS_ERR(rq)) {
 585			err = PTR_ERR(rq);
 586			goto out_batch;
 587		}
 588
 589		if (engine->emit_init_breadcrumb) { /* Be nice if we hang */
 590			err = engine->emit_init_breadcrumb(rq);
 591			if (err)
 592				goto err_request;
 593		}
 594
 595		i915_vma_lock(batch);
 596		err = i915_request_await_object(rq, batch->obj, false);
 597		if (err == 0)
 598			err = i915_vma_move_to_active(batch, rq, 0);
 599		i915_vma_unlock(batch);
 600		if (err)
 601			goto err_request;
 602
 603		i915_vma_lock(scratch);
 604		err = i915_request_await_object(rq, scratch->obj, true);
 605		if (err == 0)
 606			err = i915_vma_move_to_active(scratch, rq,
 607						      EXEC_OBJECT_WRITE);
 608		i915_vma_unlock(scratch);
 609		if (err)
 610			goto err_request;
 611
 612		err = engine->emit_bb_start(rq,
 613					    batch->node.start, PAGE_SIZE,
 614					    0);
 615		if (err)
 616			goto err_request;
 617
 618err_request:
 619		err = request_add_sync(rq, err);
 620		if (err) {
 621			pr_err("%s: Futzing %x timedout; cancelling test\n",
 622			       engine->name, reg);
 623			intel_gt_set_wedged(engine->gt);
 624			goto out_batch;
 625		}
 626
 627		results = i915_gem_object_pin_map(scratch->obj, I915_MAP_WB);
 628		if (IS_ERR(results)) {
 629			err = PTR_ERR(results);
 630			goto out_batch;
 631		}
 632
 633		GEM_BUG_ON(values[ARRAY_SIZE(values) - 1] != 0xffffffff);
 634		if (!ro_reg) {
 635			/* detect write masking */
 636			rsvd = results[ARRAY_SIZE(values)];
 637			if (!rsvd) {
 638				pr_err("%s: Unable to write to whitelisted register %x\n",
 639				       engine->name, reg);
 640				err = -EINVAL;
 641				goto out_unpin;
 642			}
 643		} else {
 644			rsvd = 0;
 645		}
 646
 647		expect = results[0];
 648		idx = 1;
 649		for (v = 0; v < ARRAY_SIZE(values); v++) {
 650			if (ro_reg)
 651				expect = results[0];
 652			else
 653				expect = reg_write(expect, values[v], rsvd);
 654
 655			if (results[idx] != expect)
 656				err++;
 657			idx++;
 658		}
 659		for (v = 0; v < ARRAY_SIZE(values); v++) {
 660			if (ro_reg)
 661				expect = results[0];
 662			else
 663				expect = reg_write(expect, ~values[v], rsvd);
 664
 665			if (results[idx] != expect)
 666				err++;
 667			idx++;
 668		}
 669		if (err) {
 670			pr_err("%s: %d mismatch between values written to whitelisted register [%x], and values read back!\n",
 671			       engine->name, err, reg);
 672
 673			if (ro_reg)
 674				pr_info("%s: Whitelisted read-only register: %x, original value %08x\n",
 675					engine->name, reg, results[0]);
 676			else
 677				pr_info("%s: Whitelisted register: %x, original value %08x, rsvd %08x\n",
 678					engine->name, reg, results[0], rsvd);
 679
 680			expect = results[0];
 681			idx = 1;
 682			for (v = 0; v < ARRAY_SIZE(values); v++) {
 683				u32 w = values[v];
 684
 685				if (ro_reg)
 686					expect = results[0];
 687				else
 688					expect = reg_write(expect, w, rsvd);
 689				pr_info("Wrote %08x, read %08x, expect %08x\n",
 690					w, results[idx], expect);
 691				idx++;
 692			}
 693			for (v = 0; v < ARRAY_SIZE(values); v++) {
 694				u32 w = ~values[v];
 695
 696				if (ro_reg)
 697					expect = results[0];
 698				else
 699					expect = reg_write(expect, w, rsvd);
 700				pr_info("Wrote %08x, read %08x, expect %08x\n",
 701					w, results[idx], expect);
 702				idx++;
 703			}
 704
 705			err = -EINVAL;
 706		}
 707out_unpin:
 708		i915_gem_object_unpin_map(scratch->obj);
 709		if (err)
 710			break;
 711	}
 712
 713	if (igt_flush_test(engine->i915))
 714		err = -EIO;
 715out_batch:
 716	i915_vma_unpin_and_release(&batch, 0);
 717out_scratch:
 718	i915_vma_unpin_and_release(&scratch, 0);
 719	return err;
 720}
 721
 722static int live_dirty_whitelist(void *arg)
 723{
 724	struct intel_gt *gt = arg;
 725	struct intel_engine_cs *engine;
 726	enum intel_engine_id id;
 727
 728	/* Can the user write to the whitelisted registers? */
 729
 730	if (INTEL_GEN(gt->i915) < 7) /* minimum requirement for LRI, SRM, LRM */
 731		return 0;
 732
 733	for_each_engine(engine, gt, id) {
 734		struct intel_context *ce;
 735		int err;
 736
 737		if (engine->whitelist.count == 0)
 738			continue;
 739
 740		ce = intel_context_create(engine);
 741		if (IS_ERR(ce))
 742			return PTR_ERR(ce);
 743
 744		err = check_dirty_whitelist(ce);
 745		intel_context_put(ce);
 746		if (err)
 747			return err;
 748	}
 749
 750	return 0;
 751}
 752
 753static int live_reset_whitelist(void *arg)
 754{
 755	struct intel_gt *gt = arg;
 756	struct intel_engine_cs *engine;
 757	enum intel_engine_id id;
 758	int err = 0;
 759
 760	/* If we reset the gpu, we should not lose the RING_NONPRIV */
 761	igt_global_reset_lock(gt);
 762
 763	for_each_engine(engine, gt, id) {
 764		if (engine->whitelist.count == 0)
 765			continue;
 766
 767		if (intel_has_reset_engine(gt)) {
 768			err = check_whitelist_across_reset(engine,
 769							   do_engine_reset,
 770							   "engine");
 771			if (err)
 772				goto out;
 773		}
 774
 775		if (intel_has_gpu_reset(gt)) {
 776			err = check_whitelist_across_reset(engine,
 777							   do_device_reset,
 778							   "device");
 779			if (err)
 780				goto out;
 781		}
 782	}
 783
 784out:
 785	igt_global_reset_unlock(gt);
 786	return err;
 787}
 788
 789static int read_whitelisted_registers(struct i915_gem_context *ctx,
 790				      struct intel_engine_cs *engine,
 791				      struct i915_vma *results)
 792{
 793	struct i915_request *rq;
 794	int i, err = 0;
 795	u32 srm, *cs;
 796
 797	rq = igt_request_alloc(ctx, engine);
 798	if (IS_ERR(rq))
 799		return PTR_ERR(rq);
 800
 801	i915_vma_lock(results);
 802	err = i915_request_await_object(rq, results->obj, true);
 803	if (err == 0)
 804		err = i915_vma_move_to_active(results, rq, EXEC_OBJECT_WRITE);
 805	i915_vma_unlock(results);
 806	if (err)
 807		goto err_req;
 808
 809	srm = MI_STORE_REGISTER_MEM;
 810	if (INTEL_GEN(ctx->i915) >= 8)
 811		srm++;
 812
 813	cs = intel_ring_begin(rq, 4 * engine->whitelist.count);
 814	if (IS_ERR(cs)) {
 815		err = PTR_ERR(cs);
 816		goto err_req;
 817	}
 818
 819	for (i = 0; i < engine->whitelist.count; i++) {
 820		u64 offset = results->node.start + sizeof(u32) * i;
 821		u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);
 822
 823		/* Clear non priv flags */
 824		reg &= RING_FORCE_TO_NONPRIV_ADDRESS_MASK;
 825
 826		*cs++ = srm;
 827		*cs++ = reg;
 828		*cs++ = lower_32_bits(offset);
 829		*cs++ = upper_32_bits(offset);
 830	}
 831	intel_ring_advance(rq, cs);
 832
 833err_req:
 834	return request_add_sync(rq, err);
 835}
 836
 837static int scrub_whitelisted_registers(struct i915_gem_context *ctx,
 838				       struct intel_engine_cs *engine)
 839{
 840	struct i915_address_space *vm;
 841	struct i915_request *rq;
 842	struct i915_vma *batch;
 843	int i, err = 0;
 844	u32 *cs;
 845
 846	vm = i915_gem_context_get_vm_rcu(ctx);
 847	batch = create_batch(vm);
 848	i915_vm_put(vm);
 849	if (IS_ERR(batch))
 850		return PTR_ERR(batch);
 851
 852	cs = i915_gem_object_pin_map(batch->obj, I915_MAP_WC);
 853	if (IS_ERR(cs)) {
 854		err = PTR_ERR(cs);
 855		goto err_batch;
 856	}
 857
 858	*cs++ = MI_LOAD_REGISTER_IMM(whitelist_writable_count(engine));
 859	for (i = 0; i < engine->whitelist.count; i++) {
 860		u32 reg = i915_mmio_reg_offset(engine->whitelist.list[i].reg);
 861
 862		if (ro_register(reg))
 863			continue;
 864
 865		/* Clear non priv flags */
 866		reg &= RING_FORCE_TO_NONPRIV_ADDRESS_MASK;
 867
 868		*cs++ = reg;
 869		*cs++ = 0xffffffff;
 870	}
 871	*cs++ = MI_BATCH_BUFFER_END;
 872
 873	i915_gem_object_flush_map(batch->obj);
 874	intel_gt_chipset_flush(engine->gt);
 875
 876	rq = igt_request_alloc(ctx, engine);
 877	if (IS_ERR(rq)) {
 878		err = PTR_ERR(rq);
 879		goto err_unpin;
 880	}
 881
 882	if (engine->emit_init_breadcrumb) { /* Be nice if we hang */
 883		err = engine->emit_init_breadcrumb(rq);
 884		if (err)
 885			goto err_request;
 886	}
 887
 888	i915_vma_lock(batch);
 889	err = i915_request_await_object(rq, batch->obj, false);
 890	if (err == 0)
 891		err = i915_vma_move_to_active(batch, rq, 0);
 892	i915_vma_unlock(batch);
 893	if (err)
 894		goto err_request;
 895
 896	/* Perform the writes from an unprivileged "user" batch */
 897	err = engine->emit_bb_start(rq, batch->node.start, 0, 0);
 898
 899err_request:
 900	err = request_add_sync(rq, err);
 901
 902err_unpin:
 903	i915_gem_object_unpin_map(batch->obj);
 904err_batch:
 905	i915_vma_unpin_and_release(&batch, 0);
 906	return err;
 907}
 908
 909struct regmask {
 910	i915_reg_t reg;
 911	unsigned long gen_mask;
 912};
 913
 914static bool find_reg(struct drm_i915_private *i915,
 915		     i915_reg_t reg,
 916		     const struct regmask *tbl,
 917		     unsigned long count)
 918{
 919	u32 offset = i915_mmio_reg_offset(reg);
 920
 921	while (count--) {
 922		if (INTEL_INFO(i915)->gen_mask & tbl->gen_mask &&
 923		    i915_mmio_reg_offset(tbl->reg) == offset)
 924			return true;
 925		tbl++;
 926	}
 927
 928	return false;
 929}
 930
 931static bool pardon_reg(struct drm_i915_private *i915, i915_reg_t reg)
 932{
 933	/* Alas, we must pardon some whitelists. Mistakes already made */
 934	static const struct regmask pardon[] = {
 935		{ GEN9_CTX_PREEMPT_REG, INTEL_GEN_MASK(9, 9) },
 936		{ GEN8_L3SQCREG4, INTEL_GEN_MASK(9, 9) },
 937	};
 938
 939	return find_reg(i915, reg, pardon, ARRAY_SIZE(pardon));
 940}
 941
 942static bool result_eq(struct intel_engine_cs *engine,
 943		      u32 a, u32 b, i915_reg_t reg)
 944{
 945	if (a != b && !pardon_reg(engine->i915, reg)) {
 946		pr_err("Whitelisted register 0x%4x not context saved: A=%08x, B=%08x\n",
 947		       i915_mmio_reg_offset(reg), a, b);
 948		return false;
 949	}
 950
 951	return true;
 952}
 953
 954static bool writeonly_reg(struct drm_i915_private *i915, i915_reg_t reg)
 955{
 956	/* Some registers do not seem to behave and our writes unreadable */
 957	static const struct regmask wo[] = {
 958		{ GEN9_SLICE_COMMON_ECO_CHICKEN1, INTEL_GEN_MASK(9, 9) },
 959	};
 960
 961	return find_reg(i915, reg, wo, ARRAY_SIZE(wo));
 962}
 963
 964static bool result_neq(struct intel_engine_cs *engine,
 965		       u32 a, u32 b, i915_reg_t reg)
 966{
 967	if (a == b && !writeonly_reg(engine->i915, reg)) {
 968		pr_err("Whitelist register 0x%4x:%08x was unwritable\n",
 969		       i915_mmio_reg_offset(reg), a);
 970		return false;
 971	}
 972
 973	return true;
 974}
 975
 976static int
 977check_whitelisted_registers(struct intel_engine_cs *engine,
 978			    struct i915_vma *A,
 979			    struct i915_vma *B,
 980			    bool (*fn)(struct intel_engine_cs *engine,
 981				       u32 a, u32 b,
 982				       i915_reg_t reg))
 983{
 984	u32 *a, *b;
 985	int i, err;
 986
 987	a = i915_gem_object_pin_map(A->obj, I915_MAP_WB);
 988	if (IS_ERR(a))
 989		return PTR_ERR(a);
 990
 991	b = i915_gem_object_pin_map(B->obj, I915_MAP_WB);
 992	if (IS_ERR(b)) {
 993		err = PTR_ERR(b);
 994		goto err_a;
 995	}
 996
 997	err = 0;
 998	for (i = 0; i < engine->whitelist.count; i++) {
 999		const struct i915_wa *wa = &engine->whitelist.list[i];
1000
1001		if (i915_mmio_reg_offset(wa->reg) &
1002		    RING_FORCE_TO_NONPRIV_ACCESS_RD)
1003			continue;
1004
1005		if (!fn(engine, a[i], b[i], wa->reg))
1006			err = -EINVAL;
1007	}
1008
1009	i915_gem_object_unpin_map(B->obj);
1010err_a:
1011	i915_gem_object_unpin_map(A->obj);
1012	return err;
1013}
1014
1015static int live_isolated_whitelist(void *arg)
1016{
1017	struct intel_gt *gt = arg;
1018	struct {
1019		struct i915_gem_context *ctx;
1020		struct i915_vma *scratch[2];
1021	} client[2] = {};
1022	struct intel_engine_cs *engine;
1023	enum intel_engine_id id;
1024	int i, err = 0;
1025
1026	/*
1027	 * Check that a write into a whitelist register works, but
1028	 * invisible to a second context.
1029	 */
1030
1031	if (!intel_engines_has_context_isolation(gt->i915))
1032		return 0;
1033
1034	for (i = 0; i < ARRAY_SIZE(client); i++) {
1035		struct i915_address_space *vm;
1036		struct i915_gem_context *c;
1037
1038		c = kernel_context(gt->i915);
1039		if (IS_ERR(c)) {
1040			err = PTR_ERR(c);
1041			goto err;
1042		}
1043
1044		vm = i915_gem_context_get_vm_rcu(c);
1045
1046		client[i].scratch[0] = create_scratch(vm, 1024);
1047		if (IS_ERR(client[i].scratch[0])) {
1048			err = PTR_ERR(client[i].scratch[0]);
1049			i915_vm_put(vm);
1050			kernel_context_close(c);
1051			goto err;
1052		}
1053
1054		client[i].scratch[1] = create_scratch(vm, 1024);
1055		if (IS_ERR(client[i].scratch[1])) {
1056			err = PTR_ERR(client[i].scratch[1]);
1057			i915_vma_unpin_and_release(&client[i].scratch[0], 0);
1058			i915_vm_put(vm);
1059			kernel_context_close(c);
1060			goto err;
1061		}
1062
1063		client[i].ctx = c;
1064		i915_vm_put(vm);
1065	}
1066
1067	for_each_engine(engine, gt, id) {
1068		if (!engine->kernel_context->vm)
1069			continue;
1070
1071		if (!whitelist_writable_count(engine))
1072			continue;
1073
1074		/* Read default values */
1075		err = read_whitelisted_registers(client[0].ctx, engine,
1076						 client[0].scratch[0]);
1077		if (err)
1078			goto err;
1079
1080		/* Try to overwrite registers (should only affect ctx0) */
1081		err = scrub_whitelisted_registers(client[0].ctx, engine);
1082		if (err)
1083			goto err;
1084
1085		/* Read values from ctx1, we expect these to be defaults */
1086		err = read_whitelisted_registers(client[1].ctx, engine,
1087						 client[1].scratch[0]);
1088		if (err)
1089			goto err;
1090
1091		/* Verify that both reads return the same default values */
1092		err = check_whitelisted_registers(engine,
1093						  client[0].scratch[0],
1094						  client[1].scratch[0],
1095						  result_eq);
1096		if (err)
1097			goto err;
1098
1099		/* Read back the updated values in ctx0 */
1100		err = read_whitelisted_registers(client[0].ctx, engine,
1101						 client[0].scratch[1]);
1102		if (err)
1103			goto err;
1104
1105		/* User should be granted privilege to overwhite regs */
1106		err = check_whitelisted_registers(engine,
1107						  client[0].scratch[0],
1108						  client[0].scratch[1],
1109						  result_neq);
1110		if (err)
1111			goto err;
1112	}
1113
1114err:
1115	for (i = 0; i < ARRAY_SIZE(client); i++) {
1116		if (!client[i].ctx)
1117			break;
1118
1119		i915_vma_unpin_and_release(&client[i].scratch[1], 0);
1120		i915_vma_unpin_and_release(&client[i].scratch[0], 0);
1121		kernel_context_close(client[i].ctx);
1122	}
1123
1124	if (igt_flush_test(gt->i915))
1125		err = -EIO;
1126
1127	return err;
1128}
1129
1130static bool
1131verify_wa_lists(struct i915_gem_context *ctx, struct wa_lists *lists,
1132		const char *str)
1133{
1134	struct drm_i915_private *i915 = ctx->i915;
1135	struct i915_gem_engines_iter it;
1136	struct intel_context *ce;
1137	bool ok = true;
1138
1139	ok &= wa_list_verify(&i915->uncore, &lists->gt_wa_list, str);
1140
1141	for_each_gem_engine(ce, i915_gem_context_engines(ctx), it) {
1142		enum intel_engine_id id = ce->engine->id;
1143
1144		ok &= engine_wa_list_verify(ce,
1145					    &lists->engine[id].wa_list,
1146					    str) == 0;
1147
1148		ok &= engine_wa_list_verify(ce,
1149					    &lists->engine[id].ctx_wa_list,
1150					    str) == 0;
1151	}
1152
1153	return ok;
1154}
1155
1156static int
1157live_gpu_reset_workarounds(void *arg)
1158{
1159	struct intel_gt *gt = arg;
1160	struct i915_gem_context *ctx;
1161	intel_wakeref_t wakeref;
1162	struct wa_lists lists;
1163	bool ok;
1164
1165	if (!intel_has_gpu_reset(gt))
1166		return 0;
1167
1168	ctx = kernel_context(gt->i915);
1169	if (IS_ERR(ctx))
1170		return PTR_ERR(ctx);
1171
1172	i915_gem_context_lock_engines(ctx);
1173
1174	pr_info("Verifying after GPU reset...\n");
1175
1176	igt_global_reset_lock(gt);
1177	wakeref = intel_runtime_pm_get(gt->uncore->rpm);
1178
1179	reference_lists_init(gt, &lists);
1180
1181	ok = verify_wa_lists(ctx, &lists, "before reset");
1182	if (!ok)
1183		goto out;
1184
1185	intel_gt_reset(gt, ALL_ENGINES, "live_workarounds");
1186
1187	ok = verify_wa_lists(ctx, &lists, "after reset");
1188
1189out:
1190	i915_gem_context_unlock_engines(ctx);
1191	kernel_context_close(ctx);
1192	reference_lists_fini(gt, &lists);
1193	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
1194	igt_global_reset_unlock(gt);
1195
1196	return ok ? 0 : -ESRCH;
1197}
1198
1199static int
1200live_engine_reset_workarounds(void *arg)
1201{
1202	struct intel_gt *gt = arg;
1203	struct i915_gem_engines_iter it;
1204	struct i915_gem_context *ctx;
1205	struct intel_context *ce;
1206	struct igt_spinner spin;
1207	struct i915_request *rq;
1208	intel_wakeref_t wakeref;
1209	struct wa_lists lists;
1210	int ret = 0;
1211
1212	if (!intel_has_reset_engine(gt))
1213		return 0;
1214
1215	ctx = kernel_context(gt->i915);
1216	if (IS_ERR(ctx))
1217		return PTR_ERR(ctx);
1218
1219	igt_global_reset_lock(gt);
1220	wakeref = intel_runtime_pm_get(gt->uncore->rpm);
1221
1222	reference_lists_init(gt, &lists);
1223
1224	for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
1225		struct intel_engine_cs *engine = ce->engine;
1226		bool ok;
1227
1228		pr_info("Verifying after %s reset...\n", engine->name);
1229
1230		ok = verify_wa_lists(ctx, &lists, "before reset");
1231		if (!ok) {
1232			ret = -ESRCH;
1233			goto err;
1234		}
1235
1236		intel_engine_reset(engine, "live_workarounds");
1237
1238		ok = verify_wa_lists(ctx, &lists, "after idle reset");
1239		if (!ok) {
1240			ret = -ESRCH;
1241			goto err;
1242		}
1243
1244		ret = igt_spinner_init(&spin, engine->gt);
1245		if (ret)
1246			goto err;
1247
1248		rq = igt_spinner_create_request(&spin, ce, MI_NOOP);
1249		if (IS_ERR(rq)) {
1250			ret = PTR_ERR(rq);
1251			igt_spinner_fini(&spin);
1252			goto err;
1253		}
1254
1255		ret = request_add_spin(rq, &spin);
1256		if (ret) {
1257			pr_err("Spinner failed to start\n");
1258			igt_spinner_fini(&spin);
1259			goto err;
1260		}
1261
1262		intel_engine_reset(engine, "live_workarounds");
1263
1264		igt_spinner_end(&spin);
1265		igt_spinner_fini(&spin);
1266
1267		ok = verify_wa_lists(ctx, &lists, "after busy reset");
1268		if (!ok) {
1269			ret = -ESRCH;
1270			goto err;
1271		}
1272	}
1273err:
1274	i915_gem_context_unlock_engines(ctx);
1275	reference_lists_fini(gt, &lists);
1276	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
1277	igt_global_reset_unlock(gt);
1278	kernel_context_close(ctx);
1279
1280	igt_flush_test(gt->i915);
1281
1282	return ret;
1283}
1284
1285int intel_workarounds_live_selftests(struct drm_i915_private *i915)
1286{
1287	static const struct i915_subtest tests[] = {
1288		SUBTEST(live_dirty_whitelist),
1289		SUBTEST(live_reset_whitelist),
1290		SUBTEST(live_isolated_whitelist),
1291		SUBTEST(live_gpu_reset_workarounds),
1292		SUBTEST(live_engine_reset_workarounds),
1293	};
1294
1295	if (intel_gt_is_wedged(&i915->gt))
1296		return 0;
1297
1298	return intel_gt_live_subtests(tests, &i915->gt);
1299}