selftest_workarounds.c 29 KB

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