@@ -286,11 +286,126 @@ static int intel_guc_steal_guc_ids(void *arg)
286
286
return ret ;
287
287
}
288
288
289
+ /*
290
+ * Send a context schedule H2G message with an invalid context id.
291
+ * This should generate a GUC_RESULT_INVALID_CONTEXT response.
292
+ */
293
+ static int bad_h2g (struct intel_guc * guc )
294
+ {
295
+ u32 action [] = {
296
+ INTEL_GUC_ACTION_SCHED_CONTEXT ,
297
+ 0x12345678 ,
298
+ };
299
+
300
+ return intel_guc_send_nb (guc , action , ARRAY_SIZE (action ), 0 );
301
+ }
302
+
303
+ /*
304
+ * Set a spinner running to make sure the system is alive and active,
305
+ * then send a bad but asynchronous H2G command and wait to see if an
306
+ * error response is returned. If no response is received or if the
307
+ * spinner dies then the test will fail.
308
+ */
309
+ #define FAST_RESPONSE_TIMEOUT_MS 1000
310
+ static int intel_guc_fast_request (void * arg )
311
+ {
312
+ struct intel_gt * gt = arg ;
313
+ struct intel_context * ce ;
314
+ struct igt_spinner spin ;
315
+ struct i915_request * rq ;
316
+ intel_wakeref_t wakeref ;
317
+ struct intel_engine_cs * engine = intel_selftest_find_any_engine (gt );
318
+ bool spinning = false;
319
+ int ret = 0 ;
320
+
321
+ if (!engine )
322
+ return 0 ;
323
+
324
+ wakeref = intel_runtime_pm_get (gt -> uncore -> rpm );
325
+
326
+ ce = intel_context_create (engine );
327
+ if (IS_ERR (ce )) {
328
+ ret = PTR_ERR (ce );
329
+ gt_err (gt , "Failed to create spinner request: %pe\n" , ce );
330
+ goto err_pm ;
331
+ }
332
+
333
+ ret = igt_spinner_init (& spin , engine -> gt );
334
+ if (ret ) {
335
+ gt_err (gt , "Failed to create spinner: %pe\n" , ERR_PTR (ret ));
336
+ goto err_pm ;
337
+ }
338
+ spinning = true;
339
+
340
+ rq = igt_spinner_create_request (& spin , ce , MI_ARB_CHECK );
341
+ intel_context_put (ce );
342
+ if (IS_ERR (rq )) {
343
+ ret = PTR_ERR (rq );
344
+ gt_err (gt , "Failed to create spinner request: %pe\n" , rq );
345
+ goto err_spin ;
346
+ }
347
+
348
+ ret = request_add_spin (rq , & spin );
349
+ if (ret ) {
350
+ gt_err (gt , "Failed to add Spinner request: %pe\n" , ERR_PTR (ret ));
351
+ goto err_rq ;
352
+ }
353
+
354
+ gt -> uc .guc .fast_response_selftest = 1 ;
355
+
356
+ ret = bad_h2g (& gt -> uc .guc );
357
+ if (ret ) {
358
+ gt_err (gt , "Failed to send H2G: %pe\n" , ERR_PTR (ret ));
359
+ goto err_rq ;
360
+ }
361
+
362
+ ret = wait_for (gt -> uc .guc .fast_response_selftest != 1 || i915_request_completed (rq ),
363
+ FAST_RESPONSE_TIMEOUT_MS );
364
+ if (ret ) {
365
+ gt_err (gt , "Request wait failed: %pe\n" , ERR_PTR (ret ));
366
+ goto err_rq ;
367
+ }
368
+
369
+ if (i915_request_completed (rq )) {
370
+ gt_err (gt , "Spinner died waiting for fast request error!\n" );
371
+ ret = - EIO ;
372
+ goto err_rq ;
373
+ }
374
+
375
+ if (gt -> uc .guc .fast_response_selftest != 2 ) {
376
+ gt_err (gt , "Unexpected fast response count: %d\n" ,
377
+ gt -> uc .guc .fast_response_selftest );
378
+ goto err_rq ;
379
+ }
380
+
381
+ igt_spinner_end (& spin );
382
+ spinning = false;
383
+
384
+ ret = intel_selftest_wait_for_rq (rq );
385
+ if (ret ) {
386
+ gt_err (gt , "Request failed to complete: %pe\n" , ERR_PTR (ret ));
387
+ goto err_rq ;
388
+ }
389
+
390
+ err_rq :
391
+ i915_request_put (rq );
392
+
393
+ err_spin :
394
+ if (spinning )
395
+ igt_spinner_end (& spin );
396
+ igt_spinner_fini (& spin );
397
+
398
+ err_pm :
399
+ intel_runtime_pm_put (gt -> uncore -> rpm , wakeref );
400
+ return ret ;
401
+ }
402
+
289
403
int intel_guc_live_selftests (struct drm_i915_private * i915 )
290
404
{
291
405
static const struct i915_subtest tests [] = {
292
406
SUBTEST (intel_guc_scrub_ctbs ),
293
407
SUBTEST (intel_guc_steal_guc_ids ),
408
+ SUBTEST (intel_guc_fast_request ),
294
409
};
295
410
struct intel_gt * gt = to_gt (i915 );
296
411
0 commit comments