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