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