162306a36Sopenharmony_ci// SPDX-License-Identifier: MIT 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright © 2018 Intel Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/crc32.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include "gem/i915_gem_stolen.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "i915_memcpy.h" 1162306a36Sopenharmony_ci#include "i915_selftest.h" 1262306a36Sopenharmony_ci#include "intel_gpu_commands.h" 1362306a36Sopenharmony_ci#include "selftests/igt_reset.h" 1462306a36Sopenharmony_ci#include "selftests/igt_atomic.h" 1562306a36Sopenharmony_ci#include "selftests/igt_spinner.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistatic int 1862306a36Sopenharmony_ci__igt_reset_stolen(struct intel_gt *gt, 1962306a36Sopenharmony_ci intel_engine_mask_t mask, 2062306a36Sopenharmony_ci const char *msg) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci struct i915_ggtt *ggtt = gt->ggtt; 2362306a36Sopenharmony_ci const struct resource *dsm = >->i915->dsm.stolen; 2462306a36Sopenharmony_ci resource_size_t num_pages, page; 2562306a36Sopenharmony_ci struct intel_engine_cs *engine; 2662306a36Sopenharmony_ci intel_wakeref_t wakeref; 2762306a36Sopenharmony_ci enum intel_engine_id id; 2862306a36Sopenharmony_ci struct igt_spinner spin; 2962306a36Sopenharmony_ci long max, count; 3062306a36Sopenharmony_ci void *tmp; 3162306a36Sopenharmony_ci u32 *crc; 3262306a36Sopenharmony_ci int err; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci if (!drm_mm_node_allocated(&ggtt->error_capture)) 3562306a36Sopenharmony_ci return 0; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci num_pages = resource_size(dsm) >> PAGE_SHIFT; 3862306a36Sopenharmony_ci if (!num_pages) 3962306a36Sopenharmony_ci return 0; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci crc = kmalloc_array(num_pages, sizeof(u32), GFP_KERNEL); 4262306a36Sopenharmony_ci if (!crc) 4362306a36Sopenharmony_ci return -ENOMEM; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci tmp = kmalloc(PAGE_SIZE, GFP_KERNEL); 4662306a36Sopenharmony_ci if (!tmp) { 4762306a36Sopenharmony_ci err = -ENOMEM; 4862306a36Sopenharmony_ci goto err_crc; 4962306a36Sopenharmony_ci } 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci igt_global_reset_lock(gt); 5262306a36Sopenharmony_ci wakeref = intel_runtime_pm_get(gt->uncore->rpm); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci err = igt_spinner_init(&spin, gt); 5562306a36Sopenharmony_ci if (err) 5662306a36Sopenharmony_ci goto err_lock; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci for_each_engine(engine, gt, id) { 5962306a36Sopenharmony_ci struct intel_context *ce; 6062306a36Sopenharmony_ci struct i915_request *rq; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci if (!(mask & engine->mask)) 6362306a36Sopenharmony_ci continue; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci if (!intel_engine_can_store_dword(engine)) 6662306a36Sopenharmony_ci continue; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci ce = intel_context_create(engine); 6962306a36Sopenharmony_ci if (IS_ERR(ce)) { 7062306a36Sopenharmony_ci err = PTR_ERR(ce); 7162306a36Sopenharmony_ci goto err_spin; 7262306a36Sopenharmony_ci } 7362306a36Sopenharmony_ci rq = igt_spinner_create_request(&spin, ce, MI_ARB_CHECK); 7462306a36Sopenharmony_ci intel_context_put(ce); 7562306a36Sopenharmony_ci if (IS_ERR(rq)) { 7662306a36Sopenharmony_ci err = PTR_ERR(rq); 7762306a36Sopenharmony_ci goto err_spin; 7862306a36Sopenharmony_ci } 7962306a36Sopenharmony_ci i915_request_add(rq); 8062306a36Sopenharmony_ci } 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci for (page = 0; page < num_pages; page++) { 8362306a36Sopenharmony_ci dma_addr_t dma = (dma_addr_t)dsm->start + (page << PAGE_SHIFT); 8462306a36Sopenharmony_ci void __iomem *s; 8562306a36Sopenharmony_ci void *in; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci ggtt->vm.insert_page(&ggtt->vm, dma, 8862306a36Sopenharmony_ci ggtt->error_capture.start, 8962306a36Sopenharmony_ci i915_gem_get_pat_index(gt->i915, 9062306a36Sopenharmony_ci I915_CACHE_NONE), 9162306a36Sopenharmony_ci 0); 9262306a36Sopenharmony_ci mb(); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci s = io_mapping_map_wc(&ggtt->iomap, 9562306a36Sopenharmony_ci ggtt->error_capture.start, 9662306a36Sopenharmony_ci PAGE_SIZE); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci if (!__drm_mm_interval_first(>->i915->mm.stolen, 9962306a36Sopenharmony_ci page << PAGE_SHIFT, 10062306a36Sopenharmony_ci ((page + 1) << PAGE_SHIFT) - 1)) 10162306a36Sopenharmony_ci memset_io(s, STACK_MAGIC, PAGE_SIZE); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci in = (void __force *)s; 10462306a36Sopenharmony_ci if (i915_memcpy_from_wc(tmp, in, PAGE_SIZE)) 10562306a36Sopenharmony_ci in = tmp; 10662306a36Sopenharmony_ci crc[page] = crc32_le(0, in, PAGE_SIZE); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci io_mapping_unmap(s); 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci mb(); 11162306a36Sopenharmony_ci ggtt->vm.clear_range(&ggtt->vm, ggtt->error_capture.start, PAGE_SIZE); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci if (mask == ALL_ENGINES) { 11462306a36Sopenharmony_ci intel_gt_reset(gt, mask, NULL); 11562306a36Sopenharmony_ci } else { 11662306a36Sopenharmony_ci for_each_engine(engine, gt, id) { 11762306a36Sopenharmony_ci if (mask & engine->mask) 11862306a36Sopenharmony_ci intel_engine_reset(engine, NULL); 11962306a36Sopenharmony_ci } 12062306a36Sopenharmony_ci } 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci max = -1; 12362306a36Sopenharmony_ci count = 0; 12462306a36Sopenharmony_ci for (page = 0; page < num_pages; page++) { 12562306a36Sopenharmony_ci dma_addr_t dma = (dma_addr_t)dsm->start + (page << PAGE_SHIFT); 12662306a36Sopenharmony_ci void __iomem *s; 12762306a36Sopenharmony_ci void *in; 12862306a36Sopenharmony_ci u32 x; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci ggtt->vm.insert_page(&ggtt->vm, dma, 13162306a36Sopenharmony_ci ggtt->error_capture.start, 13262306a36Sopenharmony_ci i915_gem_get_pat_index(gt->i915, 13362306a36Sopenharmony_ci I915_CACHE_NONE), 13462306a36Sopenharmony_ci 0); 13562306a36Sopenharmony_ci mb(); 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci s = io_mapping_map_wc(&ggtt->iomap, 13862306a36Sopenharmony_ci ggtt->error_capture.start, 13962306a36Sopenharmony_ci PAGE_SIZE); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci in = (void __force *)s; 14262306a36Sopenharmony_ci if (i915_memcpy_from_wc(tmp, in, PAGE_SIZE)) 14362306a36Sopenharmony_ci in = tmp; 14462306a36Sopenharmony_ci x = crc32_le(0, in, PAGE_SIZE); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci if (x != crc[page] && 14762306a36Sopenharmony_ci !__drm_mm_interval_first(>->i915->mm.stolen, 14862306a36Sopenharmony_ci page << PAGE_SHIFT, 14962306a36Sopenharmony_ci ((page + 1) << PAGE_SHIFT) - 1)) { 15062306a36Sopenharmony_ci pr_debug("unused stolen page %pa modified by GPU reset\n", 15162306a36Sopenharmony_ci &page); 15262306a36Sopenharmony_ci if (count++ == 0) 15362306a36Sopenharmony_ci igt_hexdump(in, PAGE_SIZE); 15462306a36Sopenharmony_ci max = page; 15562306a36Sopenharmony_ci } 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci io_mapping_unmap(s); 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci mb(); 16062306a36Sopenharmony_ci ggtt->vm.clear_range(&ggtt->vm, ggtt->error_capture.start, PAGE_SIZE); 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci if (count > 0) { 16362306a36Sopenharmony_ci pr_info("%s reset clobbered %ld pages of stolen, last clobber at page %ld\n", 16462306a36Sopenharmony_ci msg, count, max); 16562306a36Sopenharmony_ci } 16662306a36Sopenharmony_ci if (max >= I915_GEM_STOLEN_BIAS >> PAGE_SHIFT) { 16762306a36Sopenharmony_ci pr_err("%s reset clobbered unreserved area [above %x] of stolen; may cause severe faults\n", 16862306a36Sopenharmony_ci msg, I915_GEM_STOLEN_BIAS); 16962306a36Sopenharmony_ci err = -EINVAL; 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cierr_spin: 17362306a36Sopenharmony_ci igt_spinner_fini(&spin); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_cierr_lock: 17662306a36Sopenharmony_ci intel_runtime_pm_put(gt->uncore->rpm, wakeref); 17762306a36Sopenharmony_ci igt_global_reset_unlock(gt); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci kfree(tmp); 18062306a36Sopenharmony_cierr_crc: 18162306a36Sopenharmony_ci kfree(crc); 18262306a36Sopenharmony_ci return err; 18362306a36Sopenharmony_ci} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cistatic int igt_reset_device_stolen(void *arg) 18662306a36Sopenharmony_ci{ 18762306a36Sopenharmony_ci return __igt_reset_stolen(arg, ALL_ENGINES, "device"); 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_cistatic int igt_reset_engines_stolen(void *arg) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci struct intel_gt *gt = arg; 19362306a36Sopenharmony_ci struct intel_engine_cs *engine; 19462306a36Sopenharmony_ci enum intel_engine_id id; 19562306a36Sopenharmony_ci int err; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci if (!intel_has_reset_engine(gt)) 19862306a36Sopenharmony_ci return 0; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci for_each_engine(engine, gt, id) { 20162306a36Sopenharmony_ci err = __igt_reset_stolen(gt, engine->mask, engine->name); 20262306a36Sopenharmony_ci if (err) 20362306a36Sopenharmony_ci return err; 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci return 0; 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_cistatic int igt_global_reset(void *arg) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci struct intel_gt *gt = arg; 21262306a36Sopenharmony_ci unsigned int reset_count; 21362306a36Sopenharmony_ci intel_wakeref_t wakeref; 21462306a36Sopenharmony_ci int err = 0; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci /* Check that we can issue a global GPU reset */ 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci igt_global_reset_lock(gt); 21962306a36Sopenharmony_ci wakeref = intel_runtime_pm_get(gt->uncore->rpm); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci reset_count = i915_reset_count(>->i915->gpu_error); 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci intel_gt_reset(gt, ALL_ENGINES, NULL); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci if (i915_reset_count(>->i915->gpu_error) == reset_count) { 22662306a36Sopenharmony_ci pr_err("No GPU reset recorded!\n"); 22762306a36Sopenharmony_ci err = -EINVAL; 22862306a36Sopenharmony_ci } 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci intel_runtime_pm_put(gt->uncore->rpm, wakeref); 23162306a36Sopenharmony_ci igt_global_reset_unlock(gt); 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci if (intel_gt_is_wedged(gt)) 23462306a36Sopenharmony_ci err = -EIO; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci return err; 23762306a36Sopenharmony_ci} 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_cistatic int igt_wedged_reset(void *arg) 24062306a36Sopenharmony_ci{ 24162306a36Sopenharmony_ci struct intel_gt *gt = arg; 24262306a36Sopenharmony_ci intel_wakeref_t wakeref; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci /* Check that we can recover a wedged device with a GPU reset */ 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci igt_global_reset_lock(gt); 24762306a36Sopenharmony_ci wakeref = intel_runtime_pm_get(gt->uncore->rpm); 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci intel_gt_set_wedged(gt); 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci GEM_BUG_ON(!intel_gt_is_wedged(gt)); 25262306a36Sopenharmony_ci intel_gt_reset(gt, ALL_ENGINES, NULL); 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci intel_runtime_pm_put(gt->uncore->rpm, wakeref); 25562306a36Sopenharmony_ci igt_global_reset_unlock(gt); 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci return intel_gt_is_wedged(gt) ? -EIO : 0; 25862306a36Sopenharmony_ci} 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_cistatic int igt_atomic_reset(void *arg) 26162306a36Sopenharmony_ci{ 26262306a36Sopenharmony_ci struct intel_gt *gt = arg; 26362306a36Sopenharmony_ci const typeof(*igt_atomic_phases) *p; 26462306a36Sopenharmony_ci int err = 0; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci /* Check that the resets are usable from atomic context */ 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci intel_gt_pm_get(gt); 26962306a36Sopenharmony_ci igt_global_reset_lock(gt); 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci /* Flush any requests before we get started and check basics */ 27262306a36Sopenharmony_ci if (!igt_force_reset(gt)) 27362306a36Sopenharmony_ci goto unlock; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci for (p = igt_atomic_phases; p->name; p++) { 27662306a36Sopenharmony_ci intel_engine_mask_t awake; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci GEM_TRACE("__intel_gt_reset under %s\n", p->name); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci awake = reset_prepare(gt); 28162306a36Sopenharmony_ci p->critical_section_begin(); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci err = __intel_gt_reset(gt, ALL_ENGINES); 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci p->critical_section_end(); 28662306a36Sopenharmony_ci reset_finish(gt, awake); 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci if (err) { 28962306a36Sopenharmony_ci pr_err("__intel_gt_reset failed under %s\n", p->name); 29062306a36Sopenharmony_ci break; 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci } 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci /* As we poke around the guts, do a full reset before continuing. */ 29562306a36Sopenharmony_ci igt_force_reset(gt); 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ciunlock: 29862306a36Sopenharmony_ci igt_global_reset_unlock(gt); 29962306a36Sopenharmony_ci intel_gt_pm_put(gt); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci return err; 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_cistatic int igt_atomic_engine_reset(void *arg) 30562306a36Sopenharmony_ci{ 30662306a36Sopenharmony_ci struct intel_gt *gt = arg; 30762306a36Sopenharmony_ci const typeof(*igt_atomic_phases) *p; 30862306a36Sopenharmony_ci struct intel_engine_cs *engine; 30962306a36Sopenharmony_ci enum intel_engine_id id; 31062306a36Sopenharmony_ci int err = 0; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci /* Check that the resets are usable from atomic context */ 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci if (!intel_has_reset_engine(gt)) 31562306a36Sopenharmony_ci return 0; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci if (intel_uc_uses_guc_submission(>->uc)) 31862306a36Sopenharmony_ci return 0; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci intel_gt_pm_get(gt); 32162306a36Sopenharmony_ci igt_global_reset_lock(gt); 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci /* Flush any requests before we get started and check basics */ 32462306a36Sopenharmony_ci if (!igt_force_reset(gt)) 32562306a36Sopenharmony_ci goto out_unlock; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci for_each_engine(engine, gt, id) { 32862306a36Sopenharmony_ci struct tasklet_struct *t = &engine->sched_engine->tasklet; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci if (t->func) 33162306a36Sopenharmony_ci tasklet_disable(t); 33262306a36Sopenharmony_ci intel_engine_pm_get(engine); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci for (p = igt_atomic_phases; p->name; p++) { 33562306a36Sopenharmony_ci GEM_TRACE("intel_engine_reset(%s) under %s\n", 33662306a36Sopenharmony_ci engine->name, p->name); 33762306a36Sopenharmony_ci if (strcmp(p->name, "softirq")) 33862306a36Sopenharmony_ci local_bh_disable(); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci p->critical_section_begin(); 34162306a36Sopenharmony_ci err = __intel_engine_reset_bh(engine, NULL); 34262306a36Sopenharmony_ci p->critical_section_end(); 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci if (strcmp(p->name, "softirq")) 34562306a36Sopenharmony_ci local_bh_enable(); 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci if (err) { 34862306a36Sopenharmony_ci pr_err("intel_engine_reset(%s) failed under %s\n", 34962306a36Sopenharmony_ci engine->name, p->name); 35062306a36Sopenharmony_ci break; 35162306a36Sopenharmony_ci } 35262306a36Sopenharmony_ci } 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci intel_engine_pm_put(engine); 35562306a36Sopenharmony_ci if (t->func) { 35662306a36Sopenharmony_ci tasklet_enable(t); 35762306a36Sopenharmony_ci tasklet_hi_schedule(t); 35862306a36Sopenharmony_ci } 35962306a36Sopenharmony_ci if (err) 36062306a36Sopenharmony_ci break; 36162306a36Sopenharmony_ci } 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci /* As we poke around the guts, do a full reset before continuing. */ 36462306a36Sopenharmony_ci igt_force_reset(gt); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ciout_unlock: 36762306a36Sopenharmony_ci igt_global_reset_unlock(gt); 36862306a36Sopenharmony_ci intel_gt_pm_put(gt); 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci return err; 37162306a36Sopenharmony_ci} 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ciint intel_reset_live_selftests(struct drm_i915_private *i915) 37462306a36Sopenharmony_ci{ 37562306a36Sopenharmony_ci static const struct i915_subtest tests[] = { 37662306a36Sopenharmony_ci SUBTEST(igt_global_reset), /* attempt to recover GPU first */ 37762306a36Sopenharmony_ci SUBTEST(igt_reset_device_stolen), 37862306a36Sopenharmony_ci SUBTEST(igt_reset_engines_stolen), 37962306a36Sopenharmony_ci SUBTEST(igt_wedged_reset), 38062306a36Sopenharmony_ci SUBTEST(igt_atomic_reset), 38162306a36Sopenharmony_ci SUBTEST(igt_atomic_engine_reset), 38262306a36Sopenharmony_ci }; 38362306a36Sopenharmony_ci struct intel_gt *gt = to_gt(i915); 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci if (!intel_has_gpu_reset(gt)) 38662306a36Sopenharmony_ci return 0; 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci if (intel_gt_is_wedged(gt)) 38962306a36Sopenharmony_ci return -EIO; /* we're long past hope of a successful reset */ 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci return intel_gt_live_subtests(tests, gt); 39262306a36Sopenharmony_ci} 393