18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 58c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 68c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation 78c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 88c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 98c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the next 128c2ecf20Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 138c2ecf20Sopenharmony_ci * Software. 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 168c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 178c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 188c2ecf20Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 198c2ecf20Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 208c2ecf20Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 218c2ecf20Sopenharmony_ci * SOFTWARE. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * Authors: 248c2ecf20Sopenharmony_ci * Eddie Dong <eddie.dong@intel.com> 258c2ecf20Sopenharmony_ci * Kevin Tian <kevin.tian@intel.com> 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * Contributors: 288c2ecf20Sopenharmony_ci * Ping Gao <ping.a.gao@intel.com> 298c2ecf20Sopenharmony_ci * Zhi Wang <zhi.a.wang@intel.com> 308c2ecf20Sopenharmony_ci * Bing Niu <bing.niu@intel.com> 318c2ecf20Sopenharmony_ci * 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#include "i915_drv.h" 358c2ecf20Sopenharmony_ci#include "gvt.h" 368c2ecf20Sopenharmony_ci#include "i915_pvinfo.h" 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_civoid populate_pvinfo_page(struct intel_vgpu *vgpu) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci struct drm_i915_private *i915 = vgpu->gvt->gt->i915; 418c2ecf20Sopenharmony_ci /* setup the ballooning information */ 428c2ecf20Sopenharmony_ci vgpu_vreg64_t(vgpu, vgtif_reg(magic)) = VGT_MAGIC; 438c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(version_major)) = 1; 448c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(version_minor)) = 0; 458c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(display_ready)) = 0; 468c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(vgt_id)) = vgpu->id; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(vgt_caps)) = VGT_CAPS_FULL_PPGTT; 498c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(vgt_caps)) |= VGT_CAPS_HWSP_EMULATION; 508c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(vgt_caps)) |= VGT_CAPS_HUGE_GTT; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(avail_rs.mappable_gmadr.base)) = 538c2ecf20Sopenharmony_ci vgpu_aperture_gmadr_base(vgpu); 548c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(avail_rs.mappable_gmadr.size)) = 558c2ecf20Sopenharmony_ci vgpu_aperture_sz(vgpu); 568c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(avail_rs.nonmappable_gmadr.base)) = 578c2ecf20Sopenharmony_ci vgpu_hidden_gmadr_base(vgpu); 588c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(avail_rs.nonmappable_gmadr.size)) = 598c2ecf20Sopenharmony_ci vgpu_hidden_sz(vgpu); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(avail_rs.fence_num)) = vgpu_fence_sz(vgpu); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(cursor_x_hot)) = UINT_MAX; 648c2ecf20Sopenharmony_ci vgpu_vreg_t(vgpu, vgtif_reg(cursor_y_hot)) = UINT_MAX; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci gvt_dbg_core("Populate PVINFO PAGE for vGPU %d\n", vgpu->id); 678c2ecf20Sopenharmony_ci gvt_dbg_core("aperture base [GMADR] 0x%llx size 0x%llx\n", 688c2ecf20Sopenharmony_ci vgpu_aperture_gmadr_base(vgpu), vgpu_aperture_sz(vgpu)); 698c2ecf20Sopenharmony_ci gvt_dbg_core("hidden base [GMADR] 0x%llx size=0x%llx\n", 708c2ecf20Sopenharmony_ci vgpu_hidden_gmadr_base(vgpu), vgpu_hidden_sz(vgpu)); 718c2ecf20Sopenharmony_ci gvt_dbg_core("fence size %d\n", vgpu_fence_sz(vgpu)); 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci drm_WARN_ON(&i915->drm, sizeof(struct vgt_if) != VGT_PVINFO_SIZE); 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci#define VGPU_MAX_WEIGHT 16 778c2ecf20Sopenharmony_ci#define VGPU_WEIGHT(vgpu_num) \ 788c2ecf20Sopenharmony_ci (VGPU_MAX_WEIGHT / (vgpu_num)) 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistatic struct { 818c2ecf20Sopenharmony_ci unsigned int low_mm; 828c2ecf20Sopenharmony_ci unsigned int high_mm; 838c2ecf20Sopenharmony_ci unsigned int fence; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci /* A vGPU with a weight of 8 will get twice as much GPU as a vGPU 868c2ecf20Sopenharmony_ci * with a weight of 4 on a contended host, different vGPU type has 878c2ecf20Sopenharmony_ci * different weight set. Legal weights range from 1 to 16. 888c2ecf20Sopenharmony_ci */ 898c2ecf20Sopenharmony_ci unsigned int weight; 908c2ecf20Sopenharmony_ci enum intel_vgpu_edid edid; 918c2ecf20Sopenharmony_ci char *name; 928c2ecf20Sopenharmony_ci} vgpu_types[] = { 938c2ecf20Sopenharmony_ci/* Fixed vGPU type table */ 948c2ecf20Sopenharmony_ci { MB_TO_BYTES(64), MB_TO_BYTES(384), 4, VGPU_WEIGHT(8), GVT_EDID_1024_768, "8" }, 958c2ecf20Sopenharmony_ci { MB_TO_BYTES(128), MB_TO_BYTES(512), 4, VGPU_WEIGHT(4), GVT_EDID_1920_1200, "4" }, 968c2ecf20Sopenharmony_ci { MB_TO_BYTES(256), MB_TO_BYTES(1024), 4, VGPU_WEIGHT(2), GVT_EDID_1920_1200, "2" }, 978c2ecf20Sopenharmony_ci { MB_TO_BYTES(512), MB_TO_BYTES(2048), 4, VGPU_WEIGHT(1), GVT_EDID_1920_1200, "1" }, 988c2ecf20Sopenharmony_ci}; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci/** 1018c2ecf20Sopenharmony_ci * intel_gvt_init_vgpu_types - initialize vGPU type list 1028c2ecf20Sopenharmony_ci * @gvt : GVT device 1038c2ecf20Sopenharmony_ci * 1048c2ecf20Sopenharmony_ci * Initialize vGPU type list based on available resource. 1058c2ecf20Sopenharmony_ci * 1068c2ecf20Sopenharmony_ci */ 1078c2ecf20Sopenharmony_ciint intel_gvt_init_vgpu_types(struct intel_gvt *gvt) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci unsigned int num_types; 1108c2ecf20Sopenharmony_ci unsigned int i, low_avail, high_avail; 1118c2ecf20Sopenharmony_ci unsigned int min_low; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci /* vGPU type name is defined as GVTg_Vx_y which contains 1148c2ecf20Sopenharmony_ci * physical GPU generation type (e.g V4 as BDW server, V5 as 1158c2ecf20Sopenharmony_ci * SKL server). 1168c2ecf20Sopenharmony_ci * 1178c2ecf20Sopenharmony_ci * Depend on physical SKU resource, might see vGPU types like 1188c2ecf20Sopenharmony_ci * GVTg_V4_8, GVTg_V4_4, GVTg_V4_2, etc. We can create 1198c2ecf20Sopenharmony_ci * different types of vGPU on same physical GPU depending on 1208c2ecf20Sopenharmony_ci * available resource. Each vGPU type will have "avail_instance" 1218c2ecf20Sopenharmony_ci * to indicate how many vGPU instance can be created for this 1228c2ecf20Sopenharmony_ci * type. 1238c2ecf20Sopenharmony_ci * 1248c2ecf20Sopenharmony_ci */ 1258c2ecf20Sopenharmony_ci low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE; 1268c2ecf20Sopenharmony_ci high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE; 1278c2ecf20Sopenharmony_ci num_types = ARRAY_SIZE(vgpu_types); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type), 1308c2ecf20Sopenharmony_ci GFP_KERNEL); 1318c2ecf20Sopenharmony_ci if (!gvt->types) 1328c2ecf20Sopenharmony_ci return -ENOMEM; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci min_low = MB_TO_BYTES(32); 1358c2ecf20Sopenharmony_ci for (i = 0; i < num_types; ++i) { 1368c2ecf20Sopenharmony_ci if (low_avail / vgpu_types[i].low_mm == 0) 1378c2ecf20Sopenharmony_ci break; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci gvt->types[i].low_gm_size = vgpu_types[i].low_mm; 1408c2ecf20Sopenharmony_ci gvt->types[i].high_gm_size = vgpu_types[i].high_mm; 1418c2ecf20Sopenharmony_ci gvt->types[i].fence = vgpu_types[i].fence; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci if (vgpu_types[i].weight < 1 || 1448c2ecf20Sopenharmony_ci vgpu_types[i].weight > VGPU_MAX_WEIGHT) 1458c2ecf20Sopenharmony_ci return -EINVAL; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci gvt->types[i].weight = vgpu_types[i].weight; 1488c2ecf20Sopenharmony_ci gvt->types[i].resolution = vgpu_types[i].edid; 1498c2ecf20Sopenharmony_ci gvt->types[i].avail_instance = min(low_avail / vgpu_types[i].low_mm, 1508c2ecf20Sopenharmony_ci high_avail / vgpu_types[i].high_mm); 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci if (IS_GEN(gvt->gt->i915, 8)) 1538c2ecf20Sopenharmony_ci sprintf(gvt->types[i].name, "GVTg_V4_%s", 1548c2ecf20Sopenharmony_ci vgpu_types[i].name); 1558c2ecf20Sopenharmony_ci else if (IS_GEN(gvt->gt->i915, 9)) 1568c2ecf20Sopenharmony_ci sprintf(gvt->types[i].name, "GVTg_V5_%s", 1578c2ecf20Sopenharmony_ci vgpu_types[i].name); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci gvt_dbg_core("type[%d]: %s avail %u low %u high %u fence %u weight %u res %s\n", 1608c2ecf20Sopenharmony_ci i, gvt->types[i].name, 1618c2ecf20Sopenharmony_ci gvt->types[i].avail_instance, 1628c2ecf20Sopenharmony_ci gvt->types[i].low_gm_size, 1638c2ecf20Sopenharmony_ci gvt->types[i].high_gm_size, gvt->types[i].fence, 1648c2ecf20Sopenharmony_ci gvt->types[i].weight, 1658c2ecf20Sopenharmony_ci vgpu_edid_str(gvt->types[i].resolution)); 1668c2ecf20Sopenharmony_ci } 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci gvt->num_types = i; 1698c2ecf20Sopenharmony_ci return 0; 1708c2ecf20Sopenharmony_ci} 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_civoid intel_gvt_clean_vgpu_types(struct intel_gvt *gvt) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci kfree(gvt->types); 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic void intel_gvt_update_vgpu_types(struct intel_gvt *gvt) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci int i; 1808c2ecf20Sopenharmony_ci unsigned int low_gm_avail, high_gm_avail, fence_avail; 1818c2ecf20Sopenharmony_ci unsigned int low_gm_min, high_gm_min, fence_min; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci /* Need to depend on maxium hw resource size but keep on 1848c2ecf20Sopenharmony_ci * static config for now. 1858c2ecf20Sopenharmony_ci */ 1868c2ecf20Sopenharmony_ci low_gm_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE - 1878c2ecf20Sopenharmony_ci gvt->gm.vgpu_allocated_low_gm_size; 1888c2ecf20Sopenharmony_ci high_gm_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE - 1898c2ecf20Sopenharmony_ci gvt->gm.vgpu_allocated_high_gm_size; 1908c2ecf20Sopenharmony_ci fence_avail = gvt_fence_sz(gvt) - HOST_FENCE - 1918c2ecf20Sopenharmony_ci gvt->fence.vgpu_allocated_fence_num; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci for (i = 0; i < gvt->num_types; i++) { 1948c2ecf20Sopenharmony_ci low_gm_min = low_gm_avail / gvt->types[i].low_gm_size; 1958c2ecf20Sopenharmony_ci high_gm_min = high_gm_avail / gvt->types[i].high_gm_size; 1968c2ecf20Sopenharmony_ci fence_min = fence_avail / gvt->types[i].fence; 1978c2ecf20Sopenharmony_ci gvt->types[i].avail_instance = min(min(low_gm_min, high_gm_min), 1988c2ecf20Sopenharmony_ci fence_min); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci gvt_dbg_core("update type[%d]: %s avail %u low %u high %u fence %u\n", 2018c2ecf20Sopenharmony_ci i, gvt->types[i].name, 2028c2ecf20Sopenharmony_ci gvt->types[i].avail_instance, gvt->types[i].low_gm_size, 2038c2ecf20Sopenharmony_ci gvt->types[i].high_gm_size, gvt->types[i].fence); 2048c2ecf20Sopenharmony_ci } 2058c2ecf20Sopenharmony_ci} 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci/** 2088c2ecf20Sopenharmony_ci * intel_gvt_active_vgpu - activate a virtual GPU 2098c2ecf20Sopenharmony_ci * @vgpu: virtual GPU 2108c2ecf20Sopenharmony_ci * 2118c2ecf20Sopenharmony_ci * This function is called when user wants to activate a virtual GPU. 2128c2ecf20Sopenharmony_ci * 2138c2ecf20Sopenharmony_ci */ 2148c2ecf20Sopenharmony_civoid intel_gvt_activate_vgpu(struct intel_vgpu *vgpu) 2158c2ecf20Sopenharmony_ci{ 2168c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 2178c2ecf20Sopenharmony_ci vgpu->active = true; 2188c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 2198c2ecf20Sopenharmony_ci} 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci/** 2228c2ecf20Sopenharmony_ci * intel_gvt_deactive_vgpu - deactivate a virtual GPU 2238c2ecf20Sopenharmony_ci * @vgpu: virtual GPU 2248c2ecf20Sopenharmony_ci * 2258c2ecf20Sopenharmony_ci * This function is called when user wants to deactivate a virtual GPU. 2268c2ecf20Sopenharmony_ci * The virtual GPU will be stopped. 2278c2ecf20Sopenharmony_ci * 2288c2ecf20Sopenharmony_ci */ 2298c2ecf20Sopenharmony_civoid intel_gvt_deactivate_vgpu(struct intel_vgpu *vgpu) 2308c2ecf20Sopenharmony_ci{ 2318c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci vgpu->active = false; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci if (atomic_read(&vgpu->submission.running_workload_num)) { 2368c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 2378c2ecf20Sopenharmony_ci intel_gvt_wait_vgpu_idle(vgpu); 2388c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci intel_vgpu_stop_schedule(vgpu); 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 2448c2ecf20Sopenharmony_ci} 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci/** 2478c2ecf20Sopenharmony_ci * intel_gvt_release_vgpu - release a virtual GPU 2488c2ecf20Sopenharmony_ci * @vgpu: virtual GPU 2498c2ecf20Sopenharmony_ci * 2508c2ecf20Sopenharmony_ci * This function is called when user wants to release a virtual GPU. 2518c2ecf20Sopenharmony_ci * The virtual GPU will be stopped and all runtime information will be 2528c2ecf20Sopenharmony_ci * destroyed. 2538c2ecf20Sopenharmony_ci * 2548c2ecf20Sopenharmony_ci */ 2558c2ecf20Sopenharmony_civoid intel_gvt_release_vgpu(struct intel_vgpu *vgpu) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci intel_gvt_deactivate_vgpu(vgpu); 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 2608c2ecf20Sopenharmony_ci vgpu->d3_entered = false; 2618c2ecf20Sopenharmony_ci intel_vgpu_clean_workloads(vgpu, ALL_ENGINES); 2628c2ecf20Sopenharmony_ci intel_vgpu_dmabuf_cleanup(vgpu); 2638c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 2648c2ecf20Sopenharmony_ci} 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci/** 2678c2ecf20Sopenharmony_ci * intel_gvt_destroy_vgpu - destroy a virtual GPU 2688c2ecf20Sopenharmony_ci * @vgpu: virtual GPU 2698c2ecf20Sopenharmony_ci * 2708c2ecf20Sopenharmony_ci * This function is called when user wants to destroy a virtual GPU. 2718c2ecf20Sopenharmony_ci * 2728c2ecf20Sopenharmony_ci */ 2738c2ecf20Sopenharmony_civoid intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu) 2748c2ecf20Sopenharmony_ci{ 2758c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 2768c2ecf20Sopenharmony_ci struct drm_i915_private *i915 = gvt->gt->i915; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci drm_WARN(&i915->drm, vgpu->active, "vGPU is still active!\n"); 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci /* 2818c2ecf20Sopenharmony_ci * remove idr first so later clean can judge if need to stop 2828c2ecf20Sopenharmony_ci * service if no active vgpu. 2838c2ecf20Sopenharmony_ci */ 2848c2ecf20Sopenharmony_ci mutex_lock(&gvt->lock); 2858c2ecf20Sopenharmony_ci idr_remove(&gvt->vgpu_idr, vgpu->id); 2868c2ecf20Sopenharmony_ci mutex_unlock(&gvt->lock); 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 2898c2ecf20Sopenharmony_ci intel_gvt_debugfs_remove_vgpu(vgpu); 2908c2ecf20Sopenharmony_ci intel_vgpu_clean_sched_policy(vgpu); 2918c2ecf20Sopenharmony_ci intel_vgpu_clean_submission(vgpu); 2928c2ecf20Sopenharmony_ci intel_vgpu_clean_display(vgpu); 2938c2ecf20Sopenharmony_ci intel_vgpu_clean_opregion(vgpu); 2948c2ecf20Sopenharmony_ci intel_vgpu_reset_ggtt(vgpu, true); 2958c2ecf20Sopenharmony_ci intel_vgpu_clean_gtt(vgpu); 2968c2ecf20Sopenharmony_ci intel_gvt_hypervisor_detach_vgpu(vgpu); 2978c2ecf20Sopenharmony_ci intel_vgpu_free_resource(vgpu); 2988c2ecf20Sopenharmony_ci intel_vgpu_clean_mmio(vgpu); 2998c2ecf20Sopenharmony_ci intel_vgpu_dmabuf_cleanup(vgpu); 3008c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci mutex_lock(&gvt->lock); 3038c2ecf20Sopenharmony_ci if (idr_is_empty(&gvt->vgpu_idr)) 3048c2ecf20Sopenharmony_ci intel_gvt_clean_irq(gvt); 3058c2ecf20Sopenharmony_ci intel_gvt_update_vgpu_types(gvt); 3068c2ecf20Sopenharmony_ci mutex_unlock(&gvt->lock); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci vfree(vgpu); 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci#define IDLE_VGPU_IDR 0 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci/** 3148c2ecf20Sopenharmony_ci * intel_gvt_create_idle_vgpu - create an idle virtual GPU 3158c2ecf20Sopenharmony_ci * @gvt: GVT device 3168c2ecf20Sopenharmony_ci * 3178c2ecf20Sopenharmony_ci * This function is called when user wants to create an idle virtual GPU. 3188c2ecf20Sopenharmony_ci * 3198c2ecf20Sopenharmony_ci * Returns: 3208c2ecf20Sopenharmony_ci * pointer to intel_vgpu, error pointer if failed. 3218c2ecf20Sopenharmony_ci */ 3228c2ecf20Sopenharmony_cistruct intel_vgpu *intel_gvt_create_idle_vgpu(struct intel_gvt *gvt) 3238c2ecf20Sopenharmony_ci{ 3248c2ecf20Sopenharmony_ci struct intel_vgpu *vgpu; 3258c2ecf20Sopenharmony_ci enum intel_engine_id i; 3268c2ecf20Sopenharmony_ci int ret; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci vgpu = vzalloc(sizeof(*vgpu)); 3298c2ecf20Sopenharmony_ci if (!vgpu) 3308c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci vgpu->id = IDLE_VGPU_IDR; 3338c2ecf20Sopenharmony_ci vgpu->gvt = gvt; 3348c2ecf20Sopenharmony_ci mutex_init(&vgpu->vgpu_lock); 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci for (i = 0; i < I915_NUM_ENGINES; i++) 3378c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&vgpu->submission.workload_q_head[i]); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci ret = intel_vgpu_init_sched_policy(vgpu); 3408c2ecf20Sopenharmony_ci if (ret) 3418c2ecf20Sopenharmony_ci goto out_free_vgpu; 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci vgpu->active = false; 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci return vgpu; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ciout_free_vgpu: 3488c2ecf20Sopenharmony_ci vfree(vgpu); 3498c2ecf20Sopenharmony_ci return ERR_PTR(ret); 3508c2ecf20Sopenharmony_ci} 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci/** 3538c2ecf20Sopenharmony_ci * intel_gvt_destroy_vgpu - destroy an idle virtual GPU 3548c2ecf20Sopenharmony_ci * @vgpu: virtual GPU 3558c2ecf20Sopenharmony_ci * 3568c2ecf20Sopenharmony_ci * This function is called when user wants to destroy an idle virtual GPU. 3578c2ecf20Sopenharmony_ci * 3588c2ecf20Sopenharmony_ci */ 3598c2ecf20Sopenharmony_civoid intel_gvt_destroy_idle_vgpu(struct intel_vgpu *vgpu) 3608c2ecf20Sopenharmony_ci{ 3618c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 3628c2ecf20Sopenharmony_ci intel_vgpu_clean_sched_policy(vgpu); 3638c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci vfree(vgpu); 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_cistatic struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, 3698c2ecf20Sopenharmony_ci struct intel_vgpu_creation_params *param) 3708c2ecf20Sopenharmony_ci{ 3718c2ecf20Sopenharmony_ci struct drm_i915_private *dev_priv = gvt->gt->i915; 3728c2ecf20Sopenharmony_ci struct intel_vgpu *vgpu; 3738c2ecf20Sopenharmony_ci int ret; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci gvt_dbg_core("handle %llu low %llu MB high %llu MB fence %llu\n", 3768c2ecf20Sopenharmony_ci param->handle, param->low_gm_sz, param->high_gm_sz, 3778c2ecf20Sopenharmony_ci param->fence_sz); 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci vgpu = vzalloc(sizeof(*vgpu)); 3808c2ecf20Sopenharmony_ci if (!vgpu) 3818c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci ret = idr_alloc(&gvt->vgpu_idr, vgpu, IDLE_VGPU_IDR + 1, GVT_MAX_VGPU, 3848c2ecf20Sopenharmony_ci GFP_KERNEL); 3858c2ecf20Sopenharmony_ci if (ret < 0) 3868c2ecf20Sopenharmony_ci goto out_free_vgpu; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci vgpu->id = ret; 3898c2ecf20Sopenharmony_ci vgpu->handle = param->handle; 3908c2ecf20Sopenharmony_ci vgpu->gvt = gvt; 3918c2ecf20Sopenharmony_ci vgpu->sched_ctl.weight = param->weight; 3928c2ecf20Sopenharmony_ci mutex_init(&vgpu->vgpu_lock); 3938c2ecf20Sopenharmony_ci mutex_init(&vgpu->dmabuf_lock); 3948c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head); 3958c2ecf20Sopenharmony_ci INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL); 3968c2ecf20Sopenharmony_ci idr_init(&vgpu->object_idr); 3978c2ecf20Sopenharmony_ci intel_vgpu_init_cfg_space(vgpu, param->primary); 3988c2ecf20Sopenharmony_ci vgpu->d3_entered = false; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci ret = intel_vgpu_init_mmio(vgpu); 4018c2ecf20Sopenharmony_ci if (ret) 4028c2ecf20Sopenharmony_ci goto out_clean_idr; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci ret = intel_vgpu_alloc_resource(vgpu, param); 4058c2ecf20Sopenharmony_ci if (ret) 4068c2ecf20Sopenharmony_ci goto out_clean_vgpu_mmio; 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci populate_pvinfo_page(vgpu); 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci ret = intel_gvt_hypervisor_attach_vgpu(vgpu); 4118c2ecf20Sopenharmony_ci if (ret) 4128c2ecf20Sopenharmony_ci goto out_clean_vgpu_resource; 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci ret = intel_vgpu_init_gtt(vgpu); 4158c2ecf20Sopenharmony_ci if (ret) 4168c2ecf20Sopenharmony_ci goto out_detach_hypervisor_vgpu; 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci ret = intel_vgpu_init_opregion(vgpu); 4198c2ecf20Sopenharmony_ci if (ret) 4208c2ecf20Sopenharmony_ci goto out_clean_gtt; 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci ret = intel_vgpu_init_display(vgpu, param->resolution); 4238c2ecf20Sopenharmony_ci if (ret) 4248c2ecf20Sopenharmony_ci goto out_clean_opregion; 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci ret = intel_vgpu_setup_submission(vgpu); 4278c2ecf20Sopenharmony_ci if (ret) 4288c2ecf20Sopenharmony_ci goto out_clean_display; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci ret = intel_vgpu_init_sched_policy(vgpu); 4318c2ecf20Sopenharmony_ci if (ret) 4328c2ecf20Sopenharmony_ci goto out_clean_submission; 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci intel_gvt_debugfs_add_vgpu(vgpu); 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci ret = intel_gvt_hypervisor_set_opregion(vgpu); 4378c2ecf20Sopenharmony_ci if (ret) 4388c2ecf20Sopenharmony_ci goto out_clean_sched_policy; 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci if (IS_BROADWELL(dev_priv) || IS_BROXTON(dev_priv)) 4418c2ecf20Sopenharmony_ci ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B); 4428c2ecf20Sopenharmony_ci else 4438c2ecf20Sopenharmony_ci ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D); 4448c2ecf20Sopenharmony_ci if (ret) 4458c2ecf20Sopenharmony_ci goto out_clean_sched_policy; 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci return vgpu; 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_ciout_clean_sched_policy: 4508c2ecf20Sopenharmony_ci intel_vgpu_clean_sched_policy(vgpu); 4518c2ecf20Sopenharmony_ciout_clean_submission: 4528c2ecf20Sopenharmony_ci intel_vgpu_clean_submission(vgpu); 4538c2ecf20Sopenharmony_ciout_clean_display: 4548c2ecf20Sopenharmony_ci intel_vgpu_clean_display(vgpu); 4558c2ecf20Sopenharmony_ciout_clean_opregion: 4568c2ecf20Sopenharmony_ci intel_vgpu_clean_opregion(vgpu); 4578c2ecf20Sopenharmony_ciout_clean_gtt: 4588c2ecf20Sopenharmony_ci intel_vgpu_clean_gtt(vgpu); 4598c2ecf20Sopenharmony_ciout_detach_hypervisor_vgpu: 4608c2ecf20Sopenharmony_ci intel_gvt_hypervisor_detach_vgpu(vgpu); 4618c2ecf20Sopenharmony_ciout_clean_vgpu_resource: 4628c2ecf20Sopenharmony_ci intel_vgpu_free_resource(vgpu); 4638c2ecf20Sopenharmony_ciout_clean_vgpu_mmio: 4648c2ecf20Sopenharmony_ci intel_vgpu_clean_mmio(vgpu); 4658c2ecf20Sopenharmony_ciout_clean_idr: 4668c2ecf20Sopenharmony_ci idr_remove(&gvt->vgpu_idr, vgpu->id); 4678c2ecf20Sopenharmony_ciout_free_vgpu: 4688c2ecf20Sopenharmony_ci vfree(vgpu); 4698c2ecf20Sopenharmony_ci return ERR_PTR(ret); 4708c2ecf20Sopenharmony_ci} 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci/** 4738c2ecf20Sopenharmony_ci * intel_gvt_create_vgpu - create a virtual GPU 4748c2ecf20Sopenharmony_ci * @gvt: GVT device 4758c2ecf20Sopenharmony_ci * @type: type of the vGPU to create 4768c2ecf20Sopenharmony_ci * 4778c2ecf20Sopenharmony_ci * This function is called when user wants to create a virtual GPU. 4788c2ecf20Sopenharmony_ci * 4798c2ecf20Sopenharmony_ci * Returns: 4808c2ecf20Sopenharmony_ci * pointer to intel_vgpu, error pointer if failed. 4818c2ecf20Sopenharmony_ci */ 4828c2ecf20Sopenharmony_cistruct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt, 4838c2ecf20Sopenharmony_ci struct intel_vgpu_type *type) 4848c2ecf20Sopenharmony_ci{ 4858c2ecf20Sopenharmony_ci struct intel_vgpu_creation_params param; 4868c2ecf20Sopenharmony_ci struct intel_vgpu *vgpu; 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci param.handle = 0; 4898c2ecf20Sopenharmony_ci param.primary = 1; 4908c2ecf20Sopenharmony_ci param.low_gm_sz = type->low_gm_size; 4918c2ecf20Sopenharmony_ci param.high_gm_sz = type->high_gm_size; 4928c2ecf20Sopenharmony_ci param.fence_sz = type->fence; 4938c2ecf20Sopenharmony_ci param.weight = type->weight; 4948c2ecf20Sopenharmony_ci param.resolution = type->resolution; 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci /* XXX current param based on MB */ 4978c2ecf20Sopenharmony_ci param.low_gm_sz = BYTES_TO_MB(param.low_gm_sz); 4988c2ecf20Sopenharmony_ci param.high_gm_sz = BYTES_TO_MB(param.high_gm_sz); 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_ci mutex_lock(&gvt->lock); 5018c2ecf20Sopenharmony_ci vgpu = __intel_gvt_create_vgpu(gvt, ¶m); 5028c2ecf20Sopenharmony_ci if (!IS_ERR(vgpu)) 5038c2ecf20Sopenharmony_ci /* calculate left instance change for types */ 5048c2ecf20Sopenharmony_ci intel_gvt_update_vgpu_types(gvt); 5058c2ecf20Sopenharmony_ci mutex_unlock(&gvt->lock); 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci return vgpu; 5088c2ecf20Sopenharmony_ci} 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci/** 5118c2ecf20Sopenharmony_ci * intel_gvt_reset_vgpu_locked - reset a virtual GPU by DMLR or GT reset 5128c2ecf20Sopenharmony_ci * @vgpu: virtual GPU 5138c2ecf20Sopenharmony_ci * @dmlr: vGPU Device Model Level Reset or GT Reset 5148c2ecf20Sopenharmony_ci * @engine_mask: engines to reset for GT reset 5158c2ecf20Sopenharmony_ci * 5168c2ecf20Sopenharmony_ci * This function is called when user wants to reset a virtual GPU through 5178c2ecf20Sopenharmony_ci * device model reset or GT reset. The caller should hold the vgpu lock. 5188c2ecf20Sopenharmony_ci * 5198c2ecf20Sopenharmony_ci * vGPU Device Model Level Reset (DMLR) simulates the PCI level reset to reset 5208c2ecf20Sopenharmony_ci * the whole vGPU to default state as when it is created. This vGPU function 5218c2ecf20Sopenharmony_ci * is required both for functionary and security concerns.The ultimate goal 5228c2ecf20Sopenharmony_ci * of vGPU FLR is that reuse a vGPU instance by virtual machines. When we 5238c2ecf20Sopenharmony_ci * assign a vGPU to a virtual machine we must isse such reset first. 5248c2ecf20Sopenharmony_ci * 5258c2ecf20Sopenharmony_ci * Full GT Reset and Per-Engine GT Reset are soft reset flow for GPU engines 5268c2ecf20Sopenharmony_ci * (Render, Blitter, Video, Video Enhancement). It is defined by GPU Spec. 5278c2ecf20Sopenharmony_ci * Unlike the FLR, GT reset only reset particular resource of a vGPU per 5288c2ecf20Sopenharmony_ci * the reset request. Guest driver can issue a GT reset by programming the 5298c2ecf20Sopenharmony_ci * virtual GDRST register to reset specific virtual GPU engine or all 5308c2ecf20Sopenharmony_ci * engines. 5318c2ecf20Sopenharmony_ci * 5328c2ecf20Sopenharmony_ci * The parameter dev_level is to identify if we will do DMLR or GT reset. 5338c2ecf20Sopenharmony_ci * The parameter engine_mask is to specific the engines that need to be 5348c2ecf20Sopenharmony_ci * resetted. If value ALL_ENGINES is given for engine_mask, it means 5358c2ecf20Sopenharmony_ci * the caller requests a full GT reset that we will reset all virtual 5368c2ecf20Sopenharmony_ci * GPU engines. For FLR, engine_mask is ignored. 5378c2ecf20Sopenharmony_ci */ 5388c2ecf20Sopenharmony_civoid intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, 5398c2ecf20Sopenharmony_ci intel_engine_mask_t engine_mask) 5408c2ecf20Sopenharmony_ci{ 5418c2ecf20Sopenharmony_ci struct intel_gvt *gvt = vgpu->gvt; 5428c2ecf20Sopenharmony_ci struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; 5438c2ecf20Sopenharmony_ci intel_engine_mask_t resetting_eng = dmlr ? ALL_ENGINES : engine_mask; 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci gvt_dbg_core("------------------------------------------\n"); 5468c2ecf20Sopenharmony_ci gvt_dbg_core("resseting vgpu%d, dmlr %d, engine_mask %08x\n", 5478c2ecf20Sopenharmony_ci vgpu->id, dmlr, engine_mask); 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci vgpu->resetting_eng = resetting_eng; 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ci intel_vgpu_stop_schedule(vgpu); 5528c2ecf20Sopenharmony_ci /* 5538c2ecf20Sopenharmony_ci * The current_vgpu will set to NULL after stopping the 5548c2ecf20Sopenharmony_ci * scheduler when the reset is triggered by current vgpu. 5558c2ecf20Sopenharmony_ci */ 5568c2ecf20Sopenharmony_ci if (scheduler->current_vgpu == NULL) { 5578c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 5588c2ecf20Sopenharmony_ci intel_gvt_wait_vgpu_idle(vgpu); 5598c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 5608c2ecf20Sopenharmony_ci } 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci intel_vgpu_reset_submission(vgpu, resetting_eng); 5638c2ecf20Sopenharmony_ci /* full GPU reset or device model level reset */ 5648c2ecf20Sopenharmony_ci if (engine_mask == ALL_ENGINES || dmlr) { 5658c2ecf20Sopenharmony_ci intel_vgpu_select_submission_ops(vgpu, ALL_ENGINES, 0); 5668c2ecf20Sopenharmony_ci if (engine_mask == ALL_ENGINES) 5678c2ecf20Sopenharmony_ci intel_vgpu_invalidate_ppgtt(vgpu); 5688c2ecf20Sopenharmony_ci /*fence will not be reset during virtual reset */ 5698c2ecf20Sopenharmony_ci if (dmlr) { 5708c2ecf20Sopenharmony_ci if(!vgpu->d3_entered) { 5718c2ecf20Sopenharmony_ci intel_vgpu_invalidate_ppgtt(vgpu); 5728c2ecf20Sopenharmony_ci intel_vgpu_destroy_all_ppgtt_mm(vgpu); 5738c2ecf20Sopenharmony_ci } 5748c2ecf20Sopenharmony_ci intel_vgpu_reset_ggtt(vgpu, true); 5758c2ecf20Sopenharmony_ci intel_vgpu_reset_resource(vgpu); 5768c2ecf20Sopenharmony_ci } 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_ci intel_vgpu_reset_mmio(vgpu, dmlr); 5798c2ecf20Sopenharmony_ci populate_pvinfo_page(vgpu); 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ci if (dmlr) { 5828c2ecf20Sopenharmony_ci intel_vgpu_reset_display(vgpu); 5838c2ecf20Sopenharmony_ci intel_vgpu_reset_cfg_space(vgpu); 5848c2ecf20Sopenharmony_ci /* only reset the failsafe mode when dmlr reset */ 5858c2ecf20Sopenharmony_ci vgpu->failsafe = false; 5868c2ecf20Sopenharmony_ci /* 5878c2ecf20Sopenharmony_ci * PCI_D0 is set before dmlr, so reset d3_entered here 5888c2ecf20Sopenharmony_ci * after done using. 5898c2ecf20Sopenharmony_ci */ 5908c2ecf20Sopenharmony_ci if(vgpu->d3_entered) 5918c2ecf20Sopenharmony_ci vgpu->d3_entered = false; 5928c2ecf20Sopenharmony_ci else 5938c2ecf20Sopenharmony_ci vgpu->pv_notified = false; 5948c2ecf20Sopenharmony_ci } 5958c2ecf20Sopenharmony_ci } 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci vgpu->resetting_eng = 0; 5988c2ecf20Sopenharmony_ci gvt_dbg_core("reset vgpu%d done\n", vgpu->id); 5998c2ecf20Sopenharmony_ci gvt_dbg_core("------------------------------------------\n"); 6008c2ecf20Sopenharmony_ci} 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_ci/** 6038c2ecf20Sopenharmony_ci * intel_gvt_reset_vgpu - reset a virtual GPU (Function Level) 6048c2ecf20Sopenharmony_ci * @vgpu: virtual GPU 6058c2ecf20Sopenharmony_ci * 6068c2ecf20Sopenharmony_ci * This function is called when user wants to reset a virtual GPU. 6078c2ecf20Sopenharmony_ci * 6088c2ecf20Sopenharmony_ci */ 6098c2ecf20Sopenharmony_civoid intel_gvt_reset_vgpu(struct intel_vgpu *vgpu) 6108c2ecf20Sopenharmony_ci{ 6118c2ecf20Sopenharmony_ci mutex_lock(&vgpu->vgpu_lock); 6128c2ecf20Sopenharmony_ci intel_gvt_reset_vgpu_locked(vgpu, true, 0); 6138c2ecf20Sopenharmony_ci mutex_unlock(&vgpu->vgpu_lock); 6148c2ecf20Sopenharmony_ci} 615